From 01924b1916f4e2843a4fb3cd7ced36722e33a9b5 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Thu, 9 Aug 2018 19:23:02 +0300 Subject: [PATCH] Gradle run anything for multiple linked projects (IDEA-196883) --- .../execution/GradleRunAnythingProvider.java | 87 ++++++++++++++++--- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleRunAnythingProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleRunAnythingProvider.java index d4017897efa4..2f3393f84261 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleRunAnythingProvider.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/GradleRunAnythingProvider.java @@ -3,12 +3,14 @@ package org.jetbrains.plugins.gradle.execution; import com.intellij.execution.Executor; import com.intellij.ide.actions.runAnything.activity.RunAnythingProviderBase; +import com.intellij.ide.actions.runAnything.items.RunAnythingHelpItem; import com.intellij.ide.actions.runAnything.items.RunAnythingItem; import com.intellij.openapi.actionSystem.DataContext; 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.project.ModuleData; +import com.intellij.openapi.externalSystem.model.project.ProjectData; import com.intellij.openapi.externalSystem.model.task.TaskData; import com.intellij.openapi.externalSystem.service.project.ProjectDataManager; import com.intellij.openapi.project.Project; @@ -67,6 +69,9 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { String prefix = StringUtil.trim(spaceIndex < 0 ? getHelpCommand() : pattern.substring(0, spaceIndex + 1)) + ' '; String toComplete = spaceIndex < 0 ? "" : pattern.substring(spaceIndex + 1); + appendProjectsVariants(result, dataContext, prefix); + if (!result.isEmpty()) return result; + appendArgumentsVariants(result, prefix, toComplete); if (!result.isEmpty()) return result; @@ -74,8 +79,32 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { return result; } - private static void appendTasksVariants(@NotNull List result, @NotNull String prefix, @NotNull DataContext dataContext) { - MultiMap tasks = fetchTasks(dataContext); + private void appendProjectsVariants(@NotNull List result, + @NotNull DataContext dataContext, + @NotNull String prefix) { + if (!prefix.trim().equals(getHelpCommand())) return; + + Project project = fetchProject(dataContext); + Collection projectsSettings = GradleSettings.getInstance(project).getLinkedProjectsSettings(); + if (projectsSettings.isEmpty()) return; + + ProjectDataManager dataManager = ProjectDataManager.getInstance(); + projectsSettings.stream() + .map(setting -> dataManager.getExternalProjectData(project, GradleConstants.SYSTEM_ID, setting.getExternalProjectPath())) + .filter(projectInfo -> projectInfo != null && projectInfo.getExternalProjectStructure() != null) + .map(projectInfo -> projectInfo.getExternalProjectStructure().getData()) + .forEach(data -> result.add(prefix + data.getExternalName())); + } + + private void appendTasksVariants(@NotNull List result, @NotNull String prefix, @NotNull DataContext dataContext) { + Project project = fetchProject(dataContext); + String commandLine = StringUtil.trimStart(prefix, getHelpCommand()).trim(); + ProjectData projectData = getProjectData(project, commandLine); + if (projectData == null) return; + + MultiMap tasks = fetchTasks(dataContext).get(projectData); + if (tasks == null) return; + for (Map.Entry> entry : tasks.entrySet()) { for (String taskName : entry.getValue()) { String taskFqn = entry.getKey() + taskName; @@ -102,11 +131,28 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { @Override public void execute(@NotNull DataContext dataContext, @NotNull String value) { Project project = fetchProject(dataContext); - String commandLine = StringUtil.trimStart(value, getHelpCommand()); + String commandLine = StringUtil.trimStart(value, getHelpCommand()).trim(); + + ProjectData projectData = getProjectData(project, commandLine); + if (projectData == null) return; + + commandLine = StringUtil.trimStart(commandLine, projectData.getExternalName() + " "); Executor executor = EXECUTOR_KEY.getData(dataContext); - for (GradleProjectSettings setting : GradleSettings.getInstance(project).getLinkedProjectsSettings()) { - GradleExecuteTaskAction.runGradle(project, executor, setting.getExternalProjectPath(), commandLine); - } + GradleExecuteTaskAction.runGradle(project, executor, projectData.getLinkedExternalProjectPath(), commandLine); + } + + @Nullable + private static ProjectData getProjectData(@NotNull Project project, @NotNull String commandLine) { + Collection projectsSettings = GradleSettings.getInstance(project).getLinkedProjectsSettings(); + if (projectsSettings.isEmpty()) return null; + + ProjectDataManager dataManager = ProjectDataManager.getInstance(); + return projectsSettings.stream() + .map(setting -> dataManager.getExternalProjectData(project, GradleConstants.SYSTEM_ID, setting.getExternalProjectPath())) + .filter(projectInfo -> projectInfo != null && projectInfo.getExternalProjectStructure() != null) + .map(projectInfo -> projectInfo.getExternalProjectStructure().getData()) + .filter(projectData -> projectsSettings.size() == 1 || StringUtil.startsWith(commandLine, projectData.getExternalName())) + .findFirst().orElse(null); } @NotNull @@ -121,6 +167,14 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { return GradleIcons.Gradle; } + @Nullable + @Override + public RunAnythingHelpItem getHelpItem(@NotNull DataContext dataContext) { + String placeholder = getHelpCommandPlaceholder(dataContext); + String commandPrefix = getHelpCommand(); + return new RunAnythingHelpItem(placeholder, commandPrefix, getHelpDescription(), getHelpIcon()); + } + @NotNull public String getCompletionGroupTitle() { return "Gradle tasks"; @@ -129,6 +183,17 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { @NotNull @Override public String getHelpCommandPlaceholder() { + return getHelpCommandPlaceholder(null); + } + + @NotNull + public String getHelpCommandPlaceholder(@Nullable DataContext dataContext) { + if (dataContext != null) { + Project project = fetchProject(dataContext); + if (GradleSettings.getInstance(project).getLinkedProjectsSettings().size() > 1) { + return "gradle <--option-name...>"; + } + } return "gradle <--option-name...>"; } @@ -143,20 +208,21 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { return GradleIcons.Gradle; } - private static MultiMap fetchTasks(@NotNull DataContext dataContext) { + private static Map> fetchTasks(@NotNull DataContext dataContext) { Project project = fetchProject(dataContext); return CachedValuesManager.getManager(project).getCachedValue( project, () -> CachedValueProvider.Result.create(getTasksMap(project), ProjectRootManager.getInstance(project))); } @NotNull - private static MultiMap getTasksMap(Project project) { - MultiMap tasks = MultiMap.createOrderedSet(); + private static Map> getTasksMap(Project project) { + Map> tasks = ContainerUtil.newLinkedHashMap(); for (GradleProjectSettings setting : GradleSettings.getInstance(project).getLinkedProjectsSettings()) { final ExternalProjectInfo projectData = ProjectDataManager.getInstance().getExternalProjectData(project, GradleConstants.SYSTEM_ID, setting.getExternalProjectPath()); if (projectData == null || projectData.getExternalProjectStructure() == null) continue; + MultiMap projectTasks = MultiMap.createOrderedSet(); for (DataNode moduleDataNode : getChildren(projectData.getExternalProjectStructure(), ProjectKeys.MODULE)) { String gradlePath; String moduleId = moduleDataNode.getData().getId(); @@ -172,10 +238,11 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase { String taskName = taskData.getName(); if (StringUtil.isNotEmpty(taskName)) { String taskPathPrefix = ":".equals(gradlePath) || taskName.startsWith(gradlePath) ? "" : (gradlePath + ':'); - tasks.putValue(taskPathPrefix, taskName); + projectTasks.putValue(taskPathPrefix, taskName); } } } + tasks.put(projectData.getExternalProjectStructure().getData(), projectTasks); } return tasks; }