This message was deleted.
# configuration-cache
s
This message was deleted.
m
task.getImage().convention(imageBuilder.map(t -> t.getOutputFile().get()));
What?
map
with a
.get()
inside? Why don't you use
flatMap
instead? Well, I ask you. If I write:
task.getImage().convention(imageBuilder.flatMap(BuildNativeImageTask::getOutputFile));
then the task input (the dependency on the
imageBuilder
task) is not tracked anymore!
The pb is that the 1st one is not compatible with the configuration cache, while the 2d is
So, I have to write (put your sunglasses on, this is going to shine):
imageBuilder.map(t -> imageBuilder.flatMap(BuildNativeImageTask::getOutputFile).get())
which is both compatible with the configuration cache and tracks inputs
I thought that
flatMap
was precisely designed to track inputs...
t
I believe this has been reported a few times, both here and in the issue trackerโ€ฆ and issues have been closed by the stale bot
๐Ÿคฆโ€โ™‚๏ธ 1
v
No,
flatMap
is not designed to preserve task dependencies.
map
is. With
flatMap
the provider is completely replaced by the provider you get from the lambda. So
flatMap
only preserves task dependencies if the provider you return already has that task dependency, for example because it is an output property of a task where the task dependency got forwarded to.
and issues have been closed by the stale bot
thank god they changed it to just mark it as stale but not auto-close anymore currently. ๐Ÿ™‚
m
what I meant is that it is supposed to do exactly what I want. Quoting the docs:
this method offers a convenient way of connecting together task inputs and outputs
I am connecting the output of the
imageBuilder
task to the input of another task.
it actually doesn't work here
note that
getOuputFile
is defined as:
Copy code
@Internal
    public Provider<RegularFile> getOutputFile() {
        return getOutputDirectory().flatMap(dir -> dir.file(getExecutableName()));
    }
v
Yeah, that's exactly the problem I guess. It is
@Internal
so the task property does not get propagated to it. And the
flatMap
you do inside also removes the task dependency that would have been on
getOutputDirectory()
which I guess is
@OutputDirectory
. If you change that to a
map
it will probably have the task dependency.
So
Copy code
@Internal
    public Provider<RegularFile> getOutputFile() {
        return getOutputDirectory().map(dir -> dir.file(getExecutableName()).get());
    }
and then
Copy code
task.getImage().convention(imageBuilder.flatMap(BuildNativeImageTask::getOutputFile));
m
so you go from one silly code to another ๐Ÿ™‚
v
You could probably also annotate
getOutputFile
as output instead, with all the consequences. Then the dependency should be propagated to it from the task.
m
nope, I tried and it doesn't
๐Ÿ˜ฑ 1
I tend to think that
flatMap
shouldn't drop task dependencies, but that there should be an explicit call to drop task dependencies in case that's really what you want
v
๐Ÿคท
m
but I guess this could lead to tasks being executed when they are not needed...
v
Probably. And would be a pretty breaking change.
m
no wonder folks think Gradle is complicated ๐Ÿ˜„
v
Well, ... ๐Ÿ˜„
If you want it ugly but without
map
, how about:
Copy code
@Internal
public Provider<RegularFile> getOutputFile() {
    return getOutputDirectory().zip(getOutputDirectory().flatMap(dir -> dir.file(getExecutableName())), (a, b) -> b);
}
๐Ÿ˜„
m
๐Ÿฅน
v
Are those good or bad tears? ๐Ÿ˜„