To achieve this functionality, it is necessary to expand existing sets of sources (or at least main and test source sets). It looks like the main and test source sets are defined in JavaPlugin . Extension is possible through the Convention object.
public class FooPlugin implements Plugin<ProjectInternal> { @Override public void apply(ProjectInternal project) { project.getPluginManager().apply(JavaPlugin.class); FooExtension ext = project.getExtensions().create( "foo", FooExtension.class, project, project.getFileResolver() ); SourceSetContainer cont = (SourceSetContainer) project.getProperties().get("sourceSets"); cont.all((SourceSet ss) -> { String name = ss.getName(); File sources = project.file("src/" + name + "/foo"); FooSourceSet fss = ext.getSourceSetsContainer().maybeCreate(name); SourceDirectorySet sds = fss.getFoo(); sds.srcDir(sources); Convention sourceSetConvention = (Convention) InvokerHelper.getProperty(ss, "convention"); sourceSetConvention.getPlugins().put("foo", fss); }); project.task("compileFoo"); } } public class FooExtension { private final NamedDomainObjectContainer<FooSourceSet> sourceSetsContainer; public FooExtension(Project project, FileResolver fileResolver) { sourceSetsContainer = project.container( FooSourceSet.class, new FooSourceSetFactory(fileResolver) ); } public NamedDomainObjectContainer<FooSourceSet> getSourceSetsContainer() { return sourceSetsContainer; } public void srcDir(String file) { sourceSetsContainer.getByName("main").getFoo().srcDir(file); } } public class FooSourceSetFactory implements NamedDomainObjectFactory<FooSourceSet> { private final FileResolver fileResolver; public FooSourceSetFactory(FileResolver fileResolver) { this.fileResolver = fileResolver; } @Override public FooSourceSet create(String name) { return new DefaultFooSourceSet(name, fileResolver); } } public interface FooSourceSet { public String getName(); public SourceDirectorySet getFoo(); public FooSourceSet foo(Closure clsr); } public class DefaultFooSourceSet implements FooSourceSet { final String name; final SourceDirectorySet foo; public DefaultFooSourceSet(String displayName, FileResolver fileResolver) { this.name = displayName; DefaultDirectoryFileTreeFactory ddftf = new DefaultDirectoryFileTreeFactory(); foo = new DefaultSourceDirectorySet(name, fileResolver, ddftf); } @Override public String getName() { return name; } @Override public SourceDirectorySet getFoo() { return foo; } @Override public FooSourceSet foo(Closure clsr) { ConfigureUtil.configure(clsr, foo); return this; } } public class CompileFooTask extends DefaultTask { @TaskAction public void compileFoo() { SourceSetContainer cont = (SourceSetContainer) getProject().getProperties().get("sourceSets"); cont.all((SourceSet ss) -> { FooSourceSet fss = getProject() .getExtensions() .getByType(FooExtension.class) .getSourceSetsContainer() .maybeCreate(ss.getName()); System.out.println("directories under " + ss.getName() + ": " + fss.getFoo().getSrcDirs()); }); } }
The compileFoo task shows that the plugin really works. Given the script build fragment from the question, it prints lines like these:
directories under main: [<root>/src/main/foo, <root>/build/generated-sources/gen-foo] directories under test: [<root>/src/test/foo, <root>/build/generated-sources/gen-test-foo]
Sergey Fedorov
source share