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.
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.
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 or 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.
No, it depends on what you need and where.
If you want a lazily evaluated command as a Provider, providers.exec might be the way to go.
If you for example used it in the execution logic of a task, usually ExecOperations#exec is more appropriate for example, or even a task of type Exec.
And btw. just replacing exec by providers.exec will most of the time not work, because the latter is lazy. So unless something somewhere is getting the result of the operation, the operation is never done.
As Björn points out, Provider is lazy, so you have to call get(). For example, here is one step in a series of commands that’s been working fine. Note the .result.get() at the end:
I tried replacing this with execOperations.exec upon Björn’s suggestion and got the following error, so I’m going to stick with my providers.exec {}.result.get() solution.
> Could not get unknown property 'execOperations' for task ':buildHdf5' of type org.gradle.api.DefaultTask.
… no, definitely not
Maybe in the cases you encountered
I tried replacing this with execOperations.exec upon Björn’s suggestion
That is not what I suggested.
I did not say execOperations.exec, but ExecOperations#exec, which is the common notion for calling exec on an instance of ExecOperations.
In a build script you don’t have one readily available, so to use it you need to do it like the faff around gradle 9 getting rid of `exec ` is really an Gradle Community #community-support. So if you don’t need specifics of the ExecOperations variant, in build scripts using the provider one is often more easy as long as you consider the laziness. But often it is more appropriate to use a task of type Exec instead, or to move the logic into a proper task class where you can inject ExecOperations.
I had a typo but still, it was ExecOperations.exec, not execOperations.exec()
But it should have been ExecOperations#exec.
Either way, I did not provide a copy&paste solution, I’m not your coding bot, I gave information that you need to transfer and transform into working code.
but neither ExecOperations#exec nor execOperations#exec work either
Of course not.
As I already explained in my last comment, that syntax is not a copy&pasteable code but means “call exec on an instance of ExecOperations”.
And I also in my last comment explained and linked further how you would do so.
Please try to fully read and understand before just pasting assumed snippets around, ignoring the text around it that explains it, and then wondering that it does not work.