diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index 39c02cc7e351..e828a42d8274 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -481,16 +481,16 @@ public class ExternalSystemUtil { DataNode externalProject = task.getExternalProject(); if(externalProject != null) { - Set myExternalModulePaths = ContainerUtil.newHashSet(); + Set externalModulePaths = ContainerUtil.newHashSet(); Collection> moduleNodes = ExternalSystemApiUtil.findAll(externalProject, ProjectKeys.MODULE); for (DataNode node : moduleNodes) { - myExternalModulePaths.add(node.getData().getLinkedExternalProjectPath()); + externalModulePaths.add(node.getData().getLinkedExternalProjectPath()); } String projectPath = externalProject.getData().getLinkedExternalProjectPath(); ExternalProjectSettings linkedProjectSettings = manager.getSettingsProvider().fun(project).getLinkedProjectSettings(projectPath); if (linkedProjectSettings != null) { - linkedProjectSettings.setModules(myExternalModulePaths); + linkedProjectSettings.setModules(externalModulePaths); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java index 65f31567a7ae..7186312c24b4 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java @@ -121,6 +121,14 @@ public enum GradleDependencyScope { return null; } + @Nullable + public static GradleDependencyScope fromIdeaMappingName(final String ideaMappingName) { + for (GradleDependencyScope scope : values()) { + if (scope.myIdeaMappingName.equals(ideaMappingName.toLowerCase())) return scope; + } + return null; + } + public String getIdeaMappingName() { return myIdeaMappingName; } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java index 11763a529ad5..05864829e6ed 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java @@ -62,12 +62,14 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { boolean downloadSources = true; final IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class); + Map>> userScopes = Collections.emptyMap(); if (ideaPlugin != null) { IdeaModel ideaModel = ideaPlugin.getModel(); - if (ideaModel != null && ideaModel.getModule() == null) { + if (ideaModel != null && ideaModel.getModule() != null) { offline = ideaModel.getModule().isOffline(); downloadJavadoc = ideaModel.getModule().isDownloadJavadoc(); downloadSources = ideaModel.getModule().isDownloadSources(); + userScopes = ideaModel.getModule().getScopes(); } } @@ -79,7 +81,7 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { dependenciesExtractor.extractProjectDependencies(plusConfigurations, new ArrayList()); for (IdeDependenciesExtractor.IdeProjectDependency ideProjectDependency : ideProjectDependencies) { - merge(scopesMap, ideProjectDependency); + merge(scopesMap, ideProjectDependency, userScopes); } if (!offline) { @@ -87,14 +89,14 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { dependenciesExtractor.extractRepoFileDependencies( project.getConfigurations(), plusConfigurations, new ArrayList(), downloadSources, downloadJavadoc); for (IdeDependenciesExtractor.IdeRepoFileDependency repoFileDependency : ideRepoFileDependencies) { - merge(scopesMap, repoFileDependency); + merge(scopesMap, repoFileDependency, userScopes); } } final List ideLocalFileDependencies = dependenciesExtractor.extractLocalFileDependencies(plusConfigurations, new ArrayList()); for (IdeDependenciesExtractor.IdeLocalFileDependency fileDependency : ideLocalFileDependencies) { - merge(scopesMap, fileDependency); + merge(scopesMap, fileDependency, userScopes); } } @@ -166,9 +168,11 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { return null; } - private static void merge(Map map, IdeDependenciesExtractor.IdeProjectDependency dependency) { + private static void merge(Map map, + IdeDependenciesExtractor.IdeProjectDependency dependency, + Map>> userScopes) { final String configurationName = dependency.getDeclaredConfiguration().getName(); - final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName); + final GradleDependencyScope scope = deduceScope(configurationName, userScopes); if (scope == null) return; final Project project = dependency.getProject(); @@ -190,9 +194,11 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { return String.valueOf(o == null ? "" : o); } - private static void merge(Map map, IdeDependenciesExtractor.IdeRepoFileDependency dependency) { + private static void merge(Map map, + IdeDependenciesExtractor.IdeRepoFileDependency dependency, + Map>> userScopes) { final String configurationName = dependency.getDeclaredConfiguration().getName(); - final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName); + final GradleDependencyScope scope = deduceScope(configurationName, userScopes); if (scope == null) return; final ModuleVersionIdentifier dependencyId; @@ -218,16 +224,18 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { } private static String parseClassifier(ModuleVersionIdentifier dependencyId, File dependencyFile) { - if(dependencyFile == null) return null; + if (dependencyFile == null) return null; String dependencyFileName = dependencyFile.getName(); int i = dependencyFileName.indexOf(dependencyId.getName() + '-' + dependencyId.getVersion() + '-'); return i != -1 ? dependencyFileName.substring(i, dependencyFileName.length()) : null; } - private static void merge(Map map, IdeDependenciesExtractor.IdeLocalFileDependency dependency) { + private static void merge(Map map, + IdeDependenciesExtractor.IdeLocalFileDependency dependency, + Map>> userScopes) { final String configurationName = dependency.getDeclaredConfiguration().getName(); - final GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName); + final GradleDependencyScope scope = deduceScope(configurationName, userScopes); if (scope == null) return; String path = dependency.getFile().getPath(); @@ -242,6 +250,33 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { } } + /** + * Deduce configuration scope based on configuration name using gradle conventions. + * IDEA gradle plugin only 'plus' configuration used to support configuration based on a custom configuration (not conventional) + * + * @param configurationName gradle configuration name + * @param userScopes gradle IDEA plugin scopes map + * @return deduced scope + */ + private static GradleDependencyScope deduceScope(String configurationName, + Map>> userScopes) { + GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName); + if (scope == null) { + for (Map.Entry>> entry : userScopes.entrySet()) { + Collection plusConfigurations = entry.getValue().get("plus"); + if (plusConfigurations == null) continue; + + for (Configuration plus : plusConfigurations) { + if (plus.getName().equals(configurationName)) { + return GradleDependencyScope.fromIdeaMappingName(entry.getKey()); + } + } + } + } + + return scope; + } + private static class MyModuleVersionIdentifier implements ModuleVersionIdentifier, Serializable { private final String myName; diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/Scopes.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/Scopes.java index 3c08f521a549..cc0155e5678d 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/Scopes.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/Scopes.java @@ -33,7 +33,9 @@ public class Scopes { myForProductionRuntime = scope.isForProductionRuntime(); myForTestCompile = scope.isForTestCompile(); myForTestRuntime = scope.isForTestRuntime(); - myIsProvided = scope == GradleDependencyScope.PROVIDED_COMPILE || scope == GradleDependencyScope.PROVIDED_RUNTIME; + myIsProvided = scope == GradleDependencyScope.PROVIDED_COMPILE || + scope == GradleDependencyScope.PROVIDED_RUNTIME || + scope == GradleDependencyScope.PROVIDED; } public GradleDependencyScope[] getScopes() { @@ -74,6 +76,9 @@ public class Scopes { myForProductionRuntime = myForProductionRuntime || scope.isForProductionRuntime(); myForTestCompile = myForTestCompile || scope.isForTestCompile(); myForTestRuntime = myForTestRuntime || scope.isForTestRuntime(); - myIsProvided = myIsProvided || scope == GradleDependencyScope.PROVIDED_COMPILE || scope == GradleDependencyScope.PROVIDED_RUNTIME; + myIsProvided = myIsProvided || + scope == GradleDependencyScope.PROVIDED_COMPILE || + scope == GradleDependencyScope.PROVIDED_RUNTIME || + scope == GradleDependencyScope.PROVIDED; } } diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle new file mode 100644 index 000000000000..6f9afa4b8d09 --- /dev/null +++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle @@ -0,0 +1,38 @@ +//noinspection GrPackage + +allprojects { + apply plugin: 'java' + apply plugin: 'idea' + + version = '1.0' + + sourceCompatibility = 1.6 + + configurations { + provided + } + + sourceSets { + main { + compileClasspath += configurations.provided + } + } + + idea { + module { + scopes.PROVIDED.plus += configurations.provided + } + } +} + +project(":service") { + dependencies { + compile (project(':api')) + } +} + +project(":api") { + dependencies { + provided(project(':lib')) + } +} \ No newline at end of file diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle new file mode 100644 index 000000000000..271f7343d37b --- /dev/null +++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle @@ -0,0 +1,4 @@ +//noinspection GrPackage +include "lib" +include "api" +include "service" \ No newline at end of file diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java index d34d8cfaba38..6bb9b6f5eb9c 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java @@ -20,6 +20,8 @@ import com.intellij.util.containers.ContainerUtil; import org.gradle.tooling.model.DomainObjectSet; import org.gradle.tooling.model.idea.IdeaDependency; import org.gradle.tooling.model.idea.IdeaModule; +import org.gradle.tooling.model.idea.IdeaModuleDependency; +import org.jetbrains.plugins.gradle.model.GradleDependencyScope; import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel; import org.junit.Test; @@ -53,6 +55,53 @@ public class ModelDependenciesBuilderImplTest extends AbstractModelBuilderTest { assertEquals(1, dependencies.size()); } + @Test + public void testGradleIdeaPluginPlusScopesDependenciesModel() throws Exception { + ModelDependenciesBuilderImpl dependenciesBuilder = new ModelDependenciesBuilderImpl(); + assertTrue(dependenciesBuilder.canBuild("org.jetbrains.plugins.gradle.model.ProjectDependenciesModel")); + + DomainObjectSet ideaModules = allModels.getIdeaProject().getModules(); + + // test api module dependencies + IdeaModule apiModule = ContainerUtil.find(ideaModules, new Condition() { + @Override + public boolean value(IdeaModule module) { + return module.getName().equals("api"); + } + }); + assertNotNull(apiModule); + + DomainObjectSet dependencies = apiModule.getDependencies(); + assertEquals(1, dependencies.size()); + IdeaDependency libDependency = dependencies.getAt(0); + assertEquals(GradleDependencyScope.PROVIDED.name(), libDependency.getScope().getScope()); + assertTrue(libDependency instanceof IdeaModuleDependency); + + IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency; + assertNotNull(libModuleDependency.getDependencyModule()); + assertEquals("lib", libModuleDependency.getDependencyModule().getName()); + + + // test service module dependencies + IdeaModule serviceModule = ContainerUtil.find(ideaModules, new Condition() { + @Override + public boolean value(IdeaModule module) { + return module.getName().equals("service"); + } + }); + assertNotNull(serviceModule); + + DomainObjectSet serviceModuleDependencies = serviceModule.getDependencies(); + assertEquals(1, serviceModuleDependencies.size()); + IdeaDependency apiDependency = serviceModuleDependencies.getAt(0); + assertEquals(GradleDependencyScope.COMPILE.name(), apiDependency.getScope().getScope()); + assertTrue(apiDependency instanceof IdeaModuleDependency); + + IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency; + assertNotNull(apiModuleDependency.getDependencyModule()); + assertEquals("api", apiModuleDependency.getDependencyModule().getName()); + } + @Override protected Set getModels() { return ContainerUtil.set(ProjectDependenciesModel.class);