Adam
Adam

Reputation: 10036

Adding Properties to JavaPlugin’s SourceSets, Gradle

We're trying to draft a custom Gradle plugin to work with our modeling language, Umple. We want to make it as "ergonomic" as possible and allow for specifying properties at the "sourceSet" level.

For example,

sourceSets {
  main { 
    umple {
      foo = 'bar'
    }
  }
}

umple { // defaults
  foo = 'baz'
}

We have tried adding extensions to the source sets and tried to model the approach after how the Scala and Antlr plugins work. However, we can not figure out how to add extra properties to the sourceSet closure application. Any help is appreciated.

Upvotes: 2

Views: 559

Answers (2)

lance-java
lance-java

Reputation: 28071

// TODO: take inspiration from https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/java/org/gradle/api/tasks/GroovySourceSet.java
public interface UmpleSourceSet {
    SourceDirectorySet getUmple();
    UmpleSourceSet umple(Closure configureClosure);
    UmpleSourceSet umple(Action<? super SourceDirectorySet> configureAction);
    SourceDirectorySet getAllUmple();
}

// TODO: take inspiration from https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/java/org/gradle/api/internal/tasks/DefaultGroovySourceSet.java
public class DefaultUmpleSourceSet implements UmpleSourceSet { ... }

// TODO: take inspiration from https://github.com/gradle/gradle/blob/89b1c11a160c5f597c6c1ca50f01cf57e43c8356/subprojects/plugins/src/main/java/org/gradle/api/plugins/GroovyBasePlugin.java#L88
public class UmplePlugin implements Plugin<Project> {
    private final SourceDirectorySetFactory sourceDirectorySetFactory;

    @Inject
    public UmplePlugin(SourceDirectorySetFactory sourceDirectorySetFactory) {
        this.sourceDirectorySetFactory = sourceDirectorySetFactory;
    }

    public void apply(Project project) {
        project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().all(new Action<SourceSet>() {
            public void execute(SourceSet sourceSet) {
                DefaultUmpleSourceSet umpleSourceSet = new DefaultUmpleSourceSet(((DefaultSourceSet) sourceSet).getDisplayName(), sourceDirectorySetFactory);
                new DslObject(sourceSet).getConvention().getPlugins().put("umple", umpleSourceSet);

                umpleSourceSet.getUmple().srcDir("src/" + sourceSet.getName() + "/umple");
           }
       }
   }
}

Upvotes: 3

lance-java
lance-java

Reputation: 28071

This sounds similar to GroovySourceSet. See here for the GroovySourceSet references in the gradle sources.

This looks like the interesting bit in GroovyBasePlugin.java:

private void configureSourceSetDefaults(final JavaBasePlugin javaBasePlugin) {
    project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().all(new Action<SourceSet>() {
        public void execute(SourceSet sourceSet) {
            final DefaultGroovySourceSet groovySourceSet = new DefaultGroovySourceSet(((DefaultSourceSet) sourceSet).getDisplayName(), sourceDirectorySetFactory);
            new DslObject(sourceSet).getConvention().getPlugins().put("groovy", groovySourceSet);

            groovySourceSet.getGroovy().srcDir("src/" + sourceSet.getName() + "/groovy");

* Edit *

I think the magic resides in DSLObject (eg: new DslObject(sourceSet).getConvention().getPlugins().put(...))

Provides a unified, typed, interface to an enhanced DSL object. This is intended to be used with objects that have been decorated by the class generator.

See the documentation here

The Groovy plugin adds the following convention properties to each source set in the project. You can use these properties in your build script as though they were properties of the source set object.

Upvotes: 1

Related Questions