How do I add directories to the main resources SourceSet in a gradle plugin?

I’m writing a custom Gradle plugin and would like to add a folder to the Main SourceSets resources so that it’s contents can be included in the Jar output. At the moment I’ve got this (which does not seem to be working):

@TaskAction
public void action() {
    Project proj = getProject();
      // ... snip
      File output = new File("build/data/metadata.properties");
    if (proj.getPlugins().hasPlugin(JavaPlugin.class)) {
        // add output file to resources source directory
        SourceSetContainer cont = (SourceSetContainer) proj.getProperties()
                .get("sourceSets");
        cont.getByName("main").getResources().getSrcDirs()
                .add(output.getParentFile());
    }
}

Use the srcDir or srcDirs method.

Your check for the presence of the Java plugin won’t work if the Java plugin is applied after your plugin. The correct way is to use a callback: proj.getPlugins().withType(JavaPlugin.class, new Action() {…}).

Thank you for the reply Peter.

I re-factored the logic involved with the JavaPlugin as follows:

public class CustomPlugin implements Plugin<Project> {
    public void apply(final Project project) {
        final CustomTask task = project.getTasks().add(CUSTOM_TASK_NAME, CustomTask.class);
          project.getPlugins().withType(JavaPlugin.class, new Action<JavaPlugin>() {
            @Override
            public void execute(final JavaPlugin plugin) {
                SourceSetContainer sourceSets = (SourceSetContainer)
                        project.getProperties().get("sourceSets");
                sourceSets.getByName("main").getResources().getSrcDirs()
                        .add(task.getOutput().getParentFile());
                  Copy resourcesTask = (Copy) tasks
                        .getByName(JavaPlugin.PROCESS_RESOURCES_TASK_NAME);
                resourcesTask.dependsOn(task);
            }
    }
}

The plugin configuration is definitely being called and the callback is being fired because my plugin’s task is being executed before the processResources task from the JavaPlugin. It’s just that my task’s output isn’t being added to the web archive.

My task looks like this:

class CustomTask extends DefaultTask {
    // ... snip
    @OutputFile
    private final File output = new File("build/data/metadata.properties");
    // ... snip

I think the problem is with these lines:

SourceSetContainer sourceSets = (SourceSetContainer)
         project.getProperties().get("sourceSets");
sourceSets.getByName("main").getResources().getSrcDirs()
        .add(task.getOutput().getParentFile());

As I said, use the srcDir or srcDirs method instead of getSrcDirs().add.

Perfect, thanks Peter.

I missed the subtle distinction in your advice, for anyone that follows and sees this thread:

SourceSetContainer sourceSets = (SourceSetContainer)
        project.getProperties().get("sourceSets");
sourceSets.getByName("main").getResources()
        .srcDir(task.getOutput().getParentFile());