Gradle 8.11.1 change project.exec to?

I get this information that I should move project.exec to
Use ExecOperations.exec(Action) or ProviderFactory.exec(Action) instead.

I can’t figure out how either of them. This is the code currently used:

ext.getCurrentBranchName = {
    new ByteArrayOutputStream().withStream { os ->
        exec {
            executable = 'git'
            args = ['symbolic-ref', '--short', 'HEAD']
            standardOutput = os
        }
        return os.toString()
    }
}

ext.branch = getCurrentBranchName()

How is that converted to ExecOperations.exec?
I can’t even figure out where to find an implementation of the interface.

If it is in a build script at configuration time, using project.exec should be ok as long as you do not want to use configuration cache.

Using ext / extra properties though is most often a bad idea anyway. Typically their usage is a sign that you do something not the proper way but as a work-around.

Having said this, you can also simply do not use git executable at all and for example use JGit instead, either directly or through something like grgit.

And a more personal recommendation, you should consider 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.

And finally to answer the actually asked question anyway, to use ExecOperations from a proper task class you would inject it, from a Groovy DSL build script you would need something like

interface ExecOperationsProvider {
   @javax.inject.Inject
   ExecOperations getExecOperations()
}
objects.newInstance(ExecOperationsProvider).execOperations.exec { commandLine('echo foo') }

ProviderFactory is available at providers, so something like

providers.exec { commandLine('echo bar') }.standardOutput.asText

Proper task class? I do not know what that is.

Using the println providers.exec { commandLine('echo bar') }.standardOutput.asText does not give the expected result.

map(map(valueof(ProcessOutputValueSource)))

Should I file a bug for it?

I found that it command line expects an array. Changing to that and an last .get() made it work.

I see why you recommend kotlin. It is now totally hopeless to write the build script in an editor of choice. It must be written in an IDE with support for this provider/type mania that has happened to gradle.

Proper task class? I do not know what that is.

If you have a plugin class or a task class or an extensions class or similar, in a .java file or a .groovy file or a .kt file or whatever, you can let Gradle inject ExecOperations into it.

Using the println providers.exec { commandLine(‘echo bar’) }.standardOutput.asText does not give the expected result.

Yes it does, the output you got is exactly what is expected when you print a Provider<String>?

Should I file a bug for it?

To yourself? Sure.
Or you .get() the provider’s value if you really need the value at configuration time.
Did I mention that with Kotlin DSL this is a ton easier as you have much better IDE support and type-safe build scripts?

I found that it command line expects an array.

You can also use executable and args as you did previously.
commandLine is just both together.

It is now totally hopeless to write the build script in an editor of choice. It must be written in an IDE

Not really, I also edit build scripts with vim and occasionally code in vim, but using a proper IDE you simply have more help and convenience and safe much time, especially for things the IDE could immediately show you and a forum needs some time to get an answer and is not nice to be asked for something the IDE would have known right away.
If you know what you are doing, you can use any text editor just like before. And just like before, if you do not know what you do you run against brick walls with your head occasionally, whether there are providers involved or not.

with support for this provider/type mania that has happened to gradle.

It is not a mania, it is a great improvement for much easier configuring builds properly and having much more reliable and correct builds.