How to Add Custom Sources to SourceSet?

I’d like to create a custom plugin that among other things compiles clojurescript, and to that end I’d like to learn how to add source directories to a SourceSet. Is it sufficient to add: project.SourceSets.main.clojurescript.srcDir = "src/main/clojurescript"? To make the make the location configurable do I need to add a plugin extension or since the new location is appended to SourceSets does it automatically become configurable via the following?

sourceSets {
    main {
        clojurescript {
            srcDirs = ['src/clojurescript']
        }
        resources {
            srcDirs = ['src/resources']
        }
    }
}

You are not adding a new sourceSet, but a new language under the sourceSet. You can do that with an extension like this:

sourceSets.all { sourceSet ->
  sourceSet.extensions.create('clojurescript', ClojureScriptSourceDirectorySet)
}

Unfortunately you’ll have to implement your own ClojureScriptSourceDirectorySet at the moment, as there is no public factory for the SourceDirectorySet type used by the Java/Groovy/Scala plugin.

Thanks for the clarification. Implementing SourceDirectorySet seems simple enough. However, moving forward would you suggest I use version 3.0 mechanisms like RuleSource as shown in this language type example?

With respect to version 3.0, I understand @ComponentType essentially identifies software components built by gradle and @BinaryTasks register tasks. But do you know the purpose of @BinarySpec and @ComponentBinary or where I can find more information about them?

No, using the software model for the Java ecosystem is discontinued. We will do a blog post explaining the details soon. But in short: We plan to bring many of the same benefits with the current model, saving people the effort of re-writing all their plugins. :slight_smile:

Thanks for the heads-up. Do you know of any examples or other sources that demonstrate current (and foreseeable future) best practices with respect to developing plugins that provide custom language support?

Gradle’s own languages like Java, Scala and Groovy. Or (shameless self-endorsement) the Xtext plugin. The latter is a bit more involved actually, because it builds a whole language ecosystem of itself and then optionally integrates with Java.

Apart from that an “Idiomatic Plugin Authoring” tutorial is high on our list of new documentation we will write in the coming months.

Thanks for the suggestions. I’ve taken a look at the Groovy and Xtext plugins. While those were generally informative, there are certain aspects that remain unclear, like SourceDirectorySetFactory since information regarding it is unavailable in the plugins and the Gradle Javadoc.

In light of the above, I believe an idiomatic plugin authoring tutorial would be very helpful. I assume once it’s complete you’ll announce it’s availability; I look forward to it.

SourceDirectorySetFactory is an internal API, that’s why I suggested to implement your own ClojureScriptSourceDirectorySet and go with the extension approach I suggested.

I misunderstood your suggestion, I thought you were recommending I implement the SourceDirectorySet as demonstrated in the Groovy Plugin – hence the use of SourceDirectorySetFactory. Further, to confirm, as you mentioned in another post, I don’t have to implement the SourceDirectorySet in its entirety. Rather, I can define and implement an interface that includes only the APIs I am interested in, correct?

Absolutely, that’s what I did in the Xtext plugin too.