From 68bfa5e533660c6de9ec3dbfa8c7e2938d6a6b1a Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Mon, 20 Jan 2014 18:00:49 +0400 Subject: [PATCH] Gradle: dependencies scope merge and sourceSets type handling updated related issues: IDEA-119365 Gradle import does not respect model customisations IDEA-118280 Gradle import: IDEA detect java folder as a resource folder IDEA-117668 IDEA v13 spontaneously changes additional test source root to source root --- .../gradle/config/GradleScriptType.java | 2 +- .../gradle/model/GradleDependencyScope.java | 13 +- .../builder/ModelDependenciesBuilderImpl.java | 14 +- .../ModuleExtendedModelBuilderImpl.java | 102 ++++++++-- .../plugins/gradle/model/internal/init.gradle | 4 + ...BuildClasspathModuleGradleDataService.java | 13 +- .../testDefaultDependenciesModel/build.gradle | 4 +- .../settings.gradle | 5 +- .../build.gradle | 21 ++- .../settings.gradle | 3 +- .../build.gradle | 74 ++++++++ .../settings.gradle | 8 + .../ModelDependenciesBuilderImplTest.java | 134 ++++++++----- .../ModuleExtendedModelBuilderImplTest.java | 177 ++++++++++++++++++ 14 files changed, 485 insertions(+), 89 deletions(-) create mode 100644 plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle create mode 100644 plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle create mode 100644 plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java index dbae55e12639..3038fe163810 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java @@ -310,7 +310,7 @@ public class GradleScriptType extends GroovyScriptType { if (!FileUtilRt.extensionEquals(file.getName(), GradleConstants.EXTENSION)) return baseScope; final Collection files; - GlobalSearchScope result = GlobalSearchScope.notScope(baseScope); + GlobalSearchScope result = GlobalSearchScope.EMPTY_SCOPE; final Module module = ModuleUtilCore.findModuleForPsiElement(file); if (module != null) { for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) { 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 7186312c24b4..78caa4d9f4d5 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java @@ -22,11 +22,6 @@ import org.jetbrains.annotations.Nullable; * @since 11/25/13 */ public enum GradleDependencyScope { - // Implicit scopes - PROVIDED("provided", "provided", true, true, true, true), - OPTIONAL("optional", "compile", true, true, true, true), - - // Java Plugin Scopes /** * Compile time dependencies @@ -74,7 +69,11 @@ public enum GradleDependencyScope { /** * Compiles test Scala source files. */ - COMPILE_TEST_SCALA("compileTestScala", "test", false, false, true, true); + COMPILE_TEST_SCALA("compileTestScala", "test", false, false, true, true), + + // Implicit scopes + PROVIDED("provided", "provided", true, true, true, true), + OPTIONAL("optional", "compile", true, true, true, true),; private final String myGradleName; private final String myIdeaMappingName; @@ -124,7 +123,7 @@ public enum GradleDependencyScope { @Nullable public static GradleDependencyScope fromIdeaMappingName(final String ideaMappingName) { for (GradleDependencyScope scope : values()) { - if (scope.myIdeaMappingName.equals(ideaMappingName.toLowerCase())) return scope; + if (scope.myIdeaMappingName.equals(ideaMappingName)) return scope; } return null; } 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 05864829e6ed..31797941dbce 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 @@ -261,15 +261,13 @@ public class ModelDependenciesBuilderImpl implements ModelBuilderService { 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 (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()); - } + for (Configuration plus : plusConfigurations) { + if (plus.getName().equals(configurationName)) { + return GradleDependencyScope.fromIdeaMappingName(entry.getKey().toLowerCase()); } } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java index 3dc854020c6c..44eb6cfe328b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.gradle.model.builder; +import groovy.lang.GroovyObject; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.tasks.SourceSet; @@ -69,10 +70,17 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { moduleVersionModel.setArtifacts(artifacts); + final Set sourceDirectories = new HashSet(); final Set testDirectories = new HashSet(); + final Set resourceDirectories = new HashSet(); + final Set testResourceDirectories = new HashSet(); + + final List testClassesDirs = new ArrayList(); for (Task task : project.getTasks()) { if (task instanceof Test) { Test test = (Test)task; + testClassesDirs.add(test.getTestClassesDir()); + if (test.hasProperty(TEST_SRC_DIRS_PROPERTY)) { Object testSrcDirs = test.property(TEST_SRC_DIRS_PROPERTY); if (testSrcDirs instanceof Iterable) { @@ -84,40 +92,58 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { } } - final Set javaDirectories = new HashSet(); - final Set resourceDirectories = new HashSet(); - if (project.hasProperty(SOURCE_SETS_PROPERTY)) { Object sourceSets = project.property(SOURCE_SETS_PROPERTY); if (sourceSets instanceof SourceSetContainer) { SourceSetContainer sourceSetContainer = (SourceSetContainer)sourceSets; for (SourceSet sourceSet : sourceSetContainer) { - for (File javaSrcDir : sourceSet.getAllJava().getSrcDirs()) { - addFilePath(javaDirectories, javaSrcDir); + for (File javaSrcDir : sourceSet.getJava().getSrcDirs()) { + boolean isTestDir = isTestDir(sourceSet, testClassesDirs); + addFilePath(isTestDir ? testDirectories : sourceDirectories, javaSrcDir); } for (File resourcesSrcDir : sourceSet.getResources().getSrcDirs()) { - addFilePath(resourceDirectories, resourcesSrcDir); + boolean isTestDir = isTestDir(sourceSet, testClassesDirs); + addFilePath(isTestDir ? testResourceDirectories : resourceDirectories, resourcesSrcDir); } } } } - File projectDir = project.getProjectDir(); IdeaContentRootImpl contentRoot = new IdeaContentRootImpl(projectDir); - enrichDataFromIdeaPlugin(project, contentRoot, javaDirectories, testDirectories); + final Set ideaSourceDirectories = new HashSet(); + final Set ideaTestDirectories = new HashSet(); + final Set ideaExtResourceDirectories = new HashSet(); + final Set ideaExtTestResourceDirectories = new HashSet(); + final Set excludeDirectories = new HashSet(); - javaDirectories.removeAll(testDirectories); - javaDirectories.removeAll(resourceDirectories); + enrichDataFromIdeaPlugin(project, excludeDirectories, ideaSourceDirectories, ideaTestDirectories, + ideaExtResourceDirectories, ideaExtTestResourceDirectories); - final Set testResourceDirectories = new HashSet(resourceDirectories); - testResourceDirectories.retainAll(testDirectories); + if (ideaSourceDirectories.isEmpty()) { + sourceDirectories.clear(); + resourceDirectories.clear(); + } + if (ideaTestDirectories.isEmpty()) { + testDirectories.clear(); + testResourceDirectories.clear(); + } - testDirectories.removeAll(resourceDirectories); - resourceDirectories.removeAll(testResourceDirectories); + ideaSourceDirectories.removeAll(resourceDirectories); + sourceDirectories.addAll(ideaSourceDirectories); + ideaTestDirectories.removeAll(testResourceDirectories); + testDirectories.addAll(ideaTestDirectories); - for (String javaDir : javaDirectories) { + resourceDirectories.addAll(ideaExtResourceDirectories); + testResourceDirectories.addAll(ideaExtTestResourceDirectories); + + // ensure disjoint directories with different type + resourceDirectories.removeAll(sourceDirectories); + testDirectories.removeAll(sourceDirectories); + testResourceDirectories.removeAll(testDirectories); + + for (String javaDir : sourceDirectories) { contentRoot.addSourceDirectory(new IdeaSourceDirectoryImpl(new File(javaDir))); } for (String testDir : testDirectories) { @@ -129,11 +155,29 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { for (String testResourceDir : testResourceDirectories) { contentRoot.addTestResourceDirectory(new IdeaSourceDirectoryImpl(new File(testResourceDir))); } + for (File excludeDir : excludeDirectories) { + contentRoot.addExcludeDirectory(excludeDir); + } moduleVersionModel.setContentRoots(Collections.singleton(contentRoot)); return moduleVersionModel; } + private static boolean isTestDir(SourceSet sourceSet, List testClassesDirs) { + if (SourceSet.TEST_SOURCE_SET_NAME.equals(sourceSet.getName())) return true; + if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) return false; + + File sourceSetClassesDir = sourceSet.getOutput().getClassesDir(); + for (File testClassesDir : testClassesDirs) { + do { + if (sourceSetClassesDir.getPath().equals(testClassesDir.getPath())) return true; + } + while ((testClassesDir = testClassesDir.getParentFile()) != null); + } + + return false; + } + private static void addFilePath(Set filePathSet, Object file) { if (file instanceof File) { try { @@ -145,9 +189,11 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { } private static void enrichDataFromIdeaPlugin(Project project, - IdeaContentRootImpl contentRoot, + Set excludeDirectories, Set javaDirectories, - Set testDirectories) { + Set testDirectories, + Set ideaExtResourceDirectories, + Set ideaExtTestResourceDirectories) { IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class); if (ideaPlugin == null) return; @@ -156,7 +202,7 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { if (ideaModel == null || ideaModel.getModule() == null) return; for (File excludeDir : ideaModel.getModule().getExcludeDirs()) { - contentRoot.addExcludeDirectory(excludeDir); + excludeDirectories.add(excludeDir); } for (File file : ideaModel.getModule().getSourceDirs()) { javaDirectories.add(file.getPath()); @@ -164,5 +210,25 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { for (File file : ideaModel.getModule().getTestSourceDirs()) { testDirectories.add(file.getPath()); } + + ideaExtResourceDirectories.addAll(getExtDirs("resourceDirs", ideaModel.getModule())); + ideaExtTestResourceDirectories.addAll(getExtDirs("testResourceDirs", ideaModel.getModule())); + } + + private static List getExtDirs(String propertyName, GroovyObject ideaModule) { + List directories = new ArrayList(); + Object resourceDirs = ideaModule.getProperty(propertyName); + if (resourceDirs instanceof Iterable) { + for (Object o : Iterable.class.cast(resourceDirs)) { + if (o instanceof File) { + directories.add(File.class.cast(o).getPath()); + } + else if (o instanceof String) { + directories.add((String)o); + } + } + } + + return directories; } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle index a788cb85d83d..4f382fd42590 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle @@ -34,6 +34,10 @@ try { URLClassLoader classLoader = new URLClassLoader(urls, getClass().classLoader) Class modelClass = classLoader.loadClass('org.jetbrains.plugins.gradle.model.internal.ExtraModelBuilder') allprojects { + apply plugin: 'idea' + idea.module.ext.set('resourceDirs', []) + idea.module.ext.set('testResourceDirs', []) + ext.jetExtraModelBuilderClass = modelClass apply plugin: JetGradlePlugin } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java index 4487df9cd6e6..907f2903ef09 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java @@ -46,6 +46,7 @@ import org.jetbrains.plugins.gradle.util.GradleConstants; import java.io.File; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Set; @@ -129,7 +130,8 @@ public class BuildClasspathModuleGradleDataService implements ProjectDataService } } - ExternalProjectBuildClasspathPojo projectBuildClasspathPojo = localSettings.getProjectBuildClasspath().get(linkedExternalProjectPath); + ExternalProjectBuildClasspathPojo projectBuildClasspathPojo = + localSettings.getProjectBuildClasspath().get(linkedExternalProjectPath); if (projectBuildClasspathPojo == null) { projectBuildClasspathPojo = new ExternalProjectBuildClasspathPojo( moduleDataNode.getData().getExternalName(), @@ -138,8 +140,13 @@ public class BuildClasspathModuleGradleDataService implements ProjectDataService localSettings.getProjectBuildClasspath().put(linkedExternalProjectPath, projectBuildClasspathPojo); } - projectBuildClasspathPojo - .setProjectBuildClasspath(ContainerUtil.newArrayList(externalProjectGradleSdkLibs.get(linkedExternalProjectPath))); + List projectBuildClasspath = ContainerUtil.newArrayList(externalProjectGradleSdkLibs.get(linkedExternalProjectPath)); + // add main java root of buildSrc project + projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/java"); + // add main groovy root of buildSrc project + projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/groovy"); + + projectBuildClasspathPojo.setProjectBuildClasspath(projectBuildClasspath); projectBuildClasspathPojo.getModulesBuildClasspath().put( externalModulePath, new ExternalModuleBuildClasspathPojo(externalModulePath, ContainerUtil.newArrayList(buildClasspath))); } diff --git a/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle b/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle index 849b1b486dd2..a6c9dde56871 100644 --- a/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle +++ b/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle @@ -4,8 +4,8 @@ allprojects{ apply plugin: 'java' } -project(":group2:subgroup11:project") { +project("dependentProject") { dependencies { - compile project(":project") + compile project(":dependencyProject") } } \ No newline at end of file diff --git a/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle b/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle index cf870fe6d6d1..ef853f062e1c 100644 --- a/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle +++ b/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle @@ -1,5 +1,4 @@ //noinspection GrPackage -include 'group1:subgroup11:project' -include 'group2:subgroup11:project' -include 'project' \ No newline at end of file +include 'dependencyProject' +include 'dependentProject' \ No newline at end of file diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle index 6f9afa4b8d09..73cb6a15b5cd 100644 --- a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle +++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle @@ -27,7 +27,7 @@ allprojects { project(":service") { dependencies { - compile (project(':api')) + compile(project(':api')) } } @@ -35,4 +35,21 @@ project(":api") { dependencies { provided(project(':lib')) } -} \ No newline at end of file +} + +project(":withIdeaModelCustomisations") { + dependencies { + //compile 'org.slf4j:slf4j-api:1.7.5' + //testCompile 'junit:junit:4.11' + + compile files("lib/someDep.jar") + testCompile files("lib/someTestDep.jar") + } + + idea { + module { + scopes.COMPILE.plus += scopes.TEST.plus + scopes.TEST.plus = [] + } + } +} diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle index 271f7343d37b..26ee835a9fb1 100644 --- a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle +++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle @@ -1,4 +1,5 @@ //noinspection GrPackage include "lib" include "api" -include "service" \ No newline at end of file +include "service" +include "withIdeaModelCustomisations" \ No newline at end of file diff --git a/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle new file mode 100644 index 000000000000..8c7584942858 --- /dev/null +++ b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle @@ -0,0 +1,74 @@ +//noinspection GrPackage + +project("defaultJavaModule") { + apply plugin: "java" +} + +project("moduleWithSourceSetDirBothAsResourceAndJava") { + apply plugin: "java" + + sourceSets.main.resources.srcDir 'src/main/java' + sourceSets.test.resources.srcDir 'src/test/java' +} + +project("moduleWithCustomSourceSet") { + apply plugin: "java" + + sourceSets { + custom + } + + sourceSets.custom.java.srcDir 'src/custom/java' +} + +project("withIntegrationTests") { + apply plugin: 'java' + + sourceSets { + integrationTest { + java.srcDir file('src/integration-test/java') + resources.srcDir file('src/integration-test/resources') + } + } + + dependencies { + integrationTestCompile sourceSets.main.output + integrationTestCompile configurations.testCompile + integrationTestCompile sourceSets.test.output + integrationTestRuntime configurations.testRuntime + } + + //noinspection GrUnresolvedAccess + task integrationTest(type: Test, dependsOn: jar) { + testClassesDir = sourceSets.integrationTest.output.classesDir + classpath = sourceSets.integrationTest.runtimeClasspath + } + + check.dependsOn integrationTest +} + +project("withIdeaPluginCustomization1") { + apply plugin: 'java' + + idea { + module { + testSourceDirs += file('src/intTest/java') + testSourceDirs += file('src/intTest/resources') + excludeDirs += file('some-extra-exclude-folder') + } + } +} + +// see http://youtrack.jetbrains.com/issue/IDEA-119365 +project("withIdeaPluginCustomization2") { + apply plugin: 'java' + + idea { + module { + sourceDirs += testSourceDirs + testSourceDirs = [] + ext.resourceDirs += file('some-extra-resource-folder') + ext.testResourceDirs += file('some-extra-test-resource-folder') + } + } +} diff --git a/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle new file mode 100644 index 000000000000..4f7ab785f8fd --- /dev/null +++ b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle @@ -0,0 +1,8 @@ +//noinspection GrPackage + +include 'defaultJavaModule' +include 'moduleWithSourceSetDirBothAsResourceAndJava' +include 'moduleWithCustomSourceSet' +include 'withIntegrationTests' +include 'withIdeaPluginCustomization1' +include 'withIdeaPluginCustomization2' \ 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 6bb9b6f5eb9c..8cf50ef62af5 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 @@ -15,19 +15,26 @@ */ package org.jetbrains.plugins.gradle.model.builder; -import com.intellij.openapi.util.Condition; +import com.intellij.util.Function; 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.gradle.tooling.model.idea.IdeaSingleEntryLibraryDependency; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.gradle.model.GradleDependencyScope; import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel; +import org.junit.Assert; import org.junit.Test; +import java.util.List; import java.util.Set; -import static org.junit.Assert.*; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * @author Vladislav.Soroka @@ -42,17 +49,29 @@ public class ModelDependenciesBuilderImplTest extends AbstractModelBuilderTest { DomainObjectSet ideaModules = allModels.getIdeaProject().getModules(); - IdeaModule ideaModule = ContainerUtil.find(ideaModules, new Condition() { - @Override - public boolean value(IdeaModule module) { - return module.getName().equals("group2-subgroup11-project"); + final int modulesSize = 3; + assertEquals(modulesSize, ideaModules.size()); + + for (IdeaModule ideaModule : ideaModules) { + if (ideaModule.getName().equals("dependencyProject") || + ideaModule.getName().equals("testDefaultDependenciesModel")) { + DomainObjectSet dependencies = ideaModule.getDependencies(); + assertTrue((dependencies.isEmpty())); } - }); + else if (ideaModule.getName().equals("dependentProject")) { + DomainObjectSet dependencies = ideaModule.getDependencies(); + assertEquals(1, dependencies.size()); + assertTrue(dependencies.getAt(0) instanceof IdeaModuleDependency); + IdeaModuleDependency moduleDependency = (IdeaModuleDependency)dependencies.getAt(0); - assertNotNull(ideaModule); - - DomainObjectSet dependencies = ideaModule.getDependencies(); - assertEquals(1, dependencies.size()); + assertEquals("dependencyProject", moduleDependency.getDependencyModule().getName()); + assertEquals("COMPILE", moduleDependency.getScope().getScope()); + assertTrue(moduleDependency.getExported()); + } + else { + fail(); + } + } } @Test @@ -62,44 +81,71 @@ public class ModelDependenciesBuilderImplTest extends AbstractModelBuilderTest { 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"); + final int modulesSize = 5; + assertEquals(modulesSize, ideaModules.size()); + + for (IdeaModule ideaModule : ideaModules) { + DomainObjectSet dependencies = ideaModule.getDependencies(); + if (ideaModule.getName().equals("lib") || + ideaModule.getName().equals("testGradleIdeaPluginPlusScopesDependenciesModel")) { + assertTrue((dependencies.isEmpty())); } - }); - assertNotNull(apiModule); + else if (ideaModule.getName().equals("api")) { + assertEquals(1, dependencies.size()); + IdeaDependency libDependency = dependencies.getAt(0); + assertEquals(GradleDependencyScope.PROVIDED.getIdeaMappingName(), libDependency.getScope().getScope().toLowerCase()); + assertTrue(libDependency instanceof IdeaModuleDependency); - 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"); + IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency; + assertNotNull(libModuleDependency.getDependencyModule()); + assertEquals("lib", libModuleDependency.getDependencyModule().getName()); } - }); - assertNotNull(serviceModule); + else if (ideaModule.getName().equals("service")) { + assertEquals(1, dependencies.size()); + IdeaDependency apiDependency = dependencies.getAt(0); + assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), apiDependency.getScope().getScope().toLowerCase()); + assertTrue(apiDependency instanceof IdeaModuleDependency); - 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()); + } + else if (ideaModule.getName().equals("withIdeaModelCustomisations")) { - IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency; - assertNotNull(apiModuleDependency.getDependencyModule()); - assertEquals("api", apiModuleDependency.getDependencyModule().getName()); + assertTrue(findLocalLibraries(dependencies, GradleDependencyScope.TEST_COMPILE.getIdeaMappingName()).isEmpty()); + + List libraryDependencies = + findLocalLibraries(dependencies, GradleDependencyScope.COMPILE.getIdeaMappingName()); + assertEquals(2, libraryDependencies.size()); + + IdeaSingleEntryLibraryDependency someDep = libraryDependencies.get(0); + assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), someDep.getScope().getScope().toLowerCase()); + assertEquals("someDep.jar", someDep.getFile().getName()); + + IdeaSingleEntryLibraryDependency someTestDep = libraryDependencies.get(1); + assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), someTestDep.getScope().getScope().toLowerCase()); + assertEquals("someTestDep.jar", someTestDep.getFile().getName()); + } + else { + fail(); + } + } + } + + @NotNull + private static List findLocalLibraries( + @NotNull final DomainObjectSet dependencies, @NotNull final String scope) { + return ContainerUtil.mapNotNull( + dependencies, + new Function() { + @Override + public IdeaSingleEntryLibraryDependency fun(IdeaDependency dependency) { + return dependency instanceof IdeaSingleEntryLibraryDependency && scope.equals(dependency.getScope().getScope().toLowerCase()) + ? (IdeaSingleEntryLibraryDependency)dependency + : null; + } + } + ); } @Override diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java new file mode 100644 index 000000000000..9694c9d37345 --- /dev/null +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java @@ -0,0 +1,177 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.gradle.model.builder; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.gradle.tooling.model.DomainObjectSet; +import org.gradle.tooling.model.idea.IdeaModule; +import org.gradle.tooling.model.idea.IdeaSourceDirectory; +import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot; +import org.jetbrains.plugins.gradle.model.ModuleExtendedModel; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Vladislav.Soroka + * @since 1/16/14 + */ +public class ModuleExtendedModelBuilderImplTest extends AbstractModelBuilderTest { + + @Test + public void testGradleSourcesSetsInterpretation() throws Exception { + final int modulesSize = 7; + + ModuleExtendedModelBuilderImpl moduleExtendedModelBuilder = new ModuleExtendedModelBuilderImpl(); + assertTrue(moduleExtendedModelBuilder.canBuild("org.jetbrains.plugins.gradle.model.ModuleExtendedModel")); + + DomainObjectSet ideaModules = allModels.getIdeaProject().getModules(); + + List models = + ContainerUtil.mapNotNull(ideaModules, new Function() { + @Override + public ModuleExtendedModel fun(IdeaModule module) { + ModuleExtendedModel moduleExtendedModel = allModels.getExtraProject(module, ModuleExtendedModel.class); + + assertNotNull(moduleExtendedModel); + + List sourceDirectories = ContainerUtil.newArrayList(); + List resourceDirectories = ContainerUtil.newArrayList(); + List testResourceDirectories = ContainerUtil.newArrayList(); + List testDirectories = ContainerUtil.newArrayList(); + List excludeDirectories = ContainerUtil.newArrayList(); + + fillDirectories(moduleExtendedModel, + sourceDirectories, resourceDirectories, + testDirectories, testResourceDirectories, + excludeDirectories); + + if (module.getName().equals("defaultJavaModule") || module.getName().equals("moduleWithSourceSetDirBothAsResourceAndJava")) { + assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/test/java"), testDirectories); + assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories); + assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories); + } + else if (module.getName().equals("moduleWithCustomSourceSet")) { + assertEquals(ContainerUtil.newArrayList("src/custom/java", "src/main/java"), sourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/custom/resources", "src/main/resources"), resourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/test/java"), testDirectories); + assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories); + assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories); + } + else if (module.getName().equals("withIntegrationTests")) { + assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories); + assertEquals(ContainerUtil.newArrayList( + "src/integration-test/java", "src/integrationTest/java", "src/test/java"), testDirectories); + assertEquals(ContainerUtil.newArrayList( + "src/integration-test/resources", + "src/integrationTest/resources", + "src/test/resources"), testResourceDirectories); + assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories); + } + else if (module.getName().equals("testGradleSourcesSetsInterpretation")) { + assertTrue(sourceDirectories.isEmpty()); + assertTrue(resourceDirectories.isEmpty()); + assertTrue(testDirectories.isEmpty()); + assertTrue(testResourceDirectories.isEmpty()); + assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories); + } + else if (module.getName().equals("withIdeaPluginCustomization1")) { + assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories); + assertEquals(ContainerUtil.newArrayList("src/intTest/java", "src/intTest/resources", "src/test/java"), testDirectories); + assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories); + assertEquals(ContainerUtil.newArrayList(".gradle", "build", "some-extra-exclude-folder"), excludeDirectories); + } + else if (module.getName().equals("withIdeaPluginCustomization2")) { + assertEquals(ContainerUtil.newArrayList("src/main/java", "src/test/java", "src/test/resources"), sourceDirectories); + assertEquals(ContainerUtil.newArrayList("some-extra-resource-folder", "src/main/resources"), resourceDirectories); + assertTrue(testDirectories.isEmpty()); + assertEquals(ContainerUtil.newArrayList("some-extra-test-resource-folder"), testResourceDirectories); + assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories); + } + else { + fail(); + } + + return moduleExtendedModel; + } + }); + + assertEquals(modulesSize, models.size()); + } + + private void fillDirectories(final ModuleExtendedModel model, + List sourceDirectories, List resourceDirectories, + List testDirectories, List resourceTestDirectories, + List excludeDirectories) { + for (ExtIdeaContentRoot contentRoot : model.getContentRoots()) { + sourceDirectories.addAll(getAllPaths(contentRoot.getSourceDirectories(), model.getName())); + resourceDirectories.addAll(getAllPaths(contentRoot.getResourceDirectories(), model.getName())); + testDirectories.addAll(getAllPaths(contentRoot.getTestDirectories(), model.getName())); + resourceTestDirectories.addAll(getAllPaths(contentRoot.getTestResourceDirectories(), model.getName())); + excludeDirectories.addAll(getAllPaths(contentRoot.getExcludeDirectories(), model.getName())); + } + } + + private Collection getAllPaths(Collection directories, final String moduleName) { + List list = ContainerUtil.map2List(directories, new Function() { + @Override + public String fun(File sourceDirectory) { + String path = + FileUtil.toCanonicalPath(FileUtil.getRelativePath(new File(testDir, moduleName), sourceDirectory)); + Assert.assertNotNull(path); + return path.substring(path.indexOf("/") + 1); + } + }); + Collections.sort(list); + return list; + } + + private Collection getAllPaths(DomainObjectSet directories, final String moduleName) { + List list = ContainerUtil.map2List(directories, new Function() { + @Override + public String fun(IdeaSourceDirectory sourceDirectory) { + String path = + FileUtil.toCanonicalPath(FileUtil.getRelativePath(new File(testDir, moduleName), sourceDirectory.getDirectory())); + Assert.assertNotNull(path); + return path.substring(path.indexOf("/") + 1); + } + }); + Collections.sort(list); + return list; + } + + @Override + protected Set getModels() { + return ContainerUtil.set(ModuleExtendedModel.class); + } +} +