Martin
05/27/2024, 1:31 PMFileCollection
predictable?Vampire
05/27/2024, 1:42 PMA file collection is can be used to define a classpathand as classpaths are ordering sensitive, I'd very much hope it is predictable / consistent. If it were not, I guess that would also be pretty bad for up-to-dateness and cacheability.
Martin
05/27/2024, 1:47 PMVampire
05/27/2024, 1:50 PMFileCollection
and don't know how it is built-up / implemented, I'd expect consistent ordering on iteration, but if you don't know how it was built / implemented, you can hardly predict the order, yes.Martin
05/27/2024, 1:51 PMMartin
05/27/2024, 2:55 PMMartin
05/27/2024, 2:55 PMMartin
05/27/2024, 2:56 PMVampire
05/27/2024, 2:58 PMMartin
05/27/2024, 3:01 PMVampire
05/27/2024, 3:03 PM@Classpath
or @CompileClasspath
, order should definitely be considered.Vampire
05/27/2024, 3:03 PMVampire
05/27/2024, 3:04 PM@InputFiles
Martin
05/27/2024, 3:08 PMMartin
05/27/2024, 3:25 PMBuild cache key for task ':doStuff' is 577c34d43bca13bcb1fef643dac7d885
same cache key with PathSensistivity.RELATIVE
Martin
05/27/2024, 3:35 PM@Classpath
even if the order is different 🤔 (ci run)
macos
Build cache key for task ':doStuff' is abdad9a112189e9a43f70ec6a3d2f366
Task ':doStuff' is not up-to-date because:
No history is available.
/Users/runner/work/test-filecollection-order/test-filecollection-order/jars/netty-codec-4.1.34.Final.jar
/Users/runner/work/test-filecollection-order/test-filecollection-order/jars/analytics-jvm-0.6.4.jar
/Users/runner/work/test-filecollection-order/test-filecollection-order/jars/configuration-annotations-jvm-0.6.2.jar
/Users/runner/work/test-filecollection-order/test-filecollection-order/jars/okio-jvm-3.3.0.jar
/Users/runner/work/test-filecollection-order/test-filecollection-order/jars/okio-jvm-3.6.0.jar
/Users/runner/work/test-filecollection-order/test-filecollection-order/jars/okio-jvm-3.2.0.jar
linux
Build cache key for task ':doStuff' is abdad9a112189e9a43f70ec6a3d2f366
Task ':doStuff' is not up-to-date because:
No history is available.
/home/runner/work/test-filecollection-order/test-filecollection-order/jars/netty-codec-4.1.34.Final.jar
/home/runner/work/test-filecollection-order/test-filecollection-order/jars/okio-jvm-3.3.0.jar
/home/runner/work/test-filecollection-order/test-filecollection-order/jars/okio-jvm-3.2.0.jar
/home/runner/work/test-filecollection-order/test-filecollection-order/jars/analytics-jvm-0.6.4.jar
/home/runner/work/test-filecollection-order/test-filecollection-order/jars/configuration-annotations-jvm-0.6.2.jar
/home/runner/work/test-filecollection-order/test-filecollection-order/jars/okio-jvm-3.6.0.jar
Martin
05/27/2024, 3:38 PMVampire
05/27/2024, 3:39 PM@Classpath
property is different?
That sounds wrong to meMartin
05/27/2024, 3:40 PMThomas Broyer
05/27/2024, 3:49 PM@Classpath
in the same way that -classpath "somedir/*"
passed to the JVM is patform-dependent too.Vampire
05/27/2024, 3:53 PMval a by configurations.registering { isTransitive = false }
val b by configurations.registering { isTransitive = false }
dependencies {
a("commons-io:commons-io:2.4")
b("commons-lang:commons-lang:2.4")
}
@CacheableTask
abstract class Foo : DefaultTask() {
@get:Classpath
abstract val classpath: ConfigurableFileCollection
init {
outputs.upToDateWhen { true }
}
@TaskAction
fun foo() {
classpath.forEach { println(it) }
}
}
val foo by tasks.registering(Foo::class) {
classpath.from(a)
classpath.from(b)
}
val bar by tasks.registering(Foo::class) {
classpath.from(b)
classpath.from(a)
}
which results in
Resolve mutations for :foo (Thread[included builds,5,main]) started.
:foo (Thread[included builds,5,main]) started.
> Task :foo
Appending implementation to build cache key: Build_gradle$Foo_Decorated@b553d57856188a37e9c153a99e17afac
Appending additional implementation to build cache key: Build_gradle$Foo_Decorated@b553d57856188a37e9c153a99e17afac
Appending input file fingerprints for 'classpath' to build cache key: 80b864fcce8ee35d1fbbd1c341205786 - CLASSPATH{~\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.4\b1b6ea3b7e4aa4f492509a4952029cd8e48019ad\commons-io-2.4.jar=IGNORED / d472b1d1d088ae048cd96c7c0939fbf5, ~\.gradle\caches\modules-2\files-2.1\commons-lang\commons-lang\2.4\16313e02a793435009f1e458fa4af5d879f6fb11\commons-lang-2.4.jar=IGNORED / aece18b33613844514d59ddfe00c2f1c}
Non-cacheable because No outputs declared [NO_OUTPUTS_DECLARED]
Caching disabled for task ':foo' because:
No outputs declared
Task ':foo' is not up-to-date because:
No history is available.
~\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.4\b1b6ea3b7e4aa4f492509a4952029cd8e48019ad\commons-io-2.4.jar
~\.gradle\caches\modules-2\files-2.1\commons-lang\commons-lang\2.4\16313e02a793435009f1e458fa4af5d879f6fb11\commons-lang-2.4.jar
Resolve mutations for :bar (Thread[included builds,5,main]) started.
:bar (Thread[included builds,5,main]) started.
> Task :bar
Appending implementation to build cache key: Build_gradle$Foo_Decorated@b553d57856188a37e9c153a99e17afac
Appending additional implementation to build cache key: Build_gradle$Foo_Decorated@b553d57856188a37e9c153a99e17afac
Appending input file fingerprints for 'classpath' to build cache key: 45a7937557734f93d73fa600c2e4cb16 - CLASSPATH{~\.gradle\caches\modules-2\files-2.1\commons-lang\commons-lang\2.4\16313e02a793435009f1e458fa4af5d879f6fb11\commons-lang-2.4.jar=IGNORED / aece18b33613844514d59ddfe00c2f1c, ~\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.4\b1b6ea3b7e4aa4f492509a4952029cd8e48019ad\commons-io-2.4.jar=IGNORED / d472b1d1d088ae048cd96c7c0939fbf5}
Non-cacheable because No outputs declared [NO_OUTPUTS_DECLARED]
Caching disabled for task ':bar' because:
No outputs declared
Task ':bar' is not up-to-date because:
No history is available.
~\.gradle\caches\modules-2\files-2.1\commons-lang\commons-lang\2.4\16313e02a793435009f1e458fa4af5d879f6fb11\commons-lang-2.4.jar
~\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.4\b1b6ea3b7e4aa4f492509a4952029cd8e48019ad\commons-io-2.4.jar
So different order here result in different cache keys.
Maybe it is handled differently or has a bug when it is coming from one source with different order, so if you list files in an OS directory and it then mitigates the different order.
But even if so, if later the iteration order is different, it should probably not mitigate the different order there.Vampire
05/27/2024, 3:54 PMMight be platform dependent, but if it is, then still the result can be different if the classpath is ordered differently and thus the cache-key / up-to-date-key has to be different toopassed to the JVM is patform-dependent too.-classpath "somedir/*"
Adam
05/27/2024, 4:23 PMVampire
05/27/2024, 4:58 PMVampire
05/27/2024, 4:59 PMMartin
05/27/2024, 5:01 PMFileCollection
because I can’t make any assumptions how it was createdThomas Broyer
05/28/2024, 8:02 AMVampire
05/28/2024, 8:38 AM@InputFiles
. Do you know why that was necessary?Vampire
05/28/2024, 8:48 AMJavadoc
probably does not support incremental building due to the overview pages and so on so there it is not necessary.Martin
05/28/2024, 10:09 AMprivate final FileCollection stableSources = getProject().files((Callable<FileTree>) this::getSource);
Wait, how does that ensure stability? Is files()
going to sort by path or something like this?Martin
05/28/2024, 10:11 AMVampire
05/28/2024, 12:52 PMstable
does not refer to the order of the files, but about the FileCollection
instance.Vampire
05/28/2024, 12:53 PMIMPORTANT: To query incremental changes for an input file property, that property must always return the same instance.
Martin
05/28/2024, 12:53 PMVampire
05/28/2024, 12:53 PMJavaCompile#getSource()
calls super.getSource()
Martin
05/28/2024, 12:53 PMVampire
05/28/2024, 12:54 PMsourceFiles.getAsFileTree().matching(patternSet)
Vampire
05/28/2024, 12:54 PMgetAsFileTree()
returns a new instance on each callVampire
05/28/2024, 12:56 PMgetSource()
cannot be used directly for the incremental processing, but the stableSources
always has the same instance that then has the result of getSource
and thus is stable for the matter of the incremental task logic