How to create a custom SourceSetContainer for a plugin


(Tim Harsch) #1

OK, I’m still pretty new at Gradle, Groovy, so bear with me. I contribute on a plugin (gradle-license-plugin) that applies licenses to files in the project. It does this by scanning project.sourceSets (which means it depends on the java plugin). I would like to change this behavior so that I can specify a custom source set (which perhaps starts with the sourceSets from java plugin or Groovy or whatever). But the main thing I want to do is to be able to apply “include/exclude” filters to the source set. So, in general what would be a good approach to this.

Here is what I’ve done so far: created a licenseFiles method that takes a closure.

def licenseFiles(Closure closure) {

licenseFiles.configure(closure)

}

The licenseFiles SourceSetContainer is instantiated similar to the way the Java plugin does it. Later in the plugin I attempt to use the licenseFiles convention property and it is empty (even though I know configure was called with a closure that is Java plugin compatible). So I think what is missing here is the step of scanning the file system and somehow applying the excludes / includes to the operation. I was blindly hoping that configure would do that for me. As I read more and more of the Java plugin code I don’t really see how that is accomplished.

And then if I go back to my original problem, I don’t think I want this plugin applicable to only Java projects so I need to come up with a file set configuration and scanner that is agnostic of the project type.

Any help appreciated.


(Peter Niederwieser) #2

Could you explain the bigger picture of what you are trying to achieve? Are you trying to give people a way to say which files should have a license header added?

The concept of source sets is introduced by the java-base plugin, which forms the basis for all JVM language support (Java, Groovy, Scala, etc.). Hence relying on source sets should be fine. What you probably want is to add a ‘licenses’ ‘extension’, either to the Project object:

apply plugin: "licenses"
  licenses {
  include ...
  exclude ...
}

Or to the Source(Directory)Set objects:

apply plugin: "licenses"
  sourceSets {
  main {
    java {
      licenses {
        include ...
        exclude ...
    }
  }
}

(Tim Harsch) #3

Hi Peter, Thanks for the quick reply. Yes, I want one (or more) SourceSets to apply license headers to (or remove them from, or warn if missing, depending on the task called). Perhaps I need more than one for each license header (one for BSD, Apache, Company original header, etc.).

So the snippets you show above are pretty much exactly right. So, let’s assume for the moment that sourceSets is a good basis starting point for the moment. Now, how can I make a copy of a sourceSet and apply further include/exclude rules than were originally applied?


(Peter Niederwieser) #4

You don’t need to make a copy of the source set. What you probably want is to add an extension object to the source (directory) set which has its own include/exclude rules. To get started, study the chapter Writing Custom Plugins in the user guide. Another valuable source of information is the Gradle source code, for example the code-quality plugins.