is there any way to make this Gradle task cacheabl...
# community-support
k
is there any way to make this Gradle task cacheable?
Copy code
tasks.register("updateModuleCapabilitiesIndex") {
    val watchFiles = fileTree(project.rootDir) {
        include("**/build.gradle", "**/build.gradle.kts")
    }.files
    val moduleIndexFile = "${layout.buildDirectory.get()}/moduleCapabilities.json"
    val moduleIndexCmdLine = listOf(
        "./gradlew",
        "...",
    )
    inputs.files(watchFiles)
    doLast {
        providers.exec {
            commandLine = moduleIndexCmdLine
        }
    }
    dependsOn("build")
}
Command removed for simplification, but I'm trying to write something that parses the gradle files and then saves the info into another file in a cacheable way. The doLast{...} bit unfortunately contains a gradle script which is not serializable... Tried to search in this slack but configuration cache gets a lot of unrelated hits 😂
m
What if you put
providers
in a local variable that can be captured by the lambda maybe? Is this what pulls the Gradle script?
k
I think it's the entire providers.exec call. I can comment that out and it works (for the config cache...doesn't generate a file)
m
Copy code
tasks.register("hello") {
  val providers = project.providers
  doLast {
    providers.exec {
      commandLine = listOf("echo", "hello world")
    }
  }
}
This works for me
v
Besides that you usually should use the tooling API to drive another build, not
exec
. :-)
k
Pulling project.providers out of the doLast{} still didn't work for me..cryptic cache report is the same 🤔 Hmm...tooling API would help me avoid the exec...
👀 1
e
or a task class instead of ad-hoc can have
ExecOperations
injected,
Copy code
abstract class UpdateModuleCapabilitiesIndex : DefaultTask() {
    @get:Inject
    abstract val execOperations: ExecOperations

    @TaskAction
    fun exec() {
        execOperations.exec { ... }
    }
}

val updateModuleCapabilitiesIndex by tasks.registering(UpdateModuleCapabilitiesIndex::class)
1
👍 1
still, using Gradle from inside Gradle is kind of questionable
k
it's running a task in a separate tooling project...kinda weird I agree
m
+1 for the custom class. For anything non trivial it's usually easier to debug so the initial "investment" is quickly paid for
👍 1
k
custom task worked 🎉 thank you
🎉 1
👌 1
m
Note that you need to obtain the value of the provider returned by
providers.exec
for the external process to run, this thing is lazy. Also, its intended use is to capture the standard output of the process. ExecOperations is a better choice in the described use case.
👍 2
b
can you give an example? how do we replace
exec
?
v
As I already answered on the forums. Depending on use-case usually either with
providers.exec
or
ExecOperations#exec
or a task of type
Exec
.
☝️ 1