Creating a FileTree from settings.gradle?


(Matias Bjarland) #1

I would like to use the hierarchical pattern matching capabilities of fileTree from settings.gradle. As we don’t have access to project.fileTree there, is there another way to create a FileTree instance from settings.gradle? I tried going:

def fileOperations = gradle.services.get(org.gradle.api.internal.file.FileOperations)

, but apparently the service is not registered (yet?) at that point in time. That would also be using internal classes which is inherently evil.

Any suggestions much appreciated. For a bit of context, I need this to analyze the directory structure starting at settingsDir and build up a gradle multi-project build on the fly. The gradle projects will reflect a existing third-party project structure.

Any help much appreciated.


(Peter Niederwieser) #2

You don’t necessarily need a FileTree for this. Have a look at the following solution, which uses Groovy’s traverse() method: http://gradle.1045684.n5.nabble.com/Nested-multi-projects-and-caveats-tp4480779p4805669.html


(Matias Bjarland) #3

Thanks for the pointer Peter. That looks like it would work, but would perhaps not quite accomplish what I was looking for.

Some context: I have a plugin with a method which is called from the settings.gradle file. As we can’t apply plugins in settings.gradle (and please correct me if we can), this is currently done via a groovy with clause. The plugin method performs a recursive scan to create the gradle project structure. In the plugin method I have a number of include/exclude patterns of the type:

**/someDir/
**/some/other/dir/
**/someFile.*

which I was hoping I would be able to represent with a nice “from”, “include” DSL in settings.gradle instead. I already have a custom written java method which does the manual recursive traversing of the directory structure but as that is somewhat rigid I was hoping I could use the FileTree DSL and send in a FileTree object to my method instead. In this way I could leave some control of the directories included in my scan to the caller of my method. So the goal is to have the creation of the patterns “external” and visible to the user of my plugin and the actual traversal etc hidden in my plugin method.

It seems that it might be possible to hack and abuse your way to a FileTree by doing something similar to the following from ProjectInternalServiceRegistry:

protected DefaultFileOperations createFileOperations() {
        return new DefaultFileOperations(get(FileResolver.class), project.getTasks(), get(TemporaryFileProvider.class));
    }

where the file operations object in turn has methods for fileTree etc.

An identity file resolver is already registered with the gradle services, the TaskContainer can as far as I can tell be mocked as I don’t care about tasks at this phase of the build, and the temp file provider can probably also be solved. So it seems possible to hack it, but it would have been nice to not have to revert to dependencies to internal classes and abuse and mockery of the APIs.

Anyway, if no easy and non-breaking way of using FileTree shows up I’ll probably end up building a DSL for the traverse method.


(Adam Murdoch) #4

You can use ‘Script.fileTree()’ in any script, including ‘settings.gradle’: http://gradle.org/docs/current/dsl/index.html#N10011


(Matias Bjarland) #5

Perfect! Ecactly what I was hoping for. Thank you both.

And yeah, I’ll claim the darwin award of the day for not just trying to execute fileTree(…) in settings.gradle. I didn’t quite grok the Script interface and the role it plays.