Hello, this is very gradle specific so I might ask...
# gradle
j
Hello, this is very gradle specific so I might ask in the gradle forums but does anyone know how I can depend on the kotlin-dsl plugin as an
implementation
dependency for a custom gradle plugin without applying the kotlin-dsl plugin to the custom gradle plugin build? I tried depending on this target but a lot of the kotlin extension functions weren’t found (same with others in the group).
m
Maybe this?
Copy code
implementation(gradleKotlinDsl())
But TBH I discourage using the Kotlin DSL dependency. You don't need
String.invoke()
val foo by creating {}
, etc.. Using the "DSL" term is a bit misleading. It's all imperative under the hood.
e
You dont need String.invoke() or foo by creating for sure … but you do need the reified kotlin extensions (instead of sprinkling
::class.java
everywhere) & the dsl syntax is in most cases nicer than calling it imperatively. Personally, I encourage plugin authors to use the dsl if possible
m
Agree the reified variants are a bit more palatable. But it comes with so many other things I don't need, I'm happy to keep my
::class.java
around
For writing plugins especially I'm trying to avoid it because my code is not copy/pastable anymore
If my user is writing a convention plugin that doesn't have
kotlin-dsl
(which they shouldn't add because it is slow) then they have to figure out how to translate again
The removed chars are not worth the fragmentation IMO
e
because its slow
To be clear I am also very much against using precompiled script plugins & applying the
kotlin-dsl
plugin. I am saying that plugin devs writing binary plugins in kotlin should add
gradleKotlinDsl()
dependency and use it, thats all. Its already on the classpath so no / negligible overhead.
not copy/pastable anymore … fragmentation
There’s already 3 languages for writing plugins (Java, Kt, Groovy) so its pretty fragmented already. Personally, I dont think being “copy pastable” should be a goal when you are writing a plugin but if it is then of course it makes more sense not to use the kotlin DSL in your examples / code.
m
This is my latest hobby lately, write code blocks that work the same in Java/Groovy/Kotlin
It's not always possible but it sometimes is!
gradle intensifies 2
e
Thats an interesting hobby! I will admit, I don’t have the patience for it but it sounds pretty cool
m
Saves a click on one tab for users (and duplicating code blocks for me)
very nice 1
j
Thank you i’ll try that! And yes, its more for the reified extensions in building my own plugin. I was going to write my own if I needed but wanted to see if I could use the dsl
that works!
🎉 1
well partially haha. i guess i was using more than i realized. Any idea on how to get the settings dsl for things like
dependencyManagement
?
v
There’s already 3 languages for writing plugins (Java, Kt, Groovy) so its pretty fragmented already.
Why only those? You can use any JVM language. And that's fine.
👌 1
e
@Justin Tullgren If you are talking about the fact that `Action<T>`s act as lambdas with receivers, you can manually apply
org.jetbrains.kotlin.plugin.sam-with-receiver
and configure it like this:
Copy code
samWithReceiver.annotation("org.gradle.api.HasImplicitReceiver")
(OR you could apply the
kotlin-dsl-base
plugin which gives you all of the above functionality w/o the precompiled scripts part) (I know its a lot of info, sorry)
☝️ 1
🙏 1
m
Shameless plug for my "Plugins in Kotlin" recipes. There's a section that explains what `kotlin-dsl` is doing (lots of things)
💯 1
e
Didn’t know you had a cookbook! Nice. For me, I write my plugins like this these days (plus
gradleKotlinDsl()
dependency of cos). I can’t give up assignment overloading & implicit receivers. They are just sooo convenient & way more readable (imo)
m
I used to do that as well but now I just want the same Kotlin everywhere. At this point, I'm waiting eagerly for declarative Gradle so that there's no need for all this DSL stuff anymore.
e
Yeah me too. I still have mixed feelings about dcl but I will need to try it out myself. I feel like plugins with dcl will still face the same issues today so I am not totally sold yet
m
It's 100% declarative so there's no more "trying to make Kotlin look like a DSL". The downside obviously is that now everyone needs to write some king "convention plugin".
It's higher bar to entry. Hacking a build in the script file is not working anymore
But for any large-ish build, this is probably a feature
e
Yes but plugins will not be declarative scripts, they still need to be binaries (I assume) so they will face the same issues, where everyone writes their own convention plugins how they like but integration between these different “conventions” becomes a chore or even still, a nightmare (for the build engineers)
(I welcome the simplicity of dcl for build users however, just that I dont see how build authors will not have a hard time)
m
I think convention plugins should be imperative code and therefore not use any of the "DSL" things.
• Convention plugin => Imperative code => Regular Kotlin • Project file => Declarative => Some declarative language (preferrably not yaml!)
The "Kotlin DSL" blurring the lines is the original mistake IMO
e
If you are talking about our discussion before the dcl topic then my follow up is why? There is zero advantage in writing
myProperty.set(myValue)
over
myProperty = myValue
. It IS regular kotlin code 😅
m
Sure but it also looks a bit magic. It's always a tradeoff between expressivity and explicitness
Same reason why I don't like collection literals. Sure you can write
[1,2]
instead of
listOf(1,2)
but then you need to teach both versions to everyone
But Gradle likes multiple ways to do it 😄
e
I’m sorry but “looks like magic” is not a very strong point to me. When you write suspend functions it also does “look like magic” but I am guessing you wouldnt rather go back to writing callbacks (even the kotlin plugin refactored to use suspend functions in KGP) because it just models domain & operations better
m
Right. Just the assignement is Gradle specific while coroutines are first party
I also want rich errors instead of custom sealed classes
You could argue we need to experiment with those ideas
e
Assignment is not gradle specific, you can apply the assignment plugin yourself, I use it myself in a lot of projects. Although I understand what you mean that it needs an extra step to enable / configure but that is a feature in this case as kotlin wanted to limit applicability of assignment overloading.
Yeah goes back to this your point which I fully agree with > It’s always a tradeoff between expressivity and explicitness For me, I spend a lot of time reading code, so I want to get most of the “fluff” out of the way as much as possible but of course it needs to be balanced
m
I think I would be a lot more enthusiastic if the SAM receiver used the
@DslMarker
annotation (I have been burnt multiple times with resolving the wrong
name
) and there was a compile-time safe way to represent a non-optional
Property
Right now it feels halfway there
yes black 1
j
@efemoney Thanks! I’ll try it later today.