Slackbot
05/22/2023, 4:10 PMJavi
05/22/2023, 4:13 PMextensions.create<T>(…)
Javi
05/22/2023, 4:15 PMJavi
05/22/2023, 4:15 PMAdam
05/22/2023, 4:41 PMbecause the conventions plugin kts does not have a class that i am already inside (or, maybe it does but it’s not visible)yeah, you guessed right: it’s there, but it’s not visible. an explanation, if it helps: all .kts files, be they
.gradle.kts
files or .main.kts
files, basically just copy and paste the file content into a dummy class’s init block, and add some properties to the class so they’re accessible in the context.
if you check the build directory of a project with pre-compiled script plugins you can find the compiled JAR, and see that the .kts
files are compiled to regular classes.Adam
05/22/2023, 4:45 PM.gradle.kts
file has a fancy wrapper so that, seamlessly, Project is in the receiver. You can do the same thing in a regular class plugin by doing
override fun apply(target: Project) = with(target) {
// ...
}
(or don’t, because sometimes it gets a bit messy and confusing with too many receivers)Shaun Reich
05/22/2023, 5:05 PMShaun Reich
05/26/2023, 4:29 PMinterface GreetingPluginExtension {
val message: Property<String>
val greeter: Property<String>
}
class GreetingPlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create<GreetingPluginExtension>("greeting")
project.task("hello") {
doLast {
println("${extension.message.get()} from ${extension.greeter.get()}")
}
}
}
}
//apply<GreetingPlugin>()
// Configure the extension using a DSL block
configure<GreetingPluginExtension> {
message.set("Hi")
greeter.set("Gradle")
}
in the downstream plugin consumer:
apply<GreetingPlugin>()
// Configure the extension using a DSL block
configure<GreetingPluginExtension> {
message.set("Hi guid")
greeter.set("Gradle from guid")
}
Adam
05/26/2023, 4:32 PMAdam
05/26/2023, 4:32 PMShaun Reich
05/26/2023, 4:32 PMShaun Reich
05/26/2023, 4:33 PMAdam
05/26/2023, 4:33 PMbuildSrc/build.gradle.kts
?Adam
05/26/2023, 4:33 PMapply<MyPlugin>()
btwShaun Reich
05/26/2023, 4:34 PMShaun Reich
05/26/2023, 4:35 PMthis
class)
(2) second, totally separate project applies the convention plugin. that works fine. what isn't working, is it not being able to find that symbol WITHIN the convention pluginAdam
05/26/2023, 4:37 PMGreetingPlugin
is a nested class. So you’ll need do something like
apply<My_convention_Gradle.GreetingPlugin>()
because Gradle will generate a class based on the file name, if that makes sense?Adam
05/26/2023, 4:39 PM.gradle.kts
file? I have distant warning alarms ringing… :) I suspect you’re going to run into more issuesShaun Reich
05/26/2023, 4:40 PMShaun Reich
05/26/2023, 4:40 PMShaun Reich
05/26/2023, 4:40 PMShaun Reich
05/26/2023, 4:42 PMShaun Reich
05/26/2023, 4:43 PMAdam
05/26/2023, 4:44 PMbuildSrc/src/main/kotlin/GreetingPluginExtension.kt
interface GreetingPluginExtension {
val message: Property<String>
val greeter: Property<String>
}
Adam
05/26/2023, 4:45 PM// buildSrc/src/main/kotlin/greeting-plugin.gradle.kts
val extension = project.extensions.create<GreetingPluginExtension>("greeting")
Adam
05/26/2023, 4:47 PM// ./build.gradle.kts
plugins {
`greeting-plugin`
}
greeting {
println(message.orNull)
}
Adam
05/26/2023, 4:47 PMkotlin-dsl
plugin applied in buildSrc/build.gradle.kts
)Adam
05/26/2023, 4:48 PMbuildSrc/src/main/kotlin/greeting-plugin.gradle.kts
// buildSrc/src/main/kotlin/greeting-plugin.gradle.kts
val extension = project.extensions.create<GreetingPluginExtension>("greeting")
extension.message.convention("hello!")
extension.greeter.convention("greetings!")
Adam
05/26/2023, 4:48 PMShaun Reich
05/26/2023, 9:15 PMAdam
05/27/2023, 9:30 AMAdam
05/27/2023, 9:30 AMShaun Reich
05/30/2023, 5:58 PMAdam
05/30/2023, 6:43 PMbuildSrc/build.gradle.kts
that says “I depend on the subproject ‘build-conventions’”Adam
05/30/2023, 6:45 PMbuildSrc/src/main/kotlin
Adam
05/30/2023, 6:48 PM├── buildSrc/
│ ├── src/main/kotlin/
│ │ ├── GreetingPluginExtension.kt
│ │ └── myproject.greeting.gradle.kts
│ ├── build.gradle.kts
│ └── settings.gradle.kts
├── build.gradle.kts
└── settings.gradle.kts
Shaun Reich
05/30/2023, 6:57 PMAdam
05/30/2023, 6:58 PMShaun Reich
05/30/2023, 6:59 PMShaun Reich
05/30/2023, 7:00 PMShaun Reich
05/30/2023, 7:01 PMAdam
05/30/2023, 7:04 PMincludeBuild("../build-conventions)
in buildSrc/settings.gradle.kts
(probably in the pluginsManagement {}
blockAdam
05/30/2023, 7:05 PMAdam
05/30/2023, 7:08 PMmyproject.java-conventions.gradle.kts
, are you sure it’s worth the complication? It’s okay if buildSrc/build.gradle.kts
just looks like this:
plugins {
`kotlin-dsl`
}
dependencies {
/* plugins */
}
And maybe you need to have a little duplication between some build configs, but a little duplication is much more simple than trying to set up multiple included buildsShaun Reich
05/30/2023, 7:34 PMbuildsrc
in this context, doesn't have everything on the classpath. but...that's my point, if i tell you to create my-conventions-plugin, then i should just be able to apply that in my application, assuming it can resolve t hat in the first placeShaun Reich
05/30/2023, 7:36 PMShaun Reich
05/30/2023, 7:39 PMShaun Reich
05/30/2023, 7:40 PMAdam
05/30/2023, 7:40 PMAdam
05/30/2023, 7:40 PMShaun Reich
05/30/2023, 7:41 PMShaun Reich
05/30/2023, 7:42 PMShaun Reich
05/30/2023, 7:42 PMAdam
05/30/2023, 7:42 PMShaun Reich
05/30/2023, 7:43 PMShaun Reich
05/30/2023, 7:43 PMShaun Reich
05/30/2023, 7:43 PMAdam
05/30/2023, 7:45 PM├── buildSrc/
│ ├── src/main/kotlin/
│ │ ├── GreetingPluginExtension.kt
│ │ └── myproject.greeting.gradle.kts
│ ├── build.gradle.kts
│ └── settings.gradle.kts
├── build.gradle.kts
└── settings.gradle.kts
then the Kotlin DSL Gradle will create a JAR with an auto-generated plugin class, and the extension class, and a Plugin ID marker.
And that whole JAR will get added to the build.gradle.kts
classpath if there’s a plugin ID that matches the plugin ID marker in the JARAdam
05/30/2023, 7:49 PMbut that’s not the thing i can get. Hence why the code i linked to, the build breaksI haven’t checked it out so maybe I’ve missed something, but from what I can see the build will break because 1. it tries to compile the file
buildSrc/src/main/kotlin/myproject.greeting.gradle.kts
2. but that needs the GreetingPluginExtension class
3. but in build.gradle.kts
there’s no dependency on the build-conventions
project - so it can’t fetch the file
In order for the class to be available you’d have to add a dependency (probably using dependency substitutions)… but I’m not 100% sure that would work, because buildSrc has some limitations so I don’t think it can use composite buildsAdam
05/30/2023, 7:55 PMShaun Reich
05/30/2023, 8:16 PMShaun Reich
05/30/2023, 8:19 PMAdam
05/30/2023, 8:21 PMAdam
05/30/2023, 8:22 PMsonar uses gradlePlugin and pluginBundle {}, neither of which i do outright by myself.Ah yeah, that’s part of the Kotlin DSL plugin magic. Normally you have to manually define an implementation class and a plugin ID, but the Kotlin DSL plugin will scan your source files and automatically generate a plugin ID (based on package + filename) that points towards the generated implementation class If you look in
$myProject/buildSrc/build/pluginDescriptors
you’ll see the descriptorsShaun Reich
05/30/2023, 8:23 PMShaun Reich
05/30/2023, 8:24 PMShaun Reich
05/30/2023, 8:24 PMShaun Reich
05/30/2023, 8:24 PMAdam
05/30/2023, 8:25 PMAdam
05/30/2023, 8:25 PMShaun Reich
05/30/2023, 8:26 PMAdam
05/30/2023, 8:27 PMAdam
05/30/2023, 8:27 PMbuild-logic/src/main/kotlin/org/jetbrains/DokkaBuildProperties.kt
which is a project-local extension that’s applied in a ‘base’ convention plugin
build-logic/src/main/kotlin/org/jetbrains/conventions/base.gradle.kts
Adam
05/30/2023, 8:29 PMprovider.gradleProperty()
to get the default value, which means the values can be overridden on the command line, or a gradle.properties file, or using a environment variable
this is most useful when setting the Java version used to run the project’s tests, so in a GitHub action loads of different Java versions can be tested
https://github.com/Kotlin/dokka/blob/0cad056d84bf1dbe285ca008be17ca5fbb224818/build-logic/src/main/kotlin/org/jetbrains/conventions/base-java.gradle.kts#L31-L33Shaun Reich
05/30/2023, 8:30 PMShaun Reich
05/30/2023, 8:30 PMShaun Reich
05/30/2023, 8:31 PMAdam
05/30/2023, 8:33 PM