Gradle run anything for multiple linked projects (IDEA-196883)

This commit is contained in:
Vladislav.Soroka
2018-08-09 19:23:27 +03:00
parent 2c4f1f00ae
commit 01924b1916
@@ -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> {
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<String> {
return result;
}
private static void appendTasksVariants(@NotNull List<String> result, @NotNull String prefix, @NotNull DataContext dataContext) {
MultiMap<String, String> tasks = fetchTasks(dataContext);
private void appendProjectsVariants(@NotNull List<String> result,
@NotNull DataContext dataContext,
@NotNull String prefix) {
if (!prefix.trim().equals(getHelpCommand())) return;
Project project = fetchProject(dataContext);
Collection<GradleProjectSettings> 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<String> 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<String, String> tasks = fetchTasks(dataContext).get(projectData);
if (tasks == null) return;
for (Map.Entry<String, Collection<String>> entry : tasks.entrySet()) {
for (String taskName : entry.getValue()) {
String taskFqn = entry.getKey() + taskName;
@@ -102,11 +131,28 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase<String> {
@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<GradleProjectSettings> 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<String> {
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<String> {
@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 <rootProjectName> <taskName...> <--option-name...>";
}
}
return "gradle <taskName...> <--option-name...>";
}
@@ -143,20 +208,21 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase<String> {
return GradleIcons.Gradle;
}
private static MultiMap<String, String> fetchTasks(@NotNull DataContext dataContext) {
private static Map<ProjectData, MultiMap<String, String>> 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<String, String> getTasksMap(Project project) {
MultiMap<String, String> tasks = MultiMap.createOrderedSet();
private static Map<ProjectData, MultiMap<String, String>> getTasksMap(Project project) {
Map<ProjectData, MultiMap<String, String>> 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<String, String> projectTasks = MultiMap.createOrderedSet();
for (DataNode<ModuleData> moduleDataNode : getChildren(projectData.getExternalProjectStructure(), ProjectKeys.MODULE)) {
String gradlePath;
String moduleId = moduleDataNode.getData().getId();
@@ -172,10 +238,11 @@ public class GradleRunAnythingProvider extends RunAnythingProviderBase<String> {
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;
}