Also, with project.exec deprecated, is the recomme...
# community-support
m
Also, with project.exec deprecated, is the recommended approach to do
project.providers.exec { ... }.result.get()
?
m
I would make it a separate and dedicated
Exec
task. Just because I like reasonning in terms of tasks. But there might be other options
m
But how would I run a number of tasks which may be unknown at configure-time? (e.g. running an exec on each file in a ConfigurableFileCollection)
m
Make one big task that takes your
ConfigurableFileCollection
as input and uses
ProcessBuilder
to run N separate processes
And dumps its output in a big JSON file
v
Why
ProcessBuilder
?
r
you should checkout ExecOperations
m
Whatever works
Yea ExecOperations is fine too
v
If you have a separate task anyway, inject
ExecOperations
and use
exec
on it, that also is a drop-in replacement behavior- and api-wise to
project.exec
m
My point is mostly about moving the logic to execution, I find this easier to reason about
m
For more context, here's my current snippet:
Copy code
@TaskAction
fun run() {
    val bundler = bundler.get().asFile
    val minifier = minifier.get().asFile
    val doMinify = minify.get()
    val requireRoot = sourceDirectory.get().asFile.absolutePath

    for ((inFile, outFile) in inputFiles.files.zip(outputFiles.files)) {
        project.providers.exec {
            executable(bundler)
            args("bundle", inFile.absolutePath)
            args("-p", "${requireRoot}/?.lua")
            args("-p", "${requireRoot}/?/init.lua")
            args("-o", outFile.absolutePath)
        }.result.get()

        if (doMinify) {
            val minifiedStream = ByteArrayOutputStream()
            project.providers.exec {
                executable(minifier)
                args("-f")
                args(outFile.absolutePath)
                standardOutput = minifiedStream
            }.result.get()
            outFile.writeText(minifiedStream.toString())
        }
    }
}
v
Within an ad-hoc task in the build script you can also use
ExecOperations
but, it needs a bit of boilerplate or the usage of an internal function to get it. You could in that case use
provider.exec
yes, if you are aware of the laziness and that you do not see the output in the build log unless you print it out in the end.
For more context, here's my current snippet
Well, that is a proper task class, so inject
ExecOperations
and use
exec
on it đŸ™‚
Unless you want to suprress the output (stdout and stderr) of those commands you execute, then the
providers.exec
is also fine.
Besides that you must not use
project
in the task action
That is deprecated and with CC a hard error
For that way you would inject
ProviderFactory
and use
exec
on that
m
what do you mean with "inject ExecOperations"? I can't extend the interface because then I need to provide my own implementations for exec and javaexec, no?
v
inject, not implement
Copy code
@get:Inject
protected abstract val execOperations: ExecOperations
Gradle will inject it for you
m
image.png
v
Wrong
Inject
?
javax.inject.Inject
it should be
m
ah I see