Need to define @Input property that is either the classpath entries of a configuration, or nothing, depending on another property

I’m working on a Gradle plugin that has a task that generates compilable Java source code. It takes as input for the code generator a “static” directory (property value) which should contain files in a special language (using a specific extent). In addition, if a particular configuration property is set to true, it will also search for files with the same extent in a particular configuration.

I want to make sure that the task runs if any of its input dependencies are new.

It’s easy enough to add @InputDirectory to the property definition for the “static” location, but I’m unsure how to handle the “dynamic” input dependency.

I have a property that defines the name of the configuration that would be used to search for additional files with that extent. We’ll call that “searchConfiguration”. This property is optional. If it’s not set, it will use “compile”. I also have the property that specifies whether we will search for additional files in the first place. We’ll call that “inspectDependencies”.

I think I could write a @Input-annotated method that returns essentially the “configurations.searchConfiguration.files” list. We’ll call that “getDependencies”. I think that is the basic idea. However, I don’t understand what to do about “inspectDependencies”. I could easily make “getDependencies” return an empty list if “inspectDependencies” is false, but is that truly the correct thing to do? It seems likely that if someone changed “inspectDependencies” from “true” to “false” after a build, the next build should run the task again.

Rather than have the toggle property, why not just have a single property which is the “classpath” configuration and annotate it with ‘@InputFiles’. You can make it optional and if the user doesn’t specify it you can default to ‘configurations.compile’.

myTask {

classpath = configurations.foo

}

That wouldn’t have the same semantics. The intention is, if “inspectDependencies” is false, it will not search ANY configuration.

You could then certainly add that property and provide a getter for the classpath property that returned an empty collection if that property is true. The user could also just as well set it to an empty collection themselves.

myTask {

classpath = []

}

Ok, then I guess it would look like this:

@Input
 def getOptionalYangClasspath() {
  if (inspectDependencies) {
   return project.configurations[yangFilesConfiguration].files
  }
  else {
   return Collections.emptyList()
  }
 }

It’s becoming very clear to me that strategies to optimize the automated testing of input “up to date” checks will be very important. It’s great that Gradle skips tasks that don’t need to run, but the bad news is that custom plugins have to make absolutely sure that they didn’t actually have to run.

Except that you’ll want to use the ‘@InputFiles’ annotation. Also, you can simply return the configuration itself (rather than ‘.files’) since a ‘Configuration’ implements ‘FileCollection’.

Also, custom tasks will need their own test suites to ensure incremental build support works as intended. You would likely want to create your own integration tests to ensure this is the case.