Open TWiStErRob opened 1 year ago
Don't use Kotlin lambdas in your public API
I think this should go with
Don't use Groovy closures in your public API
The rationale is that one is pretty much unusable from the other language - also both from Java.
When you use Action<T>
, it stays idiomatic in plugins implemented in plain Java, Groovy or Kotlin.
In the Groovy DSL (build scripts and precompiled scripts), there's some bytecode magic to also add Closure
based overloads mostly for backwards compatibility.
In the Kotlin DSL (build scripts, precompiled scripts and .kt
files in source sets with the kotlin-dsl
applied), Action<T>
is declared as a "lambda with receiver" equivalent to T.() -> Unit
in order to remove the need to use it.
.
@TWiStErRob, if your users are using includeBuild(gradle/plugins)
they should get what Gradle provides according to the following, otherwise it's a bug
@eskatos Ah, thanks, that's some proper magic there 🙇🏻♂️!!!
Sorry, I confused two of my projects (or in some places I didn't apply kotlin-dsl
). I double-checked now and I see it actually working in practice:
includeBuild(gradle/plugins)
and in gradle/plugins/build.gradle.kts
have implementation(...)
dependencies on Detekt Gradle Plugin, and then it defines plugins that configure Detekt reports. This fun reports
only defines Action<T>
overload, yet the usage compiles as if it was T.()
overload. This works fine as you described.java-gradle-plugin
+ kotlin(jvm)
subproject that pulls in the same dependency and if I put the same code in there, I have to use it
:
project.tasks.withType<Detekt>().configureEach {
it.reports {
it.html.required.set(true) // human
it.txt.required.set(true) // console
}
}
otherwise it doesn't compile. This is what I was referring to. So the answer here is that I need to apply kotlin-dsl
to these modules to get the magic of @HasImplicitReceiver interface Action<T>
.
It was always confusing not being able to use them the same way, thanks for clarifying! (Now I understand some IntellIJ errors I saw related to this when sync was broken! TIL)
I've been reading your guide, pretty cool summary. I got hung up on this suggestion, could you please expand on it a bit more or link to some resources?
Why is that? What will break?
That's great, but what if my users are using
includeBuild(gradle/plugins)
, at that point my plugin will be a normal dependency and Gradle doesn't provide a nice DSL magic transformation. Any suggestion to support both?