does anyone have a utility that converts a `List&l...
# plugin-development
t
does anyone have a utility that converts a
List<Provider<T>>
into a
Provider<List<T>>
? I've seen the Gradle-internal version here. I'm not a fan of using internal classes
j
I think maybe Provider.zip could be used?
e
I suppose you could
Copy code
fun <T : Any> Iterable<Provider<T>>.toProvider(): Provider<List<T>>? = fold(null) { acc: Provider<List<T>>?, provider ->
    acc?.zip(provider) { list, item -> list + item }
}
but I don't see a way of creating a
provider { emptyList() }
(for the empty case) without internals or access to a
ProviderFactory
šŸ¤” 1
a
Could pass it through a NDOC?
Copy code
val listOfProviders = listOf(
  provider { "a" },
  provider { "b" },
  provider { "c" },
)

abstract class X @Inject constructor(private val named:  String ): Named {
  abstract val value: Property<String>
  override fun getName(): String = named
}

val ndoc = objects.domainObjectContainer(X::class)

listOfProviders.forEachIndexed { index, provider ->
  ndoc.register("provider$index") {
    value = provider
  }
}

val providerOfList: Provider<List<String>> = ndoc.elements.map { elements ->
  elements.map { it.value.get() }
}
Personally I try and avoid ListProperty and the like, NDOCs tend to be easier to reason about and use.
y
@tony What kind of behaviour do you want? • Ignore providers that do not have a value and return a reduced list from the final provider • Return an empty provider if any of the source providers are empty.
t
Schalk, that's a great question. For my use-case, I think the first: ignore any provider that doesn't have a value and return a reduced list in the final
Provider<List<T>>
Specifically, I have a
List<Provider<MinimalExternalModuleDependency>>
. I'm iterating over it and doing
dependencies.add("...", provider)
. I'd like to do
configurations.named("...") { dependencies.addAllLater(providerOfList) }
. tbh I'm not actually sure that's "better" but I wanted to give it a try. Encountering this problem also reminded me I've run into it before so I became interested in the conversion in general
y
@tony In the generic case it could be something like this piece of Groovy
Copy code
public <R> Provider<List<? super R>> invertListDropEmpty(List<Provider<? super R>> list) {
        provider { ->
            list.findAll { it.present }.collect { it.get() }
        }
    }
Still not sure whether it will actually work in the context you've mentioned.
šŸ‘€ 1
t
I may give it (or another of the examples above) a shot! if so, will update the thread.
šŸ‘ 1
I've tried both these approaches and they both pass the simple test. It's not clear to me if one is better than the other
well, it doesn't work for my use-case, actually. But I think that has to do with how
configuration.dependencies.addAllLater()
works, not necessarily those utility functions themselves
y
I had a suspicion it wouldn't work for that use case.