Reputation: 10036
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
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
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