diff --git a/plugins/gradle/java/src/execution/GradleRunnerUtil.java b/plugins/gradle/java/src/execution/GradleRunnerUtil.java index d93f5a9cbb44..c428c6d03093 100644 --- a/plugins/gradle/java/src/execution/GradleRunnerUtil.java +++ b/plugins/gradle/java/src/execution/GradleRunnerUtil.java @@ -9,7 +9,6 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; @@ -18,8 +17,12 @@ import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.model.data.BuildParticipant; import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil; +import org.jetbrains.plugins.gradle.settings.CompositeDefinitionSource; import org.jetbrains.plugins.gradle.settings.GradleExtensionsSettings; +import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; +import org.jetbrains.plugins.gradle.settings.GradleSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; @@ -65,13 +68,24 @@ public class GradleRunnerUtil { @Nullable public static String resolveProjectPath(@NotNull Module module) { final String rootProjectPath = ExternalSystemApiUtil.getExternalRootProjectPath(module); - String projectPath = ExternalSystemApiUtil.getExternalProjectPath(module); - + final String projectPath = ExternalSystemApiUtil.getExternalProjectPath(module); if (rootProjectPath == null || projectPath == null) return null; - if (!FileUtil.isAncestor(rootProjectPath, projectPath, false)) { - projectPath = rootProjectPath; + + GradleProjectSettings projectSettings = GradleSettings.getInstance(module.getProject()).getLinkedProjectSettings(rootProjectPath); + if (projectSettings != null && + projectSettings.getCompositeBuild() != null && + projectSettings.getCompositeBuild().getCompositeDefinitionSource() == CompositeDefinitionSource.SCRIPT) { + List buildParticipants = projectSettings.getCompositeBuild().getCompositeParticipants(); + String compositeProjectPath = buildParticipants.stream() + .filter(participant -> participant.getProjects().contains(projectPath)) + .findFirst() + .map(BuildParticipant::getRootPath) + .orElse(null); + if (compositeProjectPath != null) { + return compositeProjectPath; + } } - return projectPath; + return rootProjectPath; } public static boolean isFromGroovyGradleScript(@Nullable Location location) { diff --git a/plugins/gradle/java/src/execution/build/GradleApplicationEnvironmentProvider.java b/plugins/gradle/java/src/execution/build/GradleApplicationEnvironmentProvider.java index 68587e545179..a4da5117f69d 100644 --- a/plugins/gradle/java/src/execution/build/GradleApplicationEnvironmentProvider.java +++ b/plugins/gradle/java/src/execution/build/GradleApplicationEnvironmentProvider.java @@ -51,6 +51,7 @@ import com.intellij.task.ExecuteRunConfigurationTask; import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.execution.GradleRunnerUtil; import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil; import org.jetbrains.plugins.gradle.service.task.GradleTaskManager; import org.jetbrains.plugins.gradle.util.GradleConstants; @@ -107,7 +108,8 @@ public class GradleApplicationEnvironmentProvider implements GradleExecutionEnvi ExternalSystemTaskExecutionSettings taskSettings = new ExternalSystemTaskExecutionSettings(); taskSettings.setExternalSystemIdString(GradleConstants.SYSTEM_ID.getId()); - taskSettings.setExternalProjectPath(ExternalSystemApiUtil.getExternalProjectPath(module)); + String projectPath = GradleRunnerUtil.resolveProjectPath(module); + taskSettings.setExternalProjectPath(projectPath); final String runAppTaskName = mainClass.getName() + ".main()"; taskSettings.setTaskNames(Collections.singletonList(runAppTaskName)); diff --git a/plugins/gradle/java/src/execution/build/GradleProjectTaskRunner.java b/plugins/gradle/java/src/execution/build/GradleProjectTaskRunner.java index 43b612a4f062..beb0404dc5e9 100644 --- a/plugins/gradle/java/src/execution/build/GradleProjectTaskRunner.java +++ b/plugins/gradle/java/src/execution/build/GradleProjectTaskRunner.java @@ -30,12 +30,10 @@ import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExe import com.intellij.openapi.externalSystem.model.project.ModuleData; import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode; import com.intellij.openapi.externalSystem.task.TaskCallback; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.UserDataHolderBase; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.Artifact; import com.intellij.task.*; import com.intellij.task.impl.JpsProjectTaskRunner; @@ -47,11 +45,9 @@ import com.intellij.util.containers.MultiMap; import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.gradle.model.data.BuildParticipant; import org.jetbrains.plugins.gradle.service.project.GradleBuildSrcProjectsResolver; import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil; import org.jetbrains.plugins.gradle.service.task.GradleTaskManager; -import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; import org.jetbrains.plugins.gradle.settings.GradleSettings; import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; @@ -61,6 +57,9 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import static com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration.PROGRESS_LISTENER_KEY; +import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.*; +import static com.intellij.openapi.util.text.StringUtil.*; +import static org.jetbrains.plugins.gradle.execution.GradleRunnerUtil.resolveProjectPath; /** * TODO automatically create exploded-war task @@ -76,7 +75,7 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { @Language("Groovy") private static final String FORCE_COMPILE_TASKS_INIT_SCRIPT_TEMPLATE = "projectsEvaluated { \n" + - " rootProject.project('%s').tasks.withType(AbstractCompile) { \n" + + " rootProject.findProject('%s')?.tasks?.withType(AbstractCompile) { \n" + " outputs.upToDateWhen { false } \n" + " } \n" + "}\n"; @@ -169,7 +168,7 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { Collection scripts = initScripts.getModifiable(rootProjectPath); scripts.add(compilerOptionsInitScript); - userData.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, StringUtil.join(scripts, SystemProperties.getLineSeparator())); + userData.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, join(scripts, SystemProperties.getLineSeparator())); ExternalSystemUtil.runTask(settings, DefaultRunExecutor.EXECUTOR_ID, project, GradleConstants.SYSTEM_ID, taskCallback, ProgressExecutionMode.IN_BACKGROUND_ASYNC, false, userData); @@ -180,7 +179,7 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { public boolean canRun(@NotNull ProjectTask projectTask) { if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake()) return false; if (projectTask instanceof ModuleBuildTask) { - return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, ((ModuleBuildTask)projectTask).getModule()); + return isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, ((ModuleBuildTask)projectTask).getModule()); } if (projectTask instanceof ProjectModelBuildTask) { ProjectModelBuildTask buildTask = (ProjectModelBuildTask)projectTask; @@ -195,7 +194,7 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { RunProfile runProfile = ((ExecuteRunConfigurationTask)projectTask).getRunProfile(); if (runProfile instanceof ModuleBasedConfiguration) { RunConfigurationModule module = ((ModuleBasedConfiguration)runProfile).getConfigurationModule(); - if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module.getModule())) { + if (!isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module.getModule())) { return false; } } @@ -227,7 +226,7 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { if (ContainerUtil.isEmpty(projectTasks)) return Collections.emptyList(); List affectedModules = new SmartList<>(); - Map rootPathsMap = FactoryMap.create(module -> getGradleRootProjectPath(module)); + Map rootPathsMap = FactoryMap.create(module -> notNullize(resolveProjectPath(module))); final CachedModuleDataFinder moduleDataFinder = new CachedModuleDataFinder(); for (ProjectTask projectTask : projectTasks) { if (!(projectTask instanceof ModuleBuildTask)) continue; @@ -237,12 +236,12 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { affectedModules.add(module); final String rootProjectPath = rootPathsMap.get(module); - if (StringUtil.isEmpty(rootProjectPath)) continue; + if (isEmpty(rootProjectPath)) continue; - final String projectId = ExternalSystemApiUtil.getExternalProjectId(module); + final String projectId = getExternalProjectId(module); if (projectId == null) continue; - final String externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module); - if (externalProjectPath == null || StringUtil.endsWith(externalProjectPath, "buildSrc")) continue; + final String externalProjectPath = getExternalProjectPath(module); + if (externalProjectPath == null || endsWith(externalProjectPath, "buildSrc")) continue; final DataNode moduleDataNode = moduleDataFinder.findMainModuleData(module); if (moduleDataNode == null) continue; @@ -252,17 +251,17 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { continue; } - List gradleTasks = ContainerUtil.mapNotNull(ExternalSystemApiUtil.findAll(moduleDataNode, ProjectKeys.TASK), - node -> node.getData().isInherited() ? null : node.getData().getName()); + String gradlePath = GradleProjectResolverUtil.getGradlePath(module); + if (gradlePath == null) continue; + String taskPrefix = endsWithChar(gradlePath, ':') ? gradlePath : (gradlePath + ':'); + + List gradleTasks = ContainerUtil.mapNotNull( + findAll(moduleDataNode, ProjectKeys.TASK), node -> + node.getData().isInherited() ? null : trimStart(node.getData().getName(), taskPrefix)); Collection projectInitScripts = initScripts.getModifiable(rootProjectPath); Collection buildRootTasks = buildTasksMap.getModifiable(rootProjectPath); - final String moduleType = ExternalSystemApiUtil.getExternalModuleType(module); - String gradlePath = GradleProjectResolverUtil.getGradlePath(module); - if(gradlePath == null) continue; - if (!StringUtil.endsWithChar(gradlePath, ':')) { - gradlePath += ":"; - } + final String moduleType = getExternalModuleType(module); if (!moduleBuildTask.isIncrementalBuild()) { projectInitScripts.add(String.format(FORCE_COMPILE_TASKS_INIT_SCRIPT_TEMPLATE, gradlePath)); @@ -270,48 +269,27 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner { String assembleTask = "assemble"; if (GradleConstants.GRADLE_SOURCE_SET_MODULE_TYPE_KEY.equals(moduleType)) { String sourceSetName = GradleProjectResolverUtil.getSourceSetName(module); - String gradleTask = StringUtil.isEmpty(sourceSetName) || "main".equals(sourceSetName) ? "classes" : sourceSetName + "Classes"; + String gradleTask = isEmpty(sourceSetName) || "main".equals(sourceSetName) ? "classes" : sourceSetName + "Classes"; if (gradleTasks.contains(gradleTask)) { - buildRootTasks.add(gradlePath + gradleTask); + buildRootTasks.add(taskPrefix + gradleTask); } else if ("main".equals(sourceSetName) || "test".equals(sourceSetName)) { - buildRootTasks.add(gradlePath + assembleTask); + buildRootTasks.add(taskPrefix + assembleTask); } } else { if (gradleTasks.contains("classes")) { - buildRootTasks.add(gradlePath + "classes"); - buildRootTasks.add(gradlePath + "testClasses"); + buildRootTasks.add(taskPrefix + "classes"); + buildRootTasks.add(taskPrefix + "testClasses"); } else if (gradleTasks.contains(assembleTask)) { - buildRootTasks.add(gradlePath + assembleTask); + buildRootTasks.add(taskPrefix + assembleTask); } } } return affectedModules; } - @NotNull - private static String getGradleRootProjectPath(Module module) { - Project project = module.getProject(); - String rootProjectPath = ExternalSystemApiUtil.getExternalRootProjectPath(module); - if (rootProjectPath == null) return ""; - - final String projectPath = ExternalSystemApiUtil.getExternalProjectPath(module); - if (projectPath == null) return ""; - - GradleProjectSettings projectSettings = GradleSettings.getInstance(project).getLinkedProjectSettings(rootProjectPath); - if (projectSettings != null && projectSettings.getCompositeBuild() != null) { - List buildParticipants = projectSettings.getCompositeBuild().getCompositeParticipants(); - return buildParticipants.stream() - .filter(participant -> participant.getProjects().contains(projectPath)) - .findFirst() - .map(BuildParticipant::getRootPath) - .orElse(rootProjectPath); - } - return rootProjectPath; - } - private static void addArtifactsBuildTasks(@Nullable Collection tasks, @NotNull MultiMap cleanTasksMap, @NotNull MultiMap buildTasksMap) { diff --git a/plugins/gradle/java/src/execution/test/runner/GradleTestRunConfigurationProducer.java b/plugins/gradle/java/src/execution/test/runner/GradleTestRunConfigurationProducer.java index fca0bbae0827..61eec9d54501 100644 --- a/plugins/gradle/java/src/execution/test/runner/GradleTestRunConfigurationProducer.java +++ b/plugins/gradle/java/src/execution/test/runner/GradleTestRunConfigurationProducer.java @@ -30,6 +30,7 @@ import org.jetbrains.plugins.gradle.util.GradleConstants; import java.util.List; +import static com.intellij.openapi.util.text.StringUtil.endsWithChar; import static org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings.PreferredTestRunner.*; /** @@ -94,7 +95,6 @@ public abstract class GradleTestRunConfigurationProducer extends RunConfiguratio } } - final List result; final String externalProjectId = ExternalSystemApiUtil.getExternalProjectId(module); if (externalProjectId == null) return ContainerUtil.emptyList(); final String projectPath = ExternalSystemApiUtil.getExternalProjectPath(module); @@ -103,42 +103,37 @@ public abstract class GradleTestRunConfigurationProducer extends RunConfiguratio ExternalSystemUtil.getExternalProjectInfo(module.getProject(), GradleConstants.SYSTEM_ID, projectPath); if (externalProjectInfo == null) return ContainerUtil.emptyList(); - boolean trimSourceSet = false; + final List tasks; + final String gradlePath = GradleProjectResolverUtil.getGradlePath(module); + if (gradlePath == null) return ContainerUtil.emptyList(); + String taskPrefix = endsWithChar(gradlePath, ':') ? gradlePath : (gradlePath + ':'); + if (StringUtil.endsWith(externalProjectId, ":test") || StringUtil.endsWith(externalProjectId, ":main")) { - result = TEST_SOURCE_SET_TASKS; - trimSourceSet = true; + return ContainerUtil.map(TEST_SOURCE_SET_TASKS, task -> taskPrefix + task); + } + + final DataNode moduleNode = + GradleProjectResolverUtil.findModule(externalProjectInfo.getExternalProjectStructure(), projectPath); + if (moduleNode == null) return ContainerUtil.emptyList(); + + final DataNode taskNode; + final String sourceSetId = StringUtil.substringAfter(externalProjectId, moduleNode.getData().getExternalName() + ':'); + if (sourceSetId == null) { + taskNode = ExternalSystemApiUtil.find( + moduleNode, ProjectKeys.TASK, + node -> GradleCommonClassNames.GRADLE_API_TASKS_TESTING_TEST.equals(node.getData().getType()) && + StringUtil.equals("test", node.getData().getName()) || StringUtil.equals(taskPrefix + "test", node.getData().getName())); } else { - final DataNode moduleNode = - GradleProjectResolverUtil.findModule(externalProjectInfo.getExternalProjectStructure(), projectPath); - if (moduleNode == null) return ContainerUtil.emptyList(); - - final DataNode taskNode; - final String sourceSetId = StringUtil.substringAfter(externalProjectId, moduleNode.getData().getExternalName() + ':'); - if (sourceSetId == null) { - taskNode = ExternalSystemApiUtil.find( - moduleNode, ProjectKeys.TASK, - node -> GradleCommonClassNames.GRADLE_API_TASKS_TESTING_TEST.equals(node.getData().getType()) && - StringUtil.equals("test", node.getData().getName())); - } - else { - trimSourceSet = true; - taskNode = ExternalSystemApiUtil.find( - moduleNode, ProjectKeys.TASK, - node -> GradleCommonClassNames.GRADLE_API_TASKS_TESTING_TEST.equals(node.getData().getType()) && - StringUtil.startsWith(node.getData().getName(), sourceSetId)); - } - - if (taskNode == null) return ContainerUtil.emptyList(); - final String taskName = taskNode.getData().getName(); - result = ContainerUtil.list("clean" + StringUtil.capitalize(taskName), taskName); + taskNode = ExternalSystemApiUtil.find( + moduleNode, ProjectKeys.TASK, + node -> GradleCommonClassNames.GRADLE_API_TASKS_TESTING_TEST.equals(node.getData().getType()) && + StringUtil.startsWith(node.getData().getName(), sourceSetId)); } - final List pathParts = StringUtil.split(externalProjectId, ":"); - if (!externalProjectId.startsWith(":") && !pathParts.isEmpty()) pathParts.remove(0); - if (trimSourceSet && !pathParts.isEmpty()) pathParts.remove(pathParts.size() - 1); - String join = StringUtil.join(pathParts, ":"); - String path = ":" + join + (!join.isEmpty() ? ":" : ""); - return ContainerUtil.map(result, s -> path + s); + if (taskNode == null) return ContainerUtil.emptyList(); + String taskName = StringUtil.trimStart(taskNode.getData().getName(), taskPrefix); + tasks = ContainerUtil.list("clean" + StringUtil.capitalize(taskName), taskName); + return ContainerUtil.map(tasks, task -> taskPrefix + task); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java index e1f54f4ce78c..5be0e620f40b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java @@ -280,20 +280,16 @@ public class GradleProjectResolverUtil { @Nullable public static String getGradlePath(final Module module) { if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return null; - final String projectId = ExternalSystemApiUtil.getExternalProjectId(module); - if (projectId == null) return null; + final String externalProjectId = ExternalSystemApiUtil.getExternalProjectId(module); + if (externalProjectId == null) return null; + final String moduleType = ExternalSystemApiUtil.getExternalModuleType(module); - final String gradlePath; - if (GradleConstants.GRADLE_SOURCE_SET_MODULE_TYPE_KEY.equals(moduleType)) { - int lastColonIndex = projectId.lastIndexOf(':'); - assert lastColonIndex != -1; - int firstColonIndex = projectId.indexOf(':'); - gradlePath = firstColonIndex == lastColonIndex ? ":" : projectId.substring(firstColonIndex, lastColonIndex); - } - else { - gradlePath = projectId.charAt(0) == ':' ? projectId : ":"; - } - return gradlePath; + boolean trimSourceSet = GradleConstants.GRADLE_SOURCE_SET_MODULE_TYPE_KEY.equals(moduleType); + final List pathParts = StringUtil.split(externalProjectId, ":"); + if (!externalProjectId.startsWith(":") && !pathParts.isEmpty()) pathParts.remove(0); + if (trimSourceSet && !pathParts.isEmpty()) pathParts.remove(pathParts.size() - 1); + String join = StringUtil.join(pathParts, ":"); + return join.isEmpty() ? ":" : ":" + join; } @NotNull diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtilTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtilTest.java index 065d22ccc4de..40f005a0572f 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtilTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtilTest.java @@ -47,6 +47,9 @@ public class GradleProjectResolverUtilTest { final Module subModule = createModuleMock(":foo:subModule"); assertEquals(":foo:subModule", GradleProjectResolverUtil.getGradlePath(subModule)); + final Module compositeBuildSubModule = createModuleMock("composite:subModule"); + assertEquals(":subModule", GradleProjectResolverUtil.getGradlePath(compositeBuildSubModule)); + final Module sourceSetModule = createModuleMock("rootModule:main", GRADLE_SOURCE_SET_MODULE_TYPE_KEY); assertEquals(":", GradleProjectResolverUtil.getGradlePath(sourceSetModule));