The new RegularFileProperty
& DirectoryProperty
should preserve a dependency relationship from the task that they are outputs on to the tasks they are inputs on. This works fine (in most cases (the exception being the dependencyFails1
case)), but once file
or dir
is invoked on DirectoryProperty
this dependency relationship is lost.
Since DirectoryProperty
and RegularFileProperty
expose no API mechanism for a user to explicitly declare what task created them (see #6336), I'd expect that the DirectoryProperty::dir
and DirectoryProperty::file
would keep the relationship from the source task to the task consuming the property.
I would expect all of the below cases to create dependencies between out1
and the respective tasks using out1
's outputs.
/**
* Some example task that has two outputs.
*/
@Suppress("LeakingThis")
open class OutputTest : DefaultTask() {
@get:OutputFile
val outputFile: RegularFileProperty = newOutputFile()
@get:OutputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
val outputDirectory: DirectoryProperty = newOutputDirectory()
}
/**
* Some example task that has two inputs.
*/
@Suppress("LeakingThis")
open class InputTest : DefaultTask() {
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
val inputDir: DirectoryProperty = newInputDirectory()
@get:InputFile
@get:PathSensitive(PathSensitivity.RELATIVE)
val inputFile: RegularFileProperty = newInputFile()
}
val out1 =
tasks.register<OutputTest>("output1")
val dependencyWorks1 =
tasks.register<InputTest>("dependencyWorks1") {
inputFile.set(out1.map { it.outputFile }.get())
}
/*
./gradlew --dry-run dependencyWorks1
:output1 SKIPPED
:dependencyWorks1 SKIPPED
BUILD SUCCESSFUL in 0s
*/
val dependencyWorks2 =
tasks.register<InputTest>("dependencyWorks2") {
inputDir.set(out1.map { it.outputDirectory }.get())
}
/*
./gradlew --dry-run dependencyWorks2
:output1 SKIPPED
:dependencyWorks2 SKIPPED
*/
val dependencyFails1 =
tasks.register<InputTest>("dependencyFails1") {
// Notice the subtle shift in where the `get` is here.
inputDir.set(out1.map { it.outputDirectory.get() })
}
/*
./gradlew --dry-run dependencyFails1
:dependencyFails1 SKIPPED
BUILD SUCCESSFUL in 0s
*/
val dependencyFails2 =
tasks.register<InputTest>("dependencyFails2") {
// Calling `file` on a `DirectoryProperty` does not retain the dependency
inputFile.set(
out1
.map { it.outputDirectory.file("someFile.txt") }
.get()
)
}
/*
./gradlew --dry-run dependencyFails2
:dependencyFails2 SKIPPED
BUILD SUCCESSFUL in 0s
*/
val dependencyFails3 =
tasks.register<InputTest>("dependencyFails3") {
inputDir.set(
out1
.map { it.outputDirectory.dir("/someDir") }
.get()
)
}
/*
./gradlew --dry-run dependencyFails3
:dependencyFails3 SKIPPED
BUILD SUCCESSFUL in 0s
*/
/* Helper method for Gradle 4.9. Won't be needed in 4.10 */
inline fun <reified T : Task> TaskContainer.register(name: String, noinline configure: T.() -> Unit = {}) =
register(name, T::class.java, configure)
In my opinion, all of the above dependency*
tasks should have a dependency upon the output1
task but many do not.
Gradle 4.9
------------------------------------------------------------
Build time: 2018-07-16 08:14:03 UTC
Revision: efcf8c1cf533b03c70f394f270f46a174c738efc
Kotlin DSL: 0.18.4
Kotlin: 1.2.41
Groovy: 2.4.12
Ant: Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM: 1.8.0_92 (Oracle Corporation 25.92-b14)
OS: Mac OS X 10.13.5 x86_64
This is probably my biggest gripe so far with the Provider
/Property
types. I reported some of the inconsistencies in https://github.com/gradle/gradle/issues/3811 and this issue has some more good examples. It also looks sort of similar to https://github.com/gradle/gradle/issues/5706 with the different map
calls.
@mkobit These problems make this API really hard to utilize in the way that I think the architect intended it to be used.
In #6336 I offered the suggestion of just adding the ability to specify a builtBy
explicitly on these types but I think that the team wants to hide that implementation detail.
Thanks for the feedback, this is very useful. We'll try to get these edge cases fixed soon.
Most helpful comment
Thanks for the feedback, this is very useful. We'll try to get these edge cases fixed soon.