I am developing a plugin allowing users to configure a random seed to obtain reproducible build artifacts. Like this:
myPlugin {
seed = 123
}
However, sometimes users may not want to hardcode the random seed. For example, they may want to use the commit count:
myPlugin {
seed = getCommitCount()
}
So far, we can set a ValueSource
to obtain the commit count. But then, each time users commit, the configuration cache misses. However, the random seed only affect the execution phase. Thus I want to make the seed a “execution-phase-only” provider and write my plugin like:
myPlugin {
seedProvider = { getCommitCount() }
}
class MyTask: DefaultTask() {
init {
outputs.upToDateWhen { !hasSeedChanged(seedProvider) }
}
@TaskAction
fun run() { doTheJob(seedProvider) }
}
My current workaround works more like the following:
open class myPluginExtension {
var seedProvider: () -> Int = { 0 }
}
open class MyTask: DefaultTask() {
@get:Input
val executionSeed: Property<Int>
@Internal
var seedProvider: (() -> Int)?
@TaskAction
fun run() { doTheJob(seedProvider.get()) }
init {
outputs.upToDateWhen { seedProvider?.invoke() == executionSeed.get() }
}
}
open class MyPlugin: Plugin<Project>{
fun apply(project: Project) {
val ext = project.extensions.create("myPlugin", myPluginExtension::class.java)
project.tasks.register("myTask", MyTask::class.java) {
it.seed.set(ext.seedProvider())
it.seedProvider = ext.seedProvider
}
}
}
But it’s kind of tricky. I would like to ask if there’re better solutions?