Martmists
08/18/2025, 12:18 PMtasks.named(...).isPresent
, but it seems tasks.named is throwing an UnknownTaskException instead?Martin
08/18/2025, 12:21 PMMartmists
08/18/2025, 12:21 PMMartin
08/18/2025, 12:22 PMVampire
08/18/2025, 12:23 PMisPresent
is to check whether the provider is present or has no value.
But you do not even come that far, as named(...)
requires that the task is already registeredMartin
08/18/2025, 12:23 PMisPresent
is part of the Provider
APIVampire
08/18/2025, 12:23 PMVampire
08/18/2025, 12:23 PMtasks.names.contains(...)
to check whether the task is already registered without forcing it to be realized.Vampire
08/18/2025, 12:23 PMVampire
08/18/2025, 12:24 PMMartin
08/18/2025, 12:27 PMtasks.names.contains(...)
That's an aside to this discussion but that's technically 2 lookups. It's a pity Gradle doesn't provide an API that does both at the same time IMO (which named()
does but at the price of using exceptions for flow control, which isn't great either)Martmists
08/18/2025, 12:28 PMVampire
08/18/2025, 12:36 PMThat's an aside to this discussion but that's technically 2 lookupsNot sure what you mean. You get a list and then look in that list. That's one lookup for me.
but only if that task doesn't already exist.You really shouldn't do that. Instead for example have one separate plugin that adds this task, and from the other plugins that would register the task if it is absent, just apply that other plugin that always registers it.
Martmists
08/18/2025, 12:37 PMdependsOn(project.tasks.named(...))
? Since this task is designed to be used by the developer in their build scripts rather than by a plugin registering the task, so if they register a task with this type it should automatically add the dependency ideallyVampire
08/18/2025, 12:39 PMMartin
08/18/2025, 12:39 PMNot sure what you mean.With
tasks.names.contains()
, you first need to check for existence and get the value if it exists. Would be cool to be able to do both in a single callMartmists
08/18/2025, 12:39 PMMartin
08/18/2025, 12:39 PMMap<T>.get(): T?
Vampire
08/18/2025, 12:43 PMJust like there isAh, I see, you didn't mean the check, but theMap<T>.get(): T?
registerIfAbsent
idiom.
Well, it is usually bad practice, that might be the reason they don't provide it. 🤷♂️
But feel free to open a feature request to see what Gradle folks think if there is none yet. 🙂
It's currently designed to just be lifted from the repo as-is and put into a buildSrcWhere would you then apply the separate plugin I mentioned? Or where would you have wanted to do the "register task if it does not exist" logic if not in a plugin they apply?
Vampire
08/18/2025, 12:45 PMtasks.withType(...).configureEach { ... }
that configures all tasks of that type and set them up as required, including tasks the consumers register manually in their build scripts.
And besides that, either way you should not use dependsOn
.
Practically any explicit dependsOn
that does not have a lifecycle task on the lefthand side is a code smell and usually a sign that you do not properly wire task outputs to task inputs, which would automatically add the necessary task dependency.
So if you for example have the download task that has an @OutputFile
property to which you download the file and then an @InputFile
property on the other task that needs it, you would wire those properties together and with that have the necessary task dependency automatically where needed.Martin
08/18/2025, 12:46 PMBut feel free to open a feature request to see what Gradle folks think if there is none yetI'll skip that one, there are a bunch of more pressing issues at the moment, I can live with this
Vampire
08/18/2025, 12:49 PMMartin
08/18/2025, 12:52 PMmaybeCreate
is Map.getOrPut{}
. In that case, it'd be more like Map.getOrDefault{}
Vampire
08/18/2025, 12:55 PMnamed { ... }
and check if it is there.
You just have to keep in mind that it is only working configuration-avoidance safe combined with configureEach
not with iterating or checking even thought that was its original intention.Vampire
08/18/2025, 12:56 PMgetOrPut
just configuration-avoidance safe ... and it shouldn't be done 😄