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 000000000000..8d675c2c0e1e Binary files /dev/null and b/plugins/gradle/lib/gradle-cli-2.2.jar differ diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleExecuteTaskAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleExecuteTaskAction.java new file mode 100644 index 000000000000..e0a61b48f9e9 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleExecuteTaskAction.java @@ -0,0 +1,193 @@ +/* + * 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.action; + +import com.intellij.execution.RunManagerEx; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.actions.ConfigurationContext; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.externalSystem.action.ExternalSystemActionUtil; +import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; +import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings; +import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo; +import com.intellij.openapi.externalSystem.model.project.ExternalConfigPathAware; +import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager; +import com.intellij.openapi.externalSystem.service.notification.NotificationCategory; +import com.intellij.openapi.externalSystem.service.notification.NotificationData; +import com.intellij.openapi.externalSystem.service.notification.NotificationSource; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.externalSystem.view.ExternalSystemNode; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import org.gradle.cli.CommandLineArgumentException; +import org.gradle.cli.CommandLineParser; +import org.gradle.cli.ParsedCommandLine; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.gradle.service.execution.cmd.GradleCommandLineOptionsConverter; +import org.jetbrains.plugins.gradle.service.task.ExecuteGradleTaskHistoryService; +import org.jetbrains.plugins.gradle.service.task.GradleRunTaskDialog; +import org.jetbrains.plugins.gradle.util.GradleConstants; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Vladislav.Soroka + * @since 11/25/2014 + */ +public class GradleExecuteTaskAction extends DumbAwareAction { + @Override + public void actionPerformed(@NotNull final AnActionEvent e) { + final Project project = e.getRequiredData(CommonDataKeys.PROJECT); + ExecuteGradleTaskHistoryService historyService = ExecuteGradleTaskHistoryService.getInstance(project); + GradleRunTaskDialog dialog = new GradleRunTaskDialog(project, historyService.getHistory()); + String lastWorkingDirectory = historyService.getWorkDirectory(); + if (lastWorkingDirectory.length() == 0) { + lastWorkingDirectory = obtainAppropriateWorkingDirectory(e); + } + + dialog.setWorkDirectory(lastWorkingDirectory); + + if (StringUtil.isEmptyOrSpaces(historyService.getCanceledCommand())) { + if (historyService.getHistory().size() > 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