This message was deleted.
# plugin-development
s
This message was deleted.
a
It would be a
NamedDomainObjectContainer<Provider<String>>
?
k
The
Provider<String>
is meant to be a name key to something in the container.
a
I apologize if I'm being dense. But
NamedDomainObjectContainer
is keyed with a String. Would the
Provider<String>
be the source for that key?
k
Yes.
a
ohh, I think I understand now. By "produce" you meant create a custom Provider, and not retrieve a Provider<String> from the Container?
k
Right - I have a
Provider<String>
, and the container can produce
Provider<T>
, so I was looking for some
map()
or
flatMap()
operation on the name provider that gets around
container.named()
erroring out if there is no object of type
T
by that name in the container.
a
ohh, duh. I got mixed up. Sorry!
What would you consider "no value" that's being returned to be?
null
?
k
Provider.isPresent == false
equivalently,
Provider.get()
errors,
Provider.getOrNull()
returns null, etc.
a
So, I don't see a way doing this without bolting something onto an existing container and breaking it's interface. The contract of the container is to either error, or return
null
if the key isn't found (depending on which method you use). There's no way to get it to produce anything else. Even the method which accept a configuration action fail if the key isn't found. So, in order to get what you want, you'd need to implement your own
NamedDomainObjectContainer<T>
or wrap calls to it in some code, which wouldn't be compliant with it's interface.
What object would the
map{}
you referenced be called on?
k
Provider.map()
a
ohhhh, hrmm.
k
ie.
Copy code
val result: Provider<T> = nameProvider.flatMap { container.named(it) }
but not erroring if
named()
errors out.
a
nameProvider
is of type
Provider<String>
?
k
Yes
a
So, the problem is that you can't change the type of the provider using any of the inbuilt functions.
map
not being able to accept a String isn't an issue with the Kotlin version, but rather that
result
is declared using a generic. Since you're passing
it
to
findByName
it assumes that
it
is a String, which is why it's complaining.
it
needs to be of type
T
I think...
k
??? To reiterate:
Copy code
val nameProvider: Provider<String> = ...
val container: NamedDomainObjectContainer<T> = ...
val result: Provider<T> = ...?
a
Can you post the full code snippet?
Do you have access to the
project
object?
k
No; I don't see why you would need it.
a
#2 isn't applicable in this scenario, since the key is of type
Provider<String>
and you're looking for a more generic
Provider<T>
and you can't change the type of the provider with the inbuilt transform methods.
k
Copy code
fun <R, T> Provider<T>.map(fn: T -> R?): Provider<R>
fun <R, T> Provider<T>.flatMap(fn: T -> Provider<R>?): Provider<R>
(note: on older versions of Gradle, the return type of
fn
is not nullable)
a
huh... Where are you seeing those docs?
And which version of Gradle are you using?
Sure enough. I was wrong!
Good catch ๐Ÿ™‚
My apologies for being a dunce and leading you astray ๐Ÿ˜ž
I'm assuming you're not using gradle 8, right?
Specifically 8.4+
k
Currently on Gradle 7, for which the functions passed to
map()
and
flatMap()
need to return non-nullable values from the Kotlin API. (I am aware that Gradle 8 fixed it.)
a
Darn. The filter() method (Added in 8.4) would allow you to return an empty Provider based upon a predicate. So, if findByName returned null, you can filter on that.
And if you get a null back, return an empty Provider
I'm sorry. I don't see a way to do this using Gradle 7. ๐Ÿ˜ž
e
NamedDomainObject provides you with the names, no?
You should be able to do
myProvider.map { if (it !in namedContainer.names) null else it }
or if on Gradle 8.4/5
myProvider.filter { it in namedContainer.names }
(Iโ€™m using an older version of Gradle where the Kotlin API says that
map
canโ€™t take a
String -> T?
)
Its there even in the newer versions of Gradle, its an issue with the API declaration, see a workaround here https://github.com/slackhq/slack-gradle-plugin/blob/aed728664ab35501b27c0e6979b228[โ€ฆ]/slack-plugin/src/main/kotlin/slack/gradle/util/PropertyUtil.kt
v
I didn't read the whole conversation, but you already gave the solution yourself in your original post already.
Just don't get confused by the IDE showing an error. ๐Ÿ™‚
121333: Executing 'help'...
Type-safe project accessors is an incubating feature.
> Configure project :
task ':build'
null
> Task :help
Welcome to Gradle 7.6.3.