Custom Task: connecting multiple Properties together

The documentation shows nicely how to connect an @Input Property of Task with an @Internal Provider using the map function:
https://docs.gradle.org/current/userguide/lazy_configuration.html#connecting_properties_together

abstract class Greeting : DefaultTask() {
    // Configurable by the user
    @get:Input
    abstract val greeting: Property<String>

    // Read-only property calculated from the greeting
    @Internal
    val message: Provider<String> = greeting.map { it + " from Gradle" }

    ...
}

Is there a way to connect multiple Properties this way? Let’s say, for example, if we had another Property

    @get:Input
    abstract val name: Property<String>

Maybe I’m missing something simple… :grimacing:

Yes, what you are after is the zip method. :slight_smile:

Thanks Björn! I already followed what I understood of your advice :slight_smile: But I don’t want to simply go away without completing my example. Besides, I have another related question…

So I went from Zip.java to AbstractArchiveTask.java, more specifically, this block:

I see it’s simply using a convention to bind things together.
What I needed is a bit more convoluted (yet affordable in configuration phase), but just to complement my example, my implementation uses this approach:

abstract class Greeting : DefaultTask() {
    @get:Input
    abstract val greeting: Property<String>
	
	@get:Input
    abstract val name: Property<String>

    @get:Internal
    abstract val message: Property<String>
	
	init {
		message.convention( project.provider {
			return@provider "${greeting.get()}, ${name.get()}"
		}
	}
	...
}

Worked like a charm (although message is no longer immutable, because it’s a Property. But that’s irrelevant for now…)

But I’m wondering: isn’t using getProject() in a custom Task a bad practice nowadays?
I assumed that because there is a growing emphasis on using Service Injection instead of things like getProject.exec(...).

Besides that you could inject a ProviderFactory to create a provider, you totally got me wrong.

I said “what you are after is the zip method” and I meant what I said.

I did not mean the tactic the Zip class is using.
But literally what I wrote, the zip method: Provider (Gradle API 8.7)

private val message: Provider<String> = greeting.zip(name) { greeting, name ->
    "$greeting, $name"
}
1 Like

I see. I didn’t know the `zip´ method so I went straight into the Zip Task.
Marked your last response as Solution then. Thanks!

1 Like