Stefano Zanella
08/23/2024, 8:22 AMSync task within a custom plugin to copy files into an intermediate folder for assembling a package's content. I want to be able to configure this directory, as in another task/subproject I need to first generate the content of this directory and in other subprojects I can just use a default. The problem I'm facing is that Gradle detects a non-declared dependency between the output of the preparation task and the input of the Sync task. I don't want to directly depend on the task as it's an internal task to the plugin. Is there a way to specify the source of a Sync task as an input property? Some example code to better explain:
// subprojectA (build.gradle.kts)
val pkgSources = layout.buildDirectory.dir("generated/pkgSource")
myPlugin {
sourceDir = pkgSources
}
tasks.register("foo", Sync::class.java) {
from("someFolder")
into(pkgSources)
}
// custom plugin
// has extension with sourceDir DirectoryProperty
tasks.register("prepare", Copy::class.java) {
from(ext.sourceDir) // points to pkgSources
into("somewhere/else")
}
tasks.register("buildPackage") {
dependsOn("prepare")
}
If I call buildPackage I get the non-explicit dependency error, and I assume it's because the call to from() doesn't set an actual input for the Copy task? Or am I missing something?Adam
08/23/2024, 8:57 AMmyPlugin, and then your plugin will do some processing on them?
It makes sense that you want to hide the internal prepare task.Stefano Zanella
08/23/2024, 8:59 AMAdam
08/23/2024, 8:59 AMmyPlugin extension? Then buildscripts can pass in the files, and then internally the prepare sync task can do it's thing.Stefano Zanella
08/23/2024, 8:59 AMDirectoryProperty?Vampire
08/23/2024, 9:00 AMfrom() doesn't set an actual input for the Copy task?". If that were the case it would bad and you wouldn't get the error.
The problem is, that your pkgSources Provider does not carry an implicit task dependency to the foo task.Adam
08/23/2024, 9:01 AM// my-plugin
abstract class MyPluginExtension {
abstract val inputFiles: ConfigurableFileCollection
}
// build.gradle.kts
val fooTask by tasks.registering(Sync::class) {
from("someFolder")
into(temporaryDir)
}
myPlugin {
inputFiles.from(fooTask)
}Vampire
08/23/2024, 9:01 AMsourceDir to the destinationDirectory of foo it probably works as intendedStefano Zanella
08/23/2024, 9:01 AMStefano Zanella
08/23/2024, 9:02 AMAdam
08/23/2024, 9:02 AMStefano Zanella
08/23/2024, 9:05 AMFileCollection provides different semantics in that regardAdam
08/23/2024, 9:07 AMAdam
08/23/2024, 9:08 AMStefano Zanella
08/23/2024, 9:09 AMStefano Zanella
08/23/2024, 9:09 AMAdam
08/23/2024, 9:13 AMprocess task (like your plugin's task) uses the ConfigurableFileCollection.
Even though process doesn't have explicit dependencies on the producer tasks, Gradle will be able to figure it out correctly.
// build.gradle.kts
val producerTask1 by tasks.registering(Sync::class) {
from("sources1")
into("result/producer1")
}
val producerTask2 by tasks.registering(Sync::class) {
from("sources2")
into("result/producer2")
}
val producerTask3 by tasks.registering(Sync::class) {
from("sources3")
into("result/producer3")
}
val allProducedFiles = objects.fileCollection()
.from(producerTask1)
.from(producerTask2)
.from(producerTask3)
val process by tasks.registering(Sync::class) {
from(allProducedFiles)
into("result/aggregated")
}Adam
08/23/2024, 9:13 AMVampire
08/23/2024, 9:16 AMactually I have 3 tasks running and putting files into the destination directoryThis also sounds suspicious. Hopefully all three tasks have no overlapping outputs. That means they have the concrete files as outputs, not the output directory. If all three tasks have the same directory as output directory, this is highly problematic and discouraged. The solution for that would exactly be what Adam just showed.
Stefano Zanella
08/23/2024, 9:58 AM