Reputation: 158
In build.gradle.kts
file, I include this code on the top line. Then I use KotlinCompilerVesion.VERSION below.
import org.jetbrains.kotlin.config.KotlinCompilerVersion
Some code works fine, but some code failed:
It seems like only plugins
block can not enable this import
.
Here works fine:
dependencies {
Implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION))
Implementation(kotlin("test", KotlinCompilerVersion.VERSION))
}
Here always wrong:
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
/*
* Error: Unresolved reference: KotlinCompilerVersion
*/
id("kotlinx-serialization") version KotlinCompilerVersion.VERSION
/*
* Error: Unresolved reference: KotlinCompilerVersion
*/
id("kotlinx-serialization") version "$KotlinCompilerVersion.VERSION"
/*
* Error: Unresolved reference: KotlinCompilerVersion
*/
id("kotlinx-serialization") version "${KotlinCompilerVersion.VERSION}"
}
How can I use it correctly in here, without declare an ext.xxxVersion
var?
Upvotes: 8
Views: 9938
Reputation: 1765
One solution is to define a local object in the plugin {}
block. This can reduce duplication within the block itself.
plugins {
val PluginVersions =
object {
val SPRING_BOOT = "3.2.2"
val SPRING_DEPENDENCY_MANAGEMENT = "1.1.4"
val KOTLIN = "1.9.22"
val KTFMT = "0.17.0"
}
war
id("org.springframework.boot") version PluginVersions.SPRING_BOOT
id("io.spring.dependency-management") version PluginVersions.SPRING_DEPENDENCY_MANAGEMENT
kotlin("jvm") version PluginVersions.KOTLIN
kotlin("plugin.spring") version PluginVersions.KOTLIN
kotlin("plugin.serialization") version PluginVersions.KOTLIN
id("com.ncorti.ktfmt.gradle") version PluginVersions.KTFMT
}
You can also use the Gradle version catalog which lets you make a gradle/libs.versions.toml
file which can be referenced from your build.gradle.kts
file. It seems to be best practice for version management (especially if you share versions across multiple Gradle projects). However, personally I feel it makes the build.gradle.kts
look like ugly with an overload of references and aliases everywhere.
The contents of the buildSrc are available inside the plugin {}
block. So if you add a basic buildSrc/build.gradle.kts
folder with:
repositories { mavenCentral() }
plugins { `kotlin-dsl` }
And a buildSrc/main/kotlin/Versions.kt
file with:
object Versions {
const val SPRING = "3.2.2"
const val SPRING_DEPENDENCY_MANAGEMENT = "1.1.4"
const val KOTLIN = "1.9.22"
}
You will be able to access the object inside the plugins {}
block.
Upvotes: 0
Reputation: 371
Yes, the syntax of the plugins DSL is limited because Gradle parses it before parsing the rest of the file, which requires the definition to be static (no references to variables, constants, etc., pretty much no code is allowed). See Limitations of the plugins DSL for details.
The way I handle defining Kotlin version only once is by actually using the version I specify in the plugins block as canonical in other sections of the file (I picked this up from this blog post by Simon Wirtz) like so:
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
val kotlinVersion = plugins.getPlugin(KotlinPluginWrapper::class.java)
.kotlinPluginVersion
plugins {
kotlin("jvm") version "1.3.30"
}
dependencies {
implementation(platform(kotlin("bom", kotlinVersion)))
implementation(kotlin("stdlib-jdk8"))
}
But yeah, in the plugins block it needs to be static and unfortunately repeated if needed.
Update: I actually just learned it's possible to use constants in the plugins DSL, but they must be defined before Gradle parses the build.gradle.kts
file, i.e. from buildSrc
. I noticed this in the fuel library. In essence, create buildSrc/build.gradle.kts
with the following contents:
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
Then create buildSrc/src/main/kotlin/Constants.kt
with the following contents:
object Kotlin {
const val version = "1.3.30"
}
And then you'll be able to use the following in your main build.gradle.kts
:
plugins {
kotlin("jvm") version Kotlin.version
}
Upvotes: 6