How to replace deprecated Project.exec(Closure)

I have a task that is similar to the following example. The idea is that the testVersion task is UP-TO-DATE as long as the gitVersion property doesn’t change. In this example, the property is set to the contents of the file foo. In our application it is set to the output of the command git rev-parse HEAD.

The problem is that my use of exec(Closure) is deprecated in Gradle 8 and is incompatible with Gradle 9. I have been unable to come up with a replacement and hope you can provide some guidance.

Here is my build.gradle:

def gitVersion = new ByteArrayOutputStream()
exec {
    commandLine "cat", "foo"
    standardOutput = gitVersion
}
gitVersion = gitVersion.toString().trim()

task testVersion(type: Exec) {
    inputs.property "pipelineVersion", gitVersion
    outputs.file "$buildDir/build.properties"

    commandLine "touch", "$buildDir/build.properties"
}

Here is the expected behavior. testVersion is UP-TO-DATE if foo doesn’t change and there aren’t any deprecation warnings.

$ echo foo > foo
$ gradle testVersion --console plain
> Task :testVersion
$ gradle testVersion --console plain
> Task :testVersion UP-TO-DATE

$ echo bar >| foo
$ gradle testVersion --console plain
> Task :testVersion
$ gradle testVersion --console plain
> Task :testVersion UP-TO-DATE

I think what you need here is providers.exec. Or maybe to be configuration cache compatible a ValueSource with injected ExecOperations.

Thanks, Björn! That’s what the deprecation message suggests. Unfortunately, I was not able to come up with a working example. Would you be willing to try? Thanks!

What did you try and in which way did it not work?
Can you show an MCVE of what you tried?

Btw. I strongly recommend switching to Kotlin DSL. By now it is the default DSL, you immediately get type-safe build scripts, actually helpful error messages if you mess up the syntax, and amazingly better IDE support if you use a good IDE like IntelliJ IDEA or Android Studio. :slight_smile:

Oy, I spent over half a day trying a ton of things and don’t have any examples. They either didn’t compile or the testVersion task was UP-TO-DATE when it shouldn’t have been or wasn’t UP-TO-DATE when it should have been. It’s unlikely my pathetic examples would have been of any use.

I did add a MCVE of what I have.

Agreed about Kotlin, but it’s unlikely we’ll be able to prioritize a conversion over all the other mission critical work.

I’m sorry, but I’m not going to write your code for you, unless you hire me.
I gave you helpful information, now try to figure it out.
If you have problems, you can show what you tried and what problems you have and I might provide some further help.
I’m not some paid supporter some something, I’m just a user like you, helping other users.

Fortunately, I finally found an example that contained the missing pieces. After copying the following into build.gradle, the recipe above works as desired without deprecation warnings.

def gitVersionProvider = providers.exec {
    commandLine "cat", "foo"
}

task testVersion(type: Exec) {
    inputs.property "pipelineVersion", gitVersionProvider.standardOutput.asText.get().trim()
    outputs.file "$buildDir/build.properties"

    commandLine "touch", "$buildDir/build.properties"
}