Custom gradle task that accepts a file or directory

I have a custom gradle task with one input that can accept a file or a directory. I have logic in there that checks the File object to see if it’s a file or directory, and does different processing depending on the answer.

I have issues with using Task Inputs for this. If I define it as @InputFile, and the File object passed is a directory, then the task is always up-to-date. If I define it as an @InputDirectory, and the File object passed is a file, it errors.

This is the error I get when I pass a File object that is a literal file (not a directory) to a Task Input defined as @InputDirectory:

* What went wrong:
A problem was found with the configuration of task ':customTask'.
> File '/path/to/file' specified for property 'theFile' is not a file.

Is this simply not supported? If not… I suppose I could define two optional task inputs… one that’s a file and one that’s a directory. But the two arguments are mutually-exclusive, and that just feels wrong.

The way I typically approach this is to not annotate the File property, but create a getter method that returns a file collection and annotate that method with @InputFiles. That getter can then determine what should be in the collection depending on whether the property is a file or a directory.

1 Like

EDIT: Thanks for answering Gary.

I wrote one getter approach… but just writing two getters: one that had @InputFile and one that had @InputDirectory. Each of the two was optional, and returned “null” if it wasn’t applicable. This works pretty well, but has more code than it should.

I’m not familiar with the @InputFiles annotation, and the documentation is next to nothing on this. Am I simply writing the setter so that it returns a file collection? Wouldn’t a file, a directory, a fileTree all work with this? This is excellent!

Would @OutputFiles work in the same way? For some reason, I thought @OutputFiles took an Iterable.