-
Notifications
You must be signed in to change notification settings - Fork 434
Provider API recommendations and differences from Groovy DSL #597
Comments
Is this something overloaded setters might help solve? It is some more boilerplate for authors but everything is clearly specified through types with no reliance on coffee generation magic. The kotlin DSL might then be able to generate those setters if they aren't present, but I'm not sure how that works with type erasure and how it works in Groovy land either. |
…n now This takes the approach to make Kotlin look more like the explicitness of Java until we can do something fancier (like setter overloads). - We want to expose a single getter that returns the Provider/Property - The GreetingExtension and Greeting task had unnecessarily mutable variables - Handwritten separate setters/getters for a Property isn't what we want people to do. And I think we don't want authors to expose special methods for setting Provider or raw values. Fixes #597
…n now This takes the approach to make Kotlin look more like the explicitness of Java until we can do something fancier (like setter overloads). - We want to expose a single getter that returns the Provider/Property - The GreetingExtension and Greeting task had unnecessarily mutable variables - Handwritten separate setters/getters for a Property isn't what we want people to do. And I think we don't want authors to expose special methods for setting Provider or raw values. Fixes #597
Still not a fan of how the API's will be different for plugins written in Java/Groovy vs Kotlin. I think it will just add additional confusion for new users, but I don't have any better solutions. |
I think my original post made it sound like things were more different than they are the same. Everything is the same between Java, Groovy and Kotlin, except for one area. The pattern for writing plugins is the same for all languages (expose a single getter for the For Java and Kotlin, you have to use We could remove the generated setters from the Groovy DSL to make things look the same as Kotlin DSL. That would make everything the same. |
Are these |
They can be on both. e.g., https://guides.gradle.org/implementing-gradle-plugins/#capturing_user_input_to_configure_plugin_runtime_behavior (scroll down a bit) |
Almost all plugins I've ever worked with uses the "Assignment" method for configuring extensions and Tasks. Eg: kotlin {
// Enable coroutines supports for Kotlin.
experimental.coroutines = Coroutines.ENABLE
} task<Wrapper>("wrapper") {
gradleVersion = "4.7"
distributionType = Wrapper.DistributionType.ALL
} Exposing an API that doesn't use these sort of assignment setters seems completely unintuitive, especially since users have been trained by all of the various plugins and Gradle's own API that those are what will exist. Also, is there a clear migration path for plugin developers who already have these setters and want to migrate to the It really seems like whether or not the plugin developer is using the As a plugin developer, I'd rather go for consistency with the existing paradigm for my users. |
@eskatos But adding a setter would deviate from the suggested pattern, wouldn't it?
Or do you mean something different? |
Right, what I had in mind is the interface Provider<T> {
T getValue();
}
interface Property<T> extends Provider<T> {
void setValue(T value);
void setValue(Provider<? extends T> provider);
} which would allow to write: val some = someTask.stringProp.value
// and:
someTask.stringProp.value = "some"
// and with overloaded setters support in Kotlin:
someTask.stringProp.value = provider { "some" } Then, for a property that allows being set with different types: interface SomeProperty extends Property<String> {
void setValue(Object anything);
} and an implementation doing the conversion from someTask.someProp.value = whatever Its not as nice as a direct assignment on the Considering simple assignment on the |
@eskatos You're getting the closest I've seen to what we'd probably want to users to see. |
This was a discussion that came up WRT the Provider API documentation we're adding in 4.4: gradle/gradle#3478
We're recommending that plugin authors expose a single getter for their
Property
(orProvider
) properties.From the Groovy DSL, we generate methods to allow people to use
=
in build scripts withProperty
s:Under the covers, this is calling
someProperty.setFromAnyValue(...)
, which eventually callsProperty.set(T)
orProperty.set(Provider)
.I know this isn't quite possible from the Kotlin DSL. @eskatos pointed me to the PropertyStateExtensions and sample https://github.com/gradle/kotlin-dsl/blob/master/samples/provider-properties/build.gradle.kts
This is pretty close, but it has some differences/problems:
Property
in the Kotlin DSL will have to be differentProperty
.Property
(so they can't use the assignment syntax above)@Optional
doesn't play nice with the PropertyStateExtensions.I don't think the idiomatic way for writing a Gradle plugin in Kotlin needs to be exactly the same as any other language, but we should consider the impact to the Groovy DSL, other plugins (not written in Kotlin) and the general confusion users may have if
Property
s are handled differently depending on which language the plugin was written in.The text was updated successfully, but these errors were encountered: