From becfafc77db0d015e831b43417700c13f8523d78 Mon Sep 17 00:00:00 2001 From: adammurdoch Date: Tue, 8 Dec 2009 14:50:20 +1100 Subject: [PATCH] GRADLE-198 - Fix eclipse plugin to handle groovy projects. Slight modification of patch supplied by Shaun Mangelsdorf. --- build.gradle | 1 + .../internal/plugins/AbstractConvention.java | 12 ++++- .../org/gradle/api/plugins/Convention.java | 9 ++++ .../api/tasks/ide/eclipse/ProjectType.java | 8 ++++ .../plugins/DefaultConventionTest.groovy | 19 +++++++- .../tasks/ide/eclipse/EclipseProjectTest.java | 7 +++ .../ide/eclipse/expectedGroovyProjectFile.txt | 17 +++++++ .../org/gradle/api/plugins/EclipsePlugin.java | 44 ++++++++++++++++--- 8 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 subprojects/gradle-core/src/test/resources/org/gradle/api/tasks/ide/eclipse/expectedGroovyProjectFile.txt diff --git a/build.gradle b/build.gradle index 0e07c954992a..4ac039dec765 100644 --- a/build.gradle +++ b/build.gradle @@ -71,6 +71,7 @@ def FIRST_LEVEL_JMOCK = ['org.hamcrest:hamcrest-core:1.1@jar', 'org.hamcrest:ham configure(groovyProjects()) { usePlugin 'groovy' usePlugin 'code-quality' + usePlugin 'eclipse' archivesBaseName = "gradle-${name.replaceAll("\\p{Upper}") { "-${it.toLowerCase()}" } }" dependencies { diff --git a/subprojects/gradle-core/src/main/groovy/org/gradle/api/internal/plugins/AbstractConvention.java b/subprojects/gradle-core/src/main/groovy/org/gradle/api/internal/plugins/AbstractConvention.java index 4f89d8697a4a..42113760352e 100644 --- a/subprojects/gradle-core/src/main/groovy/org/gradle/api/internal/plugins/AbstractConvention.java +++ b/subprojects/gradle-core/src/main/groovy/org/gradle/api/internal/plugins/AbstractConvention.java @@ -100,6 +100,15 @@ public boolean hasMethod(String method, Object... args) { } public T getPlugin(Class type) { + T value = findPlugin(type); + if (value == null) { + throw new IllegalStateException(String.format("Could not find any convention object of type %s.", + type.getSimpleName())); + } + return value; + } + + public T findPlugin(Class type) throws IllegalStateException { List values = new ArrayList(); for (Object object : plugins.values()) { if (type.isInstance(object)) { @@ -107,8 +116,7 @@ public T getPlugin(Class type) { } } if (values.isEmpty()) { - throw new IllegalStateException(String.format("Could not find any convention object of type %s.", - type.getSimpleName())); + return null; } if (values.size() > 1) { throw new IllegalStateException(String.format("Found multiple convention objects of type %s.", diff --git a/subprojects/gradle-core/src/main/groovy/org/gradle/api/plugins/Convention.java b/subprojects/gradle-core/src/main/groovy/org/gradle/api/plugins/Convention.java index b885878a7c00..047df3b68a37 100644 --- a/subprojects/gradle-core/src/main/groovy/org/gradle/api/plugins/Convention.java +++ b/subprojects/gradle-core/src/main/groovy/org/gradle/api/plugins/Convention.java @@ -45,4 +45,13 @@ public interface Convention extends DynamicObject { * multiple such objects. */ T getPlugin(Class type) throws IllegalStateException; + + /** + * Locates the plugin convention object with the given type. + * + * @param type The convention object type. + * @return The object. Returns null if there is no such object. + * @throws IllegalStateException When there there are multiple matching objects. + */ + T findPlugin(Class type) throws IllegalStateException; } diff --git a/subprojects/gradle-core/src/main/groovy/org/gradle/api/tasks/ide/eclipse/ProjectType.java b/subprojects/gradle-core/src/main/groovy/org/gradle/api/tasks/ide/eclipse/ProjectType.java index 1e361a3822cd..c272acb5e523 100644 --- a/subprojects/gradle-core/src/main/groovy/org/gradle/api/tasks/ide/eclipse/ProjectType.java +++ b/subprojects/gradle-core/src/main/groovy/org/gradle/api/tasks/ide/eclipse/ProjectType.java @@ -30,6 +30,14 @@ public List natureNames() { return WrapUtil.toList("org.eclipse.jdt.core.javanature"); } }; + public static final ProjectType GROOVY = new ProjectType() { + public List buildCommandNames() { + return WrapUtil.toList("org.eclipse.jdt.core.javabuilder"); + } + public List natureNames() { + return WrapUtil.toList("org.eclipse.jdt.groovy.core.groovyNature", "org.eclipse.jdt.core.javanature"); + } + }; public static final ProjectType SIMPLE = new ProjectType() { public List buildCommandNames() { return new ArrayList(); diff --git a/subprojects/gradle-core/src/test/groovy/org/gradle/api/internal/plugins/DefaultConventionTest.groovy b/subprojects/gradle-core/src/test/groovy/org/gradle/api/internal/plugins/DefaultConventionTest.groovy index 84ab73e9c979..fa856d35b853 100644 --- a/subprojects/gradle-core/src/test/groovy/org/gradle/api/internal/plugins/DefaultConventionTest.groovy +++ b/subprojects/gradle-core/src/test/groovy/org/gradle/api/internal/plugins/DefaultConventionTest.groovy @@ -94,9 +94,11 @@ class DefaultConventionTest { @Test public void testCanLocateConventionObjectByType() { assertSame(convention1, convention.getPlugin(TestPluginConvention1)) assertSame(convention2, convention.getPlugin(TestPluginConvention2)) + assertSame(convention1, convention.findPlugin(TestPluginConvention1)) + assertSame(convention2, convention.findPlugin(TestPluginConvention2)) } - @Test public void testFailsWhenMultipleConventionObjectsWithCompatibleType() { + @Test public void testGetPluginFailsWhenMultipleConventionObjectsWithCompatibleType() { try { convention.getPlugin(Object) fail() @@ -105,7 +107,16 @@ class DefaultConventionTest { } } - @Test public void testFailsWhenNoConventionObjectsWithCompatibleType() { + @Test public void testFindPluginFailsWhenMultipleConventionObjectsWithCompatibleType() { + try { + convention.getPlugin(Object) + fail() + } catch (java.lang.IllegalStateException e) { + assertThat(e.message, equalTo('Found multiple convention objects of type Object.')) + } + } + + @Test public void testGetPluginFailsWhenNoConventionObjectsWithCompatibleType() { try { convention.getPlugin(String) fail() @@ -113,4 +124,8 @@ class DefaultConventionTest { assertThat(e.message, equalTo('Could not find any convention object of type String.')) } } + + @Test public void testFindPluginReturnsNullWhenNoConventionObjectsWithCompatibleType() { + assertNull(convention.findPlugin(String)) + } } diff --git a/subprojects/gradle-core/src/test/groovy/org/gradle/api/tasks/ide/eclipse/EclipseProjectTest.java b/subprojects/gradle-core/src/test/groovy/org/gradle/api/tasks/ide/eclipse/EclipseProjectTest.java index 9669d787e8cb..669be8a6bb84 100644 --- a/subprojects/gradle-core/src/test/groovy/org/gradle/api/tasks/ide/eclipse/EclipseProjectTest.java +++ b/subprojects/gradle-core/src/test/groovy/org/gradle/api/tasks/ide/eclipse/EclipseProjectTest.java @@ -44,6 +44,13 @@ public void setUp() { eclipseProject.setProjectName("myProject"); } + @Test + public void generateGroovyProject() throws IOException { + eclipseProject.setProjectType(ProjectType.GROOVY); + eclipseProject.execute(); + checkProjectFile("expectedGroovyProjectFile.txt"); + } + @Test public void generateJavaProject() throws IOException { eclipseProject.setProjectType(ProjectType.JAVA); diff --git a/subprojects/gradle-core/src/test/resources/org/gradle/api/tasks/ide/eclipse/expectedGroovyProjectFile.txt b/subprojects/gradle-core/src/test/resources/org/gradle/api/tasks/ide/eclipse/expectedGroovyProjectFile.txt new file mode 100644 index 000000000000..34a7d457f5ba --- /dev/null +++ b/subprojects/gradle-core/src/test/resources/org/gradle/api/tasks/ide/eclipse/expectedGroovyProjectFile.txt @@ -0,0 +1,17 @@ + + + + myProject + + + + org.eclipse.jdt.groovy.core.groovyNature + org.eclipse.jdt.core.javanature + + + + org.eclipse.jdt.core.javabuilder + + + + diff --git a/subprojects/gradle-plugins/src/main/groovy/org/gradle/api/plugins/EclipsePlugin.java b/subprojects/gradle-plugins/src/main/groovy/org/gradle/api/plugins/EclipsePlugin.java index 6c092508742b..6b9f99016d05 100644 --- a/subprojects/gradle-plugins/src/main/groovy/org/gradle/api/plugins/EclipsePlugin.java +++ b/subprojects/gradle-plugins/src/main/groovy/org/gradle/api/plugins/EclipsePlugin.java @@ -24,11 +24,13 @@ import org.gradle.api.artifacts.ProjectDependency; import org.gradle.api.artifacts.specs.DependencySpecs; import org.gradle.api.artifacts.specs.Type; +import org.gradle.api.internal.DynamicObjectAware; import org.gradle.api.internal.IConventionAware; import org.gradle.api.specs.Spec; import org.gradle.api.specs.Specs; import org.gradle.api.tasks.ConventionValue; import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.GroovySourceSet; import org.gradle.api.tasks.bundling.War; import org.gradle.api.tasks.ide.eclipse.*; import org.gradle.util.GUtil; @@ -39,6 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; /** *

A {@link org.gradle.api.Plugin} which generates Eclipse project files for projects that use the {@link @@ -80,24 +83,30 @@ private void configureEclipseProjectAndClasspath(Project project) { private EclipseProject configureEclipseProject(Project project) { EclipseProject eclipseProject = project.getTasks().add(ECLIPSE_PROJECT_TASK_NAME, EclipseProject.class); eclipseProject.setProjectName(project.getName()); - eclipseProject.setProjectType(ProjectType.JAVA); + eclipseProject.setProjectType(selectEclipseProjectType(project)); eclipseProject.setDescription("Generates an Eclipse .project file."); return eclipseProject; } + private ProjectType selectEclipseProjectType(Project project) { + if (project.getPlugins().hasPlugin(GroovyPlugin.class)) { + return ProjectType.GROOVY; + } + + return ProjectType.JAVA; + } + private EclipseClasspath configureEclipseClasspath(final Project project) { EclipseClasspath eclipseClasspath = project.getTasks().add(ECLIPSE_CP_TASK_NAME, EclipseClasspath.class); eclipseClasspath.getConventionMapping().map(GUtil.map( "srcDirs", new ConventionValue() { public Object getValue(Convention convention, IConventionAware conventionAwareObject) { - SourceSet sourceSet = java(convention).getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); - return GUtil.addLists(sourceSet.getJava().getSrcDirs(), sourceSet.getResources().getSrcDirs()); + return allLanguageSrcDirs(convention, SourceSet.MAIN_SOURCE_SET_NAME); } }, "testSrcDirs", new ConventionValue() { public Object getValue(Convention convention, IConventionAware conventionAwareObject) { - SourceSet sourceSet = java(convention).getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME); - return GUtil.addLists(sourceSet.getJava().getSrcDirs(), sourceSet.getResources().getSrcDirs()); + return allLanguageSrcDirs(convention, SourceSet.TEST_SOURCE_SET_NAME); } }, "outputDirectory", new ConventionValue() { @@ -219,4 +228,27 @@ protected JavaPluginConvention java(Convention convention) { private WarPluginConvention war(Convention convention) { return convention.getPlugin(WarPluginConvention.class); } -} \ No newline at end of file + + private SourceSet sourceSet(Convention convention, String name) { + return java(convention).getSourceSets().getByName(name); + } + + private GroovySourceSet groovySourceSet(Convention convention, String name) { + return ((DynamicObjectAware) sourceSet(convention, name)).getConvention().findPlugin(GroovySourceSet.class); + } + + private Object allLanguageSrcDirs(Convention convention, String name) { + SourceSet sourceSet = sourceSet(convention, name); + + Set extraDirs = new TreeSet(); + GroovySourceSet groovySourceSet = groovySourceSet(convention, name); + if (groovySourceSet != null) { + extraDirs.addAll(groovySourceSet.getGroovy().getSrcDirs()); + } + + return GUtil.addLists( + sourceSet.getJava().getSrcDirs(), + sourceSet.getResources().getSrcDirs(), + extraDirs); + } +}