I hope someone can explain this to me.
I was moving some code from a Gradle build file into a Gradle plugin.
Below are two code snippes calling the same from
function (based on Ideas indexing)
I noticed that there are some strange differences between how the apis can be used in those two contexts.
I know that Gradle is adding some extra syntax suger around the build files which is why I need to manually cast the task in the Plugin.kt
file, but I cannot find anything that explains why from in context of the Build file has this
as context where in the plugin the function uses it
to access the into
function.
It is not just Idea that reports this, running Gradle also shows that it must be like this.
I assume this is something special to Kotlin's way of handling the Action
interface in different contexts:
- kts file (No wrapping class)
- kt file (with class)
Here are the two samples
hostedStaticFiles
is gradle configuration that will be used to configure web frontend from a separate build.
build.gradle.kts
tasks.getByName<ProcessResources>("processResources") {
this.from(hostedStaticFiles) {
[email protected]("static") // <-- Note use of this here
}
}
Plugin.kt
project.tasks.getByName("processResources").let<Task, ProcessResources> {
if (it !is ProcessResources) {
throw IllegalStateException("The processResources task in Project is not of type ${ProcessResources::class.java}")
}
it
}.apply {
dependsOn(hostedStaticFiles)
[email protected](hostedStaticFiles) { it -> // <-- Note use of it here and below
it.into("static")
}
}
dependencies {
hostedStaticFiles(project("client"))
}
I hobe someone can point me to an explanation or preferably documentation on why this behaves this way :)
Gradle version 7.4.1
###################
After getting the answer from @Joffrey I updated my buildSrc/build.gradle.kts
with the below plugin configuration and it all started working as expected.
plugins {
`java-gradle-plugin`
`kotlin-dsl`
}
CodePudding user response:
Gradle uses the HasImplicitReceiver annotation on some function types (like Action
), so you can use this
instead of it
. It leverages Kotlin's SAM-with-receiver compiler plugin.
In Kotlin build scripts (.gradle.kts
files) you benefit from this automatically because the Kotlin compiler used to compile your scripts is already properly configured. However, in custom plugin projects, you are in control of the build and you need to apply the kotlin-dsl
plugin yourself. As mentioned in the documentation, it does a few things for you, including:
- Configures the Kotlin compiler with the same settings that are used for Kotlin DSL scripts, ensuring consistency between your build logic and those scripts.