Is it possible to convert: ```MapProperty<Stri...
# community-support
z
Is it possible to convert:
Copy code
MapProperty<String, Provider<String>>
into:
Copy code
Provider<Map<String, String>>
while preserving task dependencies?
I’m losing the task dependencies here:
Copy code
private class MyTaskPropertiesImpl(
    private val objects: ObjectFactory,
    private val providers: ProviderFactory
) : MyTaskProperties {

    private val mapProperty: MapProperty<String, Provider<String>> = objects.mapProperty<String, Provider<String>>()

    override fun set(key: String, value: String) {
        mapProperty.put(key, providers.provider { value })
    }

    override fun set(key: String, value: Provider<String>) {
        mapProperty.put(key, value)
    }

    override val myTaskInput: Provider<Map<String, String>> = providers.provider {
        val mapProperty = mapProperty.get()

        mapProperty.mapValues { (key, value) ->
            value.get()
        }
    }
}
and getting this problem: https://gradle-community.slack.com/archives/CAHSN3LDN/p1718938003760619
m
Why do you need map values to be providers, though? You can use
Provider<String>
as a value for
MapProperty<String, String>
. One difference that comes to mind is that
MapProperty<String, String>
evaluates all stored value providers at once when computing the actual values - is it a problem you need to work around?
z
I just have a third party task that requires
Property<Map<String, String>>
as a limitation unfortunately: https://github.com/SonarSource/sonar-scanner-gradle/blob/b7d7afad2ac036e8b0f781822[…]3a116dab1477c/src/main/java/org/sonarqube/gradle/SonarTask.java
m
Not sure if I follow.
MapProperty<String, String>
is-a
Provider<Map<String, String>>
.
MapProperty<String,String>
can accept
Provider<String>
as values. I still don't get where
MapProperty<String, Provider<String>>
is required.
and Sonar task only needs a
Provider<Map<String, String>>
. I don't think you can create
Property<Map<...>>
that easily anyway.
Having said that, I think you can
zip
the provider you want, but the way there is not nice: https://gist.github.com/mlopatkin/42a2d41947f007f07406a8c5f7dfe532
z
wow that’s wild haha
m
A person more well-versed in Kotlin API can simplify that to
Copy code
property.flatMap { map ->
map.entries.asSequence().map { e -> e.value.map { mapOf(e.key to it) } }.reduceOrNull { acc, provider ->
                acc.zip(provider) { l, r ->
                    buildMap {
                        putAll(l)
                        putAll(r)
                    }
                }
            } ?: provider { mapOf() }
}
but it still looks cursed.