I’m working through my deprecations with 4.10 in preparation for the 5.0 upgrade. I’m struggling right now to find a replacement for a TaskInternal.execute() method.
We have our feature toggle code defined in settings.gradle inside a beforeEvaluate. Here’s the relevant bits (with comments):
/* After the initialization phase is completed and projects have been loaded, we will
* generate the files needed to toggle features at build time. To ensure this is the
* very first action executed we run the following before the projects are evaluated
* (the configuration phase). By doing this, the properties needed are loaded so we can toggle
* features during the configuration and execution phases of the gradle build.
*/
gradle.rootProject {
beforeEvaluate { project ->
File featuresConfFile = ...
File txtFile = ...
File javaFile = ...
//closure which execute perl parser to generate java file with constants needed for compile and run-time toggling
def execParserForSource = {
exec {
commandLine ...
}
}
/* generateFeaturesDef creates the necessary files for feature toggle at
* build, compile and run-time. We want this to be the first thing configured
* so we can load the properties which are used to toggle at build time for
* all subprojects.
*/
task generateFeaturesDef {
inputs.file featuresConfFile
outputs.files txtFile, javaFile
doFirst {
//exec perl parser to generate the necessary files for feature toggle
execParserForSource()
}
}
//explicitly execute generateFeaturesDef before build continues on to subprojects
project.tasks.generateFeaturesDef.execute()
}
}
I haven’t been able to come up with any other way to execute this task. Any suggestions on how I can replicate this behavior in 5.0?
why are you using a task to execute that code? Why don’t you just call execParserForSource directly? I.e.:
//closure which execute perl parser to generate java file with constants needed for compile and run-time toggling
beforeEvaluate {
def execParserForSource = {
exec {
commandLine ...
}
}
/* generateFeaturesDef creates the necessary files for feature toggle at
* build, compile and run-time. We want this to be the first thing configured
* so we can load the properties which are used to toggle at build time for
* all subprojects.
*/
execParserForSource()
}
I am also pretty sure you can wrap the code generation in a task and then have the tasks which consume this code (compilation) depend on it.
I believe the primary reason it was done with a task was to make use of the inputs to prevent the closure from being executed if the source file hadn’t changed.
Is there a way to replicate that inputs logic in a closure?
If you want to participate in up-to-date checking, I think it makes much more sense to create a task, on which all the tasks that depend on the generated files depend on.
Why do you need the generated files at configuration time?
The execParserForSource closure generates a properties file with a bunch of different flags in it that we then load into a ext variable. Then sub-projects can look for those flags to decide whether to build a given project or not. Something like this: