I would like to write a plugin that adds tasks to some subprojects, where the targets are configured as properties. I would like to configure them as follows:
toolSetups { // an extension I add to the projects, of type NamedDomainObjectContainer
someTool { // an element of the container
subproject = project(':some-subproject') // 'subproject' is a Property<Project>
outputFile = file('some/file/path') // Property<File>
}
someOtherTool { // another element of the container
subproject = project(':some-other:subproject')
outputFile = file('some/other/file/path')
}
}
Let’s say that outputFile
is produced by a task of type ProduceOutput
, based on an input from the subproject
(e.g. a task in it). I would like to add an instance of ProduceOutput
under the subproject itself, as it “feels” like it belongs there. I tried to do the following:
toolSetups.all {
subproject.get().tasks.register('produceOutput', ProduceOutput)
}
The problem is that when the element is added to the container, the value of the subproject
property is not yet available and Gradle will issue an error. I’m guessing that the values set by the closure are set after the ToolSetup
is added to the container, i.e. the flow is “create object”, “add to container”, “call closure”, not “create object”, “call closure”, “add to container”.
Is there any way to ensure that the values of the properties are set before the object is added to the container? I’m guessing this would involve passing the values to the properties as constructor arguments, but can this be done while keeping the proposed DSL?
I have read up on Properties and that they have a finalizeValue()
function. I’m guessing I would somehow need it to disallow changes to the subproject
property, if I’m going to be adding tasks to it. Is there any way to get notified when a value is finalized? (I searched but couldn’t really find one). This could be the moment I could add the ProduceOutput
task to the finalized subproject.