Kanstantsin Shautsou
07/14/2024, 3:33 PMThomas Broyer
07/14/2024, 4:18 PMList<CommandLineArgumentProvider> property to which you can add an object with properly-annotated properties, and Gradle will soon start to fail if the task is reconfigured at execution time.
This could be (have been?) useful too to declare implicit task dependencies when wiring an output property to an input property, when the input property isn't a lazy Property, so similarly you'd declare the provider in task.inputs, and then get the provider value to configure the input property at execution time (this also works for wiring an extension property to a task input property). Nowadays, lazy properties and `CommandLineArgumentProvider`s makes this almost useless (but there are still cases where it's needed unfortunately)
In other words, task.inputs allows declaring dynamic additional "properties" to a task.Thomas Broyer
07/14/2024, 4:29 PMtasks.named<TheTaskType>("theTask") {
inputs.file(theFile).withPropertyName("the.property").withPathSensitivity(NONE).normalizeLineEndings()
doFirst {
systemProperty("the.property", theFile.absolutePath)
}
}
Nowadays you could do:
tasks.named<TheTaskType>("theTask") {
forkOptions.jvmArgumentProviders.add(object : CommandLineArgumentProvider, Named {
@Internal override fun getName() = "the.property"
@InputFile @PathSensitive(NONE) @NormalizeLineEndings val file = theFile
override fun asArguments() = listOf("-Dthe.property=${this.file.absolutePath}")
})
}Vampire
07/14/2024, 6:41 PMinputs....
But if you write an ad-hoc task in the build script, you use inputs... to define the inputs of the task.
In both cases, you can use inputs... to for example get the summary of input files for a task when you need them and not per input property for whatever reason.
As a quick example, this is what I gave someone else a few minutes ago:
val foo by tasks.registering {
val output = layout.buildDirectory.file("foo.txt")
outputs.file(output).withPropertyName("output")
doLast {
output.get().asFile.writeText("bar")
}
}
val signFoo by tasks.registering {
inputs.files(foo).withPropertyName("input")
outputs.file(
foo.map {
val fooOutput = it.outputs.files.singleFile
fooOutput.resolveSibling("${fooOutput.name}.asc")
}
).withPropertyName("output")
doLast {
signing.sign(*inputs.files.files.toTypedArray())
}
}Thomas Broyer
07/14/2024, 10:08 PMKanstantsin Shautsou
07/14/2024, 10:27 PMVampire
07/15/2024, 1:59 AMadhoc tasks are rather rareNot really. In fully idiomatic builds maybe where any imperative logic is moved to proper custom task classes and plugins, yes. But in reality out there, the need is quite often there. And sometimes you even need to use
inputs... to add inputs that are not considered by task implementations.
For example if you expand stuff in a Sync task like processResources, the values are not automatically inputs but have to be declared additionally.
just personal opinion though)I fully agree. Unfortunately, reality often is different from what we wished everyone does.
I thought code requires task name and task type as must haveNot sure what you mean. If you mean my code, both is present. First task has type
DefaultTask and name foo, second task has type DefaultTask and name signFoo.