IDEA-191014 Cannot Build Project and run tests when having Gradle composite project of multiprojects

This commit is contained in:
Vladislav.Soroka
2018-05-24 18:20:31 +03:00
parent 2d8b758a66
commit 6532caa803
6 changed files with 89 additions and 101 deletions
@@ -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<BuildParticipant> 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) {
@@ -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));
@@ -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<String> 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<Module> affectedModules = new SmartList<>();
Map<Module, String> rootPathsMap = FactoryMap.create(module -> getGradleRootProjectPath(module));
Map<Module, String> 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<? extends ModuleData> moduleDataNode = moduleDataFinder.findMainModuleData(module);
if (moduleDataNode == null) continue;
@@ -252,17 +251,17 @@ public class GradleProjectTaskRunner extends ProjectTaskRunner {
continue;
}
List<String> 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<String> gradleTasks = ContainerUtil.mapNotNull(
findAll(moduleDataNode, ProjectKeys.TASK), node ->
node.getData().isInherited() ? null : trimStart(node.getData().getName(), taskPrefix));
Collection<String> projectInitScripts = initScripts.getModifiable(rootProjectPath);
Collection<String> 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<BuildParticipant> 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<? extends ProjectTask> tasks,
@NotNull MultiMap<String, String> cleanTasksMap,
@NotNull MultiMap<String, String> buildTasksMap) {
@@ -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<String> 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<String> 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<ModuleData> moduleNode =
GradleProjectResolverUtil.findModule(externalProjectInfo.getExternalProjectStructure(), projectPath);
if (moduleNode == null) return ContainerUtil.emptyList();
final DataNode<TaskData> 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<ModuleData> moduleNode =
GradleProjectResolverUtil.findModule(externalProjectInfo.getExternalProjectStructure(), projectPath);
if (moduleNode == null) return ContainerUtil.emptyList();
final DataNode<TaskData> 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<String> 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);
}
}
@@ -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<String> 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
@@ -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));