diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java index 2644b5537c86..f5931ecedcdc 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.HideableTitledPanel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,6 +52,7 @@ public abstract class AbstractImportFromExternalSystemControl< @NotNull private final PaintAwarePanel myComponent = new PaintAwarePanel(new GridBagLayout()); @NotNull private final TextFieldWithBrowseButton myLinkedProjectPathField = new TextFieldWithBrowseButton(); + @Nullable private final HideableTitledPanel hideableSystemSettingsPanel; @NotNull private final ExternalSystemSettingsControl myProjectSettingsControl; @NotNull private final ProjectSystemId myExternalSystemId; @@ -103,7 +105,18 @@ public abstract class AbstractImportFromExternalSystemControl< myComponent.add(myLinkedProjectPathField, ExternalSystemUiUtil.getFillLineConstraints(0)); myProjectSettingsControl.fillUi(myComponent, 0); if (mySystemSettingsControl != null) { - mySystemSettingsControl.fillUi(myComponent, 0); + final PaintAwarePanel mySystemSettingsControlPanel = new PaintAwarePanel(); + mySystemSettingsControl.fillUi(mySystemSettingsControlPanel, 0); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(mySystemSettingsControlPanel, BorderLayout.CENTER); + hideableSystemSettingsPanel = new HideableTitledPanel( + ExternalSystemBundle.message("settings.title.system.settings", myExternalSystemId.getReadableName()), false); + hideableSystemSettingsPanel.setContentComponent(panel); + hideableSystemSettingsPanel.setOn(false); + myComponent.add(hideableSystemSettingsPanel, ExternalSystemUiUtil.getFillLineConstraints(0)); + } else { + hideableSystemSettingsPanel = null; } ExternalSystemUiUtil.fillBottom(myComponent); } @@ -181,6 +194,9 @@ public abstract class AbstractImportFromExternalSystemControl< if (mySystemSettingsControl != null) { mySystemSettingsControl.reset(); } + if (hideableSystemSettingsPanel != null) { + hideableSystemSettingsPanel.setOn(false); + } } public void apply() throws ConfigurationException { diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 254b5a99333c..0dd8da3cbcf6 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -10,6 +10,7 @@ gradle.settings.text.use.bundled.distribution=Use bundled gradle distribution: ( gradle.settings.text.home.path=Gradle home: gradle.settings.text.service.dir.path=Service directory path: gradle.settings.text.vm.options=Gradle VM options: +gradle.settings.text.offline_work=Offline work gradle.settings.title.service.dir.path=Select gradle service directory to use gradle.generic.text.error.jar.not.found=Gradle jars location is unknown diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java index 71a44fb91de2..b011f2d90016 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java @@ -180,7 +180,8 @@ public class GradleManager GradleExecutionSettings result = new GradleExecutionSettings(localGradlePath, settings.getServiceDirectoryPath(), distributionType, - settings.getGradleVmOptions()); + settings.getGradleVmOptions(), + settings.isOfflineWork()); for (GradleProjectResolverExtension extension : RESOLVER_EXTENSIONS.getValue()) { result.addResolverExtensionClass(ClassHolder.from(extension.getClass())); diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java index 285070ca8722..cf38f5765c77 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java @@ -22,6 +22,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; @@ -66,7 +67,7 @@ public class GradleExecutionHelper { @NotNull ExternalSystemTaskNotificationListener listener, @NotNull List extraJvmArgs) { ModelBuilder result = connection.model(modelType); - prepare(result, id, settings, listener, extraJvmArgs, connection); + prepare(result, id, settings, listener, extraJvmArgs, ContainerUtil.newArrayList(), connection); return result; } @@ -76,9 +77,10 @@ public class GradleExecutionHelper { @NotNull ProjectConnection connection, @Nullable GradleExecutionSettings settings, @NotNull ExternalSystemTaskNotificationListener listener, - @NotNull final List vmOptions) { + @NotNull final List vmOptions, + @NotNull final List commandLineArgs) { BuildLauncher result = connection.newBuild(); - prepare(result, id, settings, listener, vmOptions, connection); + prepare(result, id, settings, listener, vmOptions, commandLineArgs, connection); return result; } @@ -88,8 +90,9 @@ public class GradleExecutionHelper { @Nullable GradleExecutionSettings settings, @NotNull final ExternalSystemTaskNotificationListener listener, @NotNull List extraJvmArgs, + @NotNull List commandLineArgs, @NotNull ProjectConnection connection) { - prepare(operation, id, settings, listener, extraJvmArgs, connection, + prepare(operation, id, settings, listener, extraJvmArgs, commandLineArgs, connection, new OutputWrapper(listener, id, true), new OutputWrapper(listener, id, false)); } @@ -100,6 +103,7 @@ public class GradleExecutionHelper { @Nullable GradleExecutionSettings settings, @NotNull final ExternalSystemTaskNotificationListener listener, @NotNull List extraJvmArgs, + @NotNull List commandLineArgs, @NotNull ProjectConnection connection, @NotNull final OutputStream standardOutput, @NotNull final OutputStream standardError) { @@ -138,6 +142,22 @@ public class GradleExecutionHelper { operation.setJvmArguments(ArrayUtil.toStringArray(filteredArgs)); } + if(settings.isOfflineWork()) { + commandLineArgs.add(GradleConstants.OFFLINE_MODE_CMD_OPTION); + } + + if (!commandLineArgs.isEmpty()) { + LOG.info("Passing command-line args to Gradle Tooling API: " + commandLineArgs); + // filter nulls and empty strings + List filteredArgs = ContainerUtil.mapNotNull(commandLineArgs, new Function() { + @Override + public String fun(String s) { + return StringUtil.isEmpty(s) ? null : s; + } + }); + operation.withArguments(ArrayUtil.toStringArray(filteredArgs)); + } + listener.onStart(id); final String javaHome = settings.getJavaHome(); if (javaHome != null && new File(javaHome).isDirectory()) { @@ -213,7 +233,6 @@ public class GradleExecutionHelper { ProjectConnection connection = getConnection(projectPath, settings); try { - BuildLauncher launcher = getBuildLauncher(id, connection, settings, listener, ContainerUtil.newArrayList()); try { final File tempFile = FileUtil.createTempFile("wrap", ".gradle"); tempFile.deleteOnExit(); @@ -229,7 +248,9 @@ public class GradleExecutionHelper { "}}", }; FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator())); - launcher.withArguments("--init-script", tempFile.getAbsolutePath()); + + BuildLauncher launcher = getBuildLauncher(id, connection, settings, listener, ContainerUtil.newArrayList(), + ContainerUtil.newArrayList(GradleConstants.INIT_SCRIPT_CMD_OPTION, tempFile.getAbsolutePath())); launcher.forTasks("wrapper"); launcher.run(); String wrapperPropertyFile = FileUtil.loadFile(wrapperPropertyFileLocation); @@ -355,32 +376,34 @@ public class GradleExecutionHelper { field.setAccessible(isAccessible); } - @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - public static boolean setInitScript(@NotNull LongRunningOperation longRunningOperation, boolean isBuildSrcProject) { + @Nullable + public static File generateInitScript(boolean isBuildSrcProject) { + InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/init.gradle"); try { - InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/init.gradle"); - if (stream == null) return isBuildSrcProject; + if (stream == null) { + LOG.warn("Can't get init script template"); + return null; + } String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(GradleProjectResolver.class)); String s = FileUtil.loadTextAndClose(stream).replace("${JAR_PATH}", jarPath); - if(isBuildSrcProject) { + if (isBuildSrcProject) { String buildSrcDefaultInitScript = getBuildSrcDefaultInitScript(); - if(buildSrcDefaultInitScript == null) return false; + if (buildSrcDefaultInitScript == null) return null; s += buildSrcDefaultInitScript; } final File tempFile = FileUtil.createTempFile("ijinit", '.' + GradleConstants.EXTENSION, true); FileUtil.writeToFile(tempFile, s); - - String[] buildExecutorArgs = new String[]{"--init-script", tempFile.getAbsolutePath()}; - longRunningOperation.withArguments(buildExecutorArgs); - - return true; + return tempFile; } catch (Exception e) { - LOG.warn("Can't use IJ gradle init script", e); - return false; + LOG.warn("Can't generate IJ gradle init script", e); + return null; + } + finally { + StreamUtil.closeStream(stream); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 104f91c0c670..03f0e66451dc 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -160,16 +160,22 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver buildActionExecutor = resolverCtx.getConnection().action(projectImportAction); + + final List commandLineArgs = ContainerUtil.newArrayList(); + // TODO [vlad] remove the check + if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) { + File initScript = GradleExecutionHelper.generateInitScript(isBuildSrcProject); + if (initScript != null) { + ContainerUtil.addAll(commandLineArgs, GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath()); + } + } + GradleExecutionHelper.prepare( buildActionExecutor, resolverCtx.getExternalSystemTaskId(), resolverCtx.getSettings(), resolverCtx.getListener(), - parametersList.getParameters(), resolverCtx.getConnection()); - - // TODO [vlad] remove the check - if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) { - GradleExecutionHelper.setInitScript(buildActionExecutor, isBuildSrcProject); - } + parametersList.getParameters(), commandLineArgs, resolverCtx.getConnection()); ProjectImportAction.AllModels allModels; try { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java index ee527f61624a..ffdf37c74b87 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleSystemSettingsControl.java @@ -26,6 +26,7 @@ import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBTextField; import org.jetbrains.annotations.NotNull; @@ -56,6 +57,7 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro private JBLabel myGradleVmOptionsLabel; private JBTextField myGradleVmOptionsField; private boolean myServiceDirectoryPathModifiedByUser; + private JBCheckBox myOfflineModeBox; public GradleSystemSettingsControl(@NotNull GradleSettings settings) { myInitialSettings = settings; @@ -63,6 +65,9 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro @Override public void fillUi(@NotNull PaintAwarePanel canvas, int indentLevel) { + myOfflineModeBox = new JBCheckBox(GradleBundle.message("gradle.settings.text.offline_work")); + canvas.add(myOfflineModeBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel)); + myServiceDirectoryLabel = new JBLabel(GradleBundle.message("gradle.settings.text.service.dir.path")); preparePathControl(); canvas.add(myServiceDirectoryLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel)); @@ -119,6 +124,7 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro } myGradleVmOptionsField.setText(trimIfPossible(myInitialSettings.getGradleVmOptions())); + myOfflineModeBox.setSelected(myInitialSettings.isOfflineWork()); } private void deduceServiceDirectoryIfPossible() { @@ -136,7 +142,8 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro return (myServiceDirectoryPathModifiedByUser && !Comparing.equal(ExternalSystemApiUtil.normalizePath(myServiceDirectoryPathField.getText()), ExternalSystemApiUtil.normalizePath(myInitialSettings.getServiceDirectoryPath()))) - || !Comparing.equal(trimIfPossible(myGradleVmOptionsField.getText()), trimIfPossible(myInitialSettings.getGradleVmOptions())); + || !Comparing.equal(trimIfPossible(myGradleVmOptionsField.getText()), trimIfPossible(myInitialSettings.getGradleVmOptions())) + || myOfflineModeBox.isSelected() != myInitialSettings.isOfflineWork(); } @Nullable @@ -154,6 +161,7 @@ public class GradleSystemSettingsControl implements ExternalSystemSettingsContro settings.setServiceDirectoryPath(ExternalSystemApiUtil.normalizePath(myServiceDirectoryPathField.getText())); } settings.setGradleVmOptions(trimIfPossible(myGradleVmOptionsField.getText())); + settings.setOfflineWork(myOfflineModeBox.isSelected()); } @Override diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java index fdea7aecf0f9..a579699b8887 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java @@ -90,7 +90,6 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager f = new Function() { @Override public Void fun(ProjectConnection connection) { - BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings, listener, vmOptions); if (!StringUtil.isEmpty(debuggerSetup)) { try { final File tempFile = FileUtil.createTempFile("init", ".gradle"); @@ -103,17 +102,14 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager> myResolverExtensions = ContainerUtilRt.newArrayList(); @Nullable private final String myGradleHome; + @Nullable private final String myServiceDirectory; - @Nullable private final String myDaemonVmOptions; + private final boolean myIsOfflineWork; - @NotNull final DistributionType myDistributionType; + @NotNull private final DistributionType myDistributionType; @Nullable private String wrapperPropertyFile; @Nullable private String myJavaHome; @@ -49,12 +50,14 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { public GradleExecutionSettings(@Nullable String gradleHome, @Nullable String serviceDirectory, @NotNull DistributionType distributionType, - @Nullable String daemonVmOptions) + @Nullable String daemonVmOptions, + boolean isOfflineWork) { myGradleHome = gradleHome; myServiceDirectory = serviceDirectory; myDistributionType = distributionType; myDaemonVmOptions = daemonVmOptions; + myIsOfflineWork = isOfflineWork; setVerboseProcessing(USE_VERBOSE_GRADLE_API_BY_DEFAULT); } @@ -77,6 +80,10 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings { myJavaHome = javaHome; } + public boolean isOfflineWork() { + return myIsOfflineWork; + } + @NotNull public List> getResolverExtensions() { return myResolverExtensions; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java index 85993921473d..d85e6cf1a742 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleSettings.java @@ -46,6 +46,7 @@ public class GradleSettings extends AbstractExternalSystemSettings myProjectSettings = ContainerUtilRt.newTreeSet(); public String serviceDirectoryPath; public String gradleVmOptions; + public boolean offlineWork; @AbstractCollection(surroundWithTag = false, elementTypes = {GradleProjectSettings.class}) public Set getLinkedExternalProjectsSettings() { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java index 9ed33e925729..df51e51eee8a 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleConstants.java @@ -26,6 +26,9 @@ public class GradleConstants { @NotNull @NonNls public static final String HELP_TOPIC_TOOL_WINDOW = "reference.toolwindows.gradle"; + @NotNull @NonNls public static final String OFFLINE_MODE_CMD_OPTION = "--offline"; + @NotNull @NonNls public static final String INIT_SCRIPT_CMD_OPTION = "--init-script"; + private GradleConstants() { } } diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java index 0cdd2f032b78..fe5e70377843 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.gradle.model.builder; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.containers.ContainerUtil; import org.gradle.tooling.BuildActionExecuter; import org.gradle.tooling.GradleConnector; import org.gradle.tooling.ProjectConnection; @@ -73,8 +74,9 @@ public abstract class AbstractModelBuilderTest { final ProjectImportAction projectImportAction = new ProjectImportAction(true); projectImportAction.addExtraProjectModelClasses(getModels()); BuildActionExecuter buildActionExecutor = connection.action(projectImportAction); - GradleExecutionHelper.setInitScript(buildActionExecutor, false); - + File initScript = GradleExecutionHelper.generateInitScript(false); + assertNotNull(initScript); + buildActionExecutor.withArguments(GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath()); allModels = buildActionExecutor.run(); assertNotNull(allModels); }