What is the best way to execute some code against the elements in a NamedDomainObjectContainer after they have been completely configured? Using #all(), my code is executed before the elements are configured, and I haven’t found another method that behaves differently.
Here are more details in case the answer is problem-specific:
I am writing a custom plugin to implement the logic for taking some artifacts from a repository and shuffling their contents around. Specifically, the source artifacts are tar archives, and the output is a rearranged version of the archives, with some extra signatures and metadata files. I wanted to encapsulate all the fiddly bits into a plugin and extend Gradle’s DSL to give the build writers a fluent way to express the source artifacts that should be included and required metadata about them.
Here is the style I’d like to see in the build:
thingsToSign {
thingOne {
artifact group: 'foo', name: 'thing-one', version: '7.+'
metadata 'bar'
}
thingTwo {
artifact group: 'foo', name: 'thing-two', version: '4.+'
metadata 'baz'
}
}
To support this declaration, in my plugin I used the Project#container() method to create a NamedDomainObjectContainer for my Things, and added it as a project extension. Now, I am attempting to add dependencies upon the artifacts for thingOne and thingTwo to a configuration created by my plugin. This is how I tried to do that, but it doesn’t work, because the Thing’s artifact property is not set before my closure is called:
// In Plugin<Project>#apply()
def things = project.container(Thing)
project.extensions.thingsToSign = things
things.all { Thing thing ->
// At this point, thing.artifact is null
project.dependencies.add(THINGS_CONFIGURATION_NAME, thing.artifact)
}