From 73bf7f027342b4db7447f450f6628c4ddd9b77c1 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Mon, 8 Dec 2014 11:52:51 +0300 Subject: [PATCH] gradle: add CLI-style task execution action --- .../ExternalSystemTaskExecutionSettings.java | 7 + .../ExternalSystemRunConfiguration.java | 10 +- .../ExternalSystemTaskSettingsControl.java | 8 +- .../execution/TaskCompletionProvider.java | 107 ++++++++++ .../cmd/CommandLineCompletionProvider.java | 2 +- .../execution/cmd/ParametersListLexer.java | 2 +- .../ExternalSystemNotificationManager.java | 18 +- .../notification/NotificationSource.java | 2 +- plugins/gradle/gradle.iml | 2 + plugins/gradle/lib/gradle-cli-2.2.jar | Bin 0 -> 27177 bytes .../action/GradleExecuteTaskAction.java | 193 ++++++++++++++++++ .../GradleArgumentsCompletionProvider.java | 34 +++ .../GradleCommandLineOptionsConverter.java | 89 ++++++++ .../cmd/GradleCommandLineOptionsProvider.java | 98 +++++++++ .../task/ExecuteGradleTaskHistoryService.java | 105 ++++++++++ .../service/task/GradleRunTaskDialog.form | 56 +++++ .../service/task/GradleRunTaskDialog.java | 170 +++++++++++++++ plugins/maven/maven.iml | 4 +- .../MavenArgumentsCompletionProvider.java | 2 +- .../execution/MavenRunnerParametersPanel.java | 2 +- .../maven/utils/actions/MavenActionUtil.java | 12 +- 21 files changed, 895 insertions(+), 28 deletions(-) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/TaskCompletionProvider.java rename {plugins/maven/src/main/java/org/jetbrains/idea/maven => platform/external-system-impl/src/com/intellij/openapi/externalSystem/service}/execution/cmd/CommandLineCompletionProvider.java (97%) rename {plugins/maven/src/main/java/org/jetbrains/idea/maven => platform/external-system-impl/src/com/intellij/openapi/externalSystem/service}/execution/cmd/ParametersListLexer.java (94%) create mode 100644 plugins/gradle/lib/gradle-cli-2.2.jar create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleExecuteTaskAction.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleArgumentsCompletionProvider.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/cmd/GradleCommandLineOptionsConverter.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/cmd/GradleCommandLineOptionsProvider.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/ExecuteGradleTaskHistoryService.java create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleRunTaskDialog.form create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleRunTaskDialog.java diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java index ad9dec8d1fe1..fb7d8e1c0b0e 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java @@ -160,4 +160,11 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable { return true; } + + @Override + public String toString() { + return (myTaskNames == null ? "" : StringUtil.join(myTaskNames, " ")) + + (StringUtil.isEmpty(myScriptParameters) ? "" : " " + myScriptParameters) + + (StringUtil.isEmpty(myVmOptions) ? "" : " " + myVmOptions); + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java index eca62e509a47..8ef61375a42e 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java @@ -151,7 +151,6 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase { public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { if (myProject.isDisposed()) return null; - ExternalSystemUtil.updateRecentTasks(new ExternalTaskExecutionInfo(mySettings.clone(), executor.getId()), myProject); final List tasks = ContainerUtilRt.newArrayList(); for (String taskName : mySettings.getTaskNames()) { tasks.add(new ExternalTaskPojo(taskName, mySettings.getExternalProjectPath(), null)); @@ -188,11 +187,11 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase { final String greeting; if (mySettings.getTaskNames().size() > 1) { greeting = ExternalSystemBundle - .message("run.text.starting.multiple.task", startDateTime, StringUtil.join(mySettings.getTaskNames(), " ")); + .message("run.text.starting.multiple.task", startDateTime, mySettings.toString()); } else { greeting = - ExternalSystemBundle.message("run.text.starting.single.task", startDateTime, StringUtil.join(mySettings.getTaskNames(), " ")); + ExternalSystemBundle.message("run.text.starting.single.task", startDateTime, mySettings.toString()); } processHandler.notifyTextAvailable(greeting, ProcessOutputTypes.SYSTEM); task.execute(new ExternalSystemTaskNotificationListenerAdapter() { @@ -223,11 +222,11 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase { final String farewell; if (mySettings.getTaskNames().size() > 1) { farewell = ExternalSystemBundle - .message("run.text.ended.multiple.task", endDateTime, StringUtil.join(mySettings.getTaskNames(), " ")); + .message("run.text.ended.multiple.task", endDateTime, mySettings.toString()); } else { farewell = - ExternalSystemBundle.message("run.text.ended.single.task", endDateTime, StringUtil.join(mySettings.getTaskNames(), " ")); + ExternalSystemBundle.message("run.text.ended.single.task", endDateTime, mySettings.toString()); } processHandler.notifyTextAvailable(farewell, ProcessOutputTypes.SYSTEM); processHandler.notifyProcessTerminated(0); @@ -243,7 +242,6 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase { private static class MyProcessHandler extends ProcessHandler { private final ExternalSystemExecuteTaskTask myTask; - @Nullable private volatile OutputStream myOutputStream; public MyProcessHandler(ExternalSystemExecuteTaskTask task) { myTask = task; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java index 4e7a87e1d53a..8bb868f30aa1 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java @@ -23,10 +23,12 @@ import com.intellij.openapi.externalSystem.service.ui.ExternalProjectPathField; import com.intellij.openapi.externalSystem.util.*; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.EditorTextField; import com.intellij.ui.RawCommandLineEditor; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBTextField; @@ -52,7 +54,7 @@ public class ExternalSystemTaskSettingsControl implements ExternalSystemSettings private ExternalProjectPathField myProjectPathField; @SuppressWarnings("FieldCanBeLocal") // Used via reflection at showUi() and disposeResources() private JBLabel myTasksLabel; - private JBTextField myTasksTextField; + private EditorTextField myTasksTextField; @SuppressWarnings("FieldCanBeLocal") // Used via reflection at showUi() and disposeResources() private JBLabel myVmOptionsLabel; private RawCommandLineEditor myVmOptionsEditor; @@ -95,12 +97,14 @@ public class ExternalSystemTaskSettingsControl implements ExternalSystemSettings canvas.add(myProjectPathField, ExternalSystemUiUtil.getFillLineConstraints(0)); myTasksLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.tasks")); - myTasksTextField = new JBTextField(ExternalSystemConstants.TEXT_FIELD_WIDTH_IN_COLUMNS); + myTasksTextField = new EditorTextField("", myProject, PlainTextFileType.INSTANCE); canvas.add(myTasksLabel, ExternalSystemUiUtil.getLabelConstraints(0)); GridBag c = ExternalSystemUiUtil.getFillLineConstraints(0); c.insets.right = myProjectPathField.getButton().getPreferredSize().width + 8 /* street magic, sorry */; canvas.add(myTasksTextField, c); + new TaskCompletionProvider(myProject, myExternalSystemId, myProjectPathField).apply(myTasksTextField); + myVmOptionsLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.vmoptions")); myVmOptionsEditor = new RawCommandLineEditor(); myVmOptionsEditor.setDialogCaption(ExternalSystemBundle.message("run.configuration.settings.label.vmoptions")); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/TaskCompletionProvider.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/TaskCompletionProvider.java new file mode 100644 index 000000000000..0156e965a8e0 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/TaskCompletionProvider.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.service.execution; + +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.externalSystem.model.DataNode; +import com.intellij.openapi.externalSystem.model.ExternalProjectInfo; +import com.intellij.openapi.externalSystem.model.ProjectKeys; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.model.project.ModuleData; +import com.intellij.openapi.externalSystem.model.task.TaskData; +import com.intellij.openapi.externalSystem.service.execution.cmd.CommandLineCompletionProvider; +import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager; +import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.TextAccessor; +import com.intellij.util.BooleanFunction; +import com.intellij.util.containers.ContainerUtil; +import groovyjarjarcommonscli.Options; +import icons.ExternalSystemIcons; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +/** + * @author Vladislav.Soroka + * @since 11/26/2014 + */ +public class TaskCompletionProvider extends CommandLineCompletionProvider { + + private volatile List myCachedElements; + private volatile String myCachedWorkingDir; + private final Project myProject; + private final ProjectSystemId mySystemId; + private final TextAccessor myProjectPathAccessor; + + + public TaskCompletionProvider(@NotNull Project project, + @NotNull ProjectSystemId externalSystemId, + @NotNull TextAccessor workDirectoryField) { + this(project, externalSystemId, workDirectoryField, new Options()); + } + + public TaskCompletionProvider(@NotNull Project project, + @NotNull ProjectSystemId externalSystemId, + @NotNull TextAccessor workDirectoryField, + @NotNull Options options) { + super(options); + myProject = project; + mySystemId = externalSystemId; + myProjectPathAccessor = workDirectoryField; + } + + @Override + protected void addArgumentVariants(@NotNull CompletionResultSet result) { + List cachedElements = myCachedElements; + final String projectPath = myProjectPathAccessor.getText(); + if (cachedElements == null || !StringUtil.equals(myCachedWorkingDir, projectPath)) { + final ExternalProjectSettings linkedProjectSettings = + ExternalSystemApiUtil.getSettings(myProject, mySystemId).getLinkedProjectSettings(projectPath); + if (linkedProjectSettings == null) return; + + final ExternalProjectInfo projectData = + ProjectDataManager.getInstance().getExternalProjectData(myProject, mySystemId, linkedProjectSettings.getExternalProjectPath()); + + if (projectData == null || projectData.getExternalProjectStructure() == null) return; + + final DataNode node = + ExternalSystemApiUtil.findFirstRecursively(projectData.getExternalProjectStructure(), new BooleanFunction>() { + @Override + public boolean fun(DataNode node) { + return node.getKey().equals(ProjectKeys.MODULE) && + node.getData() instanceof ModuleData && + ((ModuleData)node.getData()).getLinkedExternalProjectPath().equals(projectPath); + } + }); + + final Collection> tasks = ExternalSystemApiUtil.getChildren(node, ProjectKeys.TASK); + cachedElements = ContainerUtil.newArrayListWithCapacity(tasks.size()); + for (DataNode taskDataNode : tasks) { + cachedElements.add(LookupElementBuilder.create(taskDataNode.getData().getName()).withIcon(ExternalSystemIcons.Task)); + } + myCachedElements = cachedElements; + myCachedWorkingDir = projectPath; + } + result.addAllElements(cachedElements); + } +} + diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/cmd/CommandLineCompletionProvider.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/cmd/CommandLineCompletionProvider.java similarity index 97% rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/cmd/CommandLineCompletionProvider.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/cmd/CommandLineCompletionProvider.java index bf9bfc3e1a10..4613ff6a8355 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/cmd/CommandLineCompletionProvider.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/cmd/CommandLineCompletionProvider.java @@ -1,4 +1,4 @@ -package org.jetbrains.idea.maven.execution.cmd; +package com.intellij.openapi.externalSystem.service.execution.cmd; import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.completion.CompletionResultSet; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/cmd/ParametersListLexer.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/cmd/ParametersListLexer.java similarity index 94% rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/cmd/ParametersListLexer.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/cmd/ParametersListLexer.java index 176687d5a528..9f5f117208f3 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/cmd/ParametersListLexer.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/cmd/ParametersListLexer.java @@ -1,4 +1,4 @@ -package org.jetbrains.idea.maven.execution.cmd; +package com.intellij.openapi.externalSystem.service.execution.cmd; /** * @author Sergey Evdokimov diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java index 75a227518b46..aa37b6b1b600 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java @@ -13,16 +13,17 @@ import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; import com.intellij.openapi.externalSystem.model.LocationAwareExternalSystemException; import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.externalSystem.view.ExternalProjectsView; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowId; @@ -148,8 +149,15 @@ public class ExternalSystemNotificationManager { } } - final NotificationGroup group = ExternalSystemUtil.getToolWindowElement( - NotificationGroup.class, myProject, ExternalSystemDataKeys.NOTIFICATION_GROUP, externalSystemId); + NotificationGroup group; + if (notificationData.getBalloonGroup() == null) { + ExternalProjectsView externalProjectsView = ExternalProjectsManager.getInstance(myProject).getExternalProjectsView(externalSystemId); + group = externalProjectsView != null ? externalProjectsView.getNotificationGroup() : null; + } + else { + final NotificationGroup registeredGroup = NotificationGroup.findRegisteredGroup(notificationData.getBalloonGroup()); + group = registeredGroup != null ? registeredGroup : NotificationGroup.balloonGroup(notificationData.getBalloonGroup()); + } if (group == null) return; final Notification notification = group.createNotification( @@ -360,6 +368,10 @@ public class ExternalSystemNotificationManager { contentDisplayName = ExternalSystemBundle.message("notification.messages.project.sync.tab.name", externalSystemId.getReadableName()); break; + case TASK_EXECUTION: + contentDisplayName = + ExternalSystemBundle.message("notification.messages.task.execution.tab.name", externalSystemId.getReadableName()); + break; default: throw new AssertionError("unsupported notification source found: " + notificationSource); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/NotificationSource.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/NotificationSource.java index 4a20167c778c..e88075e185b1 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/NotificationSource.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/NotificationSource.java @@ -20,5 +20,5 @@ package com.intellij.openapi.externalSystem.service.notification; * @since 3/28/14 */ public enum NotificationSource { - PROJECT_SYNC + PROJECT_SYNC, TASK_EXECUTION } diff --git a/plugins/gradle/gradle.iml b/plugins/gradle/gradle.iml index b817051efbc9..eb7b491bad70 100644 --- a/plugins/gradle/gradle.iml +++ b/plugins/gradle/gradle.iml @@ -40,6 +40,7 @@ + @@ -53,6 +54,7 @@ + diff --git a/plugins/gradle/lib/gradle-cli-2.2.jar b/plugins/gradle/lib/gradle-cli-2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..8d675c2c0e1ec4c4463769380a1dd4fee9784d0d GIT binary patch literal 27177 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 0) { + dialog.setCommandLine(historyService.getHistory().get(0)); + } + } + else { + dialog.setCommandLine(historyService.getCanceledCommand()); + } + + if (!dialog.showAndGet()) { + historyService.setCanceledCommand(dialog.getCommandLine()); + return; + } + + historyService.setCanceledCommand(null); + + String fullCommandLine = dialog.getCommandLine(); + fullCommandLine = fullCommandLine.trim(); + + String workDirectory = dialog.getWorkDirectory(); + + historyService.addCommand(fullCommandLine, workDirectory); + + final ExternalTaskExecutionInfo taskExecutionInfo; + try { + taskExecutionInfo = buildTaskInfo(workDirectory, fullCommandLine); + } + catch (CommandLineArgumentException ex) { + final NotificationData notificationData = new NotificationData( + "Command-line arguments cannot be parsed", + "" + fullCommandLine + " \n" + ex.getMessage(), + NotificationCategory.WARNING, NotificationSource.TASK_EXECUTION + ); + notificationData.setBalloonNotification(true); + ExternalSystemNotificationManager.getInstance(project).showNotification(GradleConstants.SYSTEM_ID, notificationData); + return; + } + RunManagerEx runManager = RunManagerEx.getInstanceEx(project); + + ExternalSystemUtil.runTask(taskExecutionInfo.getSettings(), taskExecutionInfo.getExecutorId(), project, GradleConstants.SYSTEM_ID); + + RunnerAndConfigurationSettings configuration = + ExternalSystemUtil.createExternalSystemRunnerAndConfigurationSettings(taskExecutionInfo.getSettings(), + project, GradleConstants.SYSTEM_ID); + if (configuration == null) return; + + final RunnerAndConfigurationSettings existingConfiguration = runManager.findConfigurationByName(configuration.getName()); + if(existingConfiguration == null) { + runManager.setTemporaryConfiguration(configuration); + } else { + runManager.setSelectedConfiguration(existingConfiguration); + } + } + + private static ExternalTaskExecutionInfo buildTaskInfo(@NotNull String projectPath, @NotNull String fullCommandLine) + throws CommandLineArgumentException { + CommandLineParser gradleCmdParser = new CommandLineParser(); + + GradleCommandLineOptionsConverter commandLineConverter = new GradleCommandLineOptionsConverter(); + commandLineConverter.configure(gradleCmdParser); + ParsedCommandLine parsedCommandLine = gradleCmdParser.parse(StringUtil.split(fullCommandLine, " ")); + + final Map> optionsMap = + commandLineConverter.convert(parsedCommandLine, new HashMap>()); + + final List systemProperties = optionsMap.remove("system-prop"); + final String vmOptions = systemProperties == null ? "" : StringUtil.join(systemProperties, new Function() { + @Override + public String fun(String entry) { + return "-D" + entry; + } + }, " "); + + final String scriptParameters = StringUtil.join(optionsMap.entrySet(), new Function>, String>() { + @Override + public String fun(Map.Entry> entry) { + final List values = entry.getValue(); + final String longOptionName = entry.getKey(); + if (values != null && !values.isEmpty()) { + return StringUtil.join(values, new Function() { + @Override + public String fun(String entry) { + return "--" + longOptionName + ' ' + entry; + } + }, " "); + } + else { + return "--" + longOptionName; + } + } + }, " "); + + final List tasks = parsedCommandLine.getExtraArguments(); + + ExternalSystemTaskExecutionSettings settings = new ExternalSystemTaskExecutionSettings(); + settings.setExternalProjectPath(projectPath); + settings.setTaskNames(tasks); + settings.setScriptParameters(scriptParameters); + settings.setVmOptions(vmOptions); + settings.setExternalSystemIdString(GradleConstants.SYSTEM_ID.toString()); + return new ExternalTaskExecutionInfo(settings, DefaultRunExecutor.EXECUTOR_ID); + } + + private static String obtainAppropriateWorkingDirectory(AnActionEvent e) { + final List selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext()); + if (selectedNodes == null || selectedNodes.size() != 1) { + final Module module = ExternalSystemActionUtil.getModule(e.getDataContext()); + String projectPath = ExternalSystemApiUtil.getExternalProjectPath(module); + return projectPath == null ? "" : projectPath; + } + + final ExternalSystemNode node = selectedNodes.get(0); + final Object externalData = node.getData(); + if (externalData instanceof ExternalConfigPathAware) { + return ((ExternalConfigPathAware)externalData).getLinkedExternalProjectPath(); + } + else { + final ExternalConfigPathAware parentExternalConfigPathAware = node.findParentData(ExternalConfigPathAware.class); + return parentExternalConfigPathAware != null ? parentExternalConfigPathAware.getLinkedExternalProjectPath() : ""; + } + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleArgumentsCompletionProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleArgumentsCompletionProvider.java new file mode 100644 index 000000000000..bf04490c0de3 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleArgumentsCompletionProvider.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.execution; + +import com.intellij.openapi.externalSystem.service.execution.TaskCompletionProvider; +import com.intellij.openapi.project.Project; +import com.intellij.ui.TextAccessor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.service.execution.cmd.GradleCommandLineOptionsProvider; +import org.jetbrains.plugins.gradle.util.GradleConstants; + +/** + * @author Vladislav.Soroka + * @since 11/25/2014 + */ +public class GradleArgumentsCompletionProvider extends TaskCompletionProvider { + + public GradleArgumentsCompletionProvider(@NotNull Project project, @NotNull TextAccessor workDirectoryField) { + super(project, GradleConstants.SYSTEM_ID, workDirectoryField, GradleCommandLineOptionsProvider.getSupportedOptions()); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/cmd/GradleCommandLineOptionsConverter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/cmd/GradleCommandLineOptionsConverter.java new file mode 100644 index 000000000000..a3763f6ea060 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/cmd/GradleCommandLineOptionsConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.service.execution.cmd; + +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; +import groovyjarjarcommonscli.Option; +import org.gradle.cli.*; +import org.jetbrains.plugins.gradle.service.execution.GradleArgumentsCompletionProvider; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * @author Vladislav.Soroka + * @since 11/25/2014 + */ +public class GradleCommandLineOptionsConverter extends AbstractCommandLineConverter>> { + + private final SystemPropertiesCommandLineConverter systemPropertiesCommandLineConverter = new SystemPropertiesCommandLineConverter(); + + @Override + public Map> convert(ParsedCommandLine options, Map> target) + throws CommandLineArgumentException { + //noinspection unchecked + final Collection