IDEA-119680 Gradle: work offline

This commit is contained in:
Vladislav.Soroka
2014-01-27 12:13:06 +04:00
parent 1d2d04052f
commit 8129c49d38
11 changed files with 115 additions and 39 deletions
@@ -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<ProjectSettings> 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 {
@@ -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
@@ -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()));
@@ -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<String> extraJvmArgs) {
ModelBuilder<T> result = connection.model(modelType);
prepare(result, id, settings, listener, extraJvmArgs, connection);
prepare(result, id, settings, listener, extraJvmArgs, ContainerUtil.<String>newArrayList(), connection);
return result;
}
@@ -76,9 +77,10 @@ public class GradleExecutionHelper {
@NotNull ProjectConnection connection,
@Nullable GradleExecutionSettings settings,
@NotNull ExternalSystemTaskNotificationListener listener,
@NotNull final List<String> vmOptions) {
@NotNull final List<String> vmOptions,
@NotNull final List<String> 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<String> extraJvmArgs,
@NotNull List<String> 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<String> extraJvmArgs,
@NotNull List<String> 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<String> filteredArgs = ContainerUtil.mapNotNull(commandLineArgs, new Function<String, String>() {
@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.<String>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.<String>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);
}
}
@@ -160,16 +160,22 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
parametersList.addProperty(jvmArg.getKey(), jvmArg.getValue());
}
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = resolverCtx.getConnection().action(projectImportAction);
final List<String> 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 {
@@ -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
@@ -90,7 +90,6 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager<GradleE
Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() {
@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<GradleE
};
FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator()));
scriptParameters.add("--init-script");
scriptParameters.add(tempFile.getAbsolutePath());
ContainerUtil.addAll(scriptParameters, GradleConstants.INIT_SCRIPT_CMD_OPTION, tempFile.getAbsolutePath());
}
catch (IOException e) {
throw new ExternalSystemException(e);
}
}
if (!scriptParameters.isEmpty()) {
launcher.withArguments(ArrayUtil.toStringArray(scriptParameters));
}
BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings, listener, vmOptions, scriptParameters);
launcher.forTasks(ArrayUtil.toStringArray(taskNames));
launcher.run();
return null;
@@ -37,11 +37,12 @@ public class GradleExecutionSettings extends ExternalSystemExecutionSettings {
@NotNull private final List<ClassHolder<? extends GradleProjectResolverExtension>> 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<ClassHolder<? extends GradleProjectResolverExtension>> getResolverExtensions() {
return myResolverExtensions;
@@ -46,6 +46,7 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
@Nullable private String myServiceDirectoryPath;
@Nullable private String myGradleVmOptions;
private boolean myIsOfflineWork;
public GradleSettings(@NotNull Project project) {
super(GradleSettingsListener.TOPIC, project);
@@ -66,6 +67,7 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
protected void copyExtraSettingsFrom(@NotNull GradleSettings settings) {
myServiceDirectoryPath = settings.getServiceDirectoryPath();
myGradleVmOptions = settings.getGradleVmOptions();
myIsOfflineWork = settings.isOfflineWork();
}
@SuppressWarnings("unchecked")
@@ -76,6 +78,7 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
fillState(state);
state.serviceDirectoryPath = myServiceDirectoryPath;
state.gradleVmOptions = myGradleVmOptions;
state.offlineWork = myIsOfflineWork;
return state;
}
@@ -84,6 +87,7 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
super.loadState(state);
myServiceDirectoryPath = state.serviceDirectoryPath;
myGradleVmOptions = state.gradleVmOptions;
myIsOfflineWork = state.offlineWork;
}
/**
@@ -118,6 +122,14 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
}
}
public boolean isOfflineWork() {
return myIsOfflineWork;
}
public void setOfflineWork(boolean isOfflineWork) {
myIsOfflineWork = isOfflineWork;
}
@Override
protected void checkSettings(@NotNull GradleProjectSettings old, @NotNull GradleProjectSettings current) {
if (!Comparing.equal(old.getGradleHome(), current.getGradleHome())) {
@@ -133,6 +145,7 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
private Set<GradleProjectSettings> myProjectSettings = ContainerUtilRt.newTreeSet();
public String serviceDirectoryPath;
public String gradleVmOptions;
public boolean offlineWork;
@AbstractCollection(surroundWithTag = false, elementTypes = {GradleProjectSettings.class})
public Set<GradleProjectSettings> getLinkedExternalProjectsSettings() {
@@ -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() {
}
}
@@ -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<ProjectImportAction.AllModels> 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);
}