Reputation: 1338
Gradle 5.0, Kotlin DSL
Create gradle.properties
file:
kotlinVersion=1.3.10
Create build.gradle.kts
file:
val kotlinVersion: String by project
println(kotlinVersion) // works
plugins {
kotlin("jvm").version(kotlinVersion)
// ^ Unresolved reference: kotlinVersion
}
repositories {
jcenter()
}
tasks.register("compute") {
doLast {
println(kotlinVersion) // works
}
}
Run gradle compute
, then change
kotlin("jvm").version(kotlinVersion)
to
kotlin("jvm").version("1.3.10")
and run again. Everything works.
Am I just doing something wrong? Or is it some sort of limitation or a bug?
I just wanted to move the Kotlin version out of the build script, so I could play with changing it later (e.g. via command line, ... -PkotlinVersion=1.3.0
) and also to keep it the same both for dependencies and plugins.
Upvotes: 8
Views: 3503
Reputation: 116
I typically use the buildSrc
directory to define objects that represent versions or properties that I wish to reuse, especially when I have multiple projects or multiple dependencies that stay lock-step with versioning. I put together a little example project here that demonstrates usage.
In buildSrc/src/main/kotlin/Versions.kt
I have:
object Versions {
// Library versions
val Kotlin = "1.3.10"
val logback = "1.2.3"
// Plugin versions
object Plugins {
// Can be changed if we want to use a version other than one matching the library version
val Kotlin = Versions.Kotlin
}
}
And I use it elsewhere like so:
plugins {
kotlin("jvm") version Versions.Plugins.Kotlin
}
// snip...
dependencies {
compile(kotlin("stdlib-jdk8"))
compile(group = "ch.qos.logback", name = "logback-classic", version = Versions.logback)
}
These are statically defined in the Versions.kt
file, but you could also read them from the environment, or a file, or properties. The real key is that your buildSrc
is evaluated before everything else, so it's available for all of the other phases in your build script (At least all the ones I've tried!).
Upvotes: 3
Reputation: 148149
As @yole said in his answer, the plugins { ... }
block is a special construct that is evaluated before the rest of the build script and has limited access to the Gradle model.
One way to pass a property and use it in the plugins { ... }
DSL is to use system properties:
val kotlinVersion = System.getProperty("kotlinVersion")?.toString()
?: error("Add a 'kotlinVersion' system property or pass -DkotlinVersion=...")
id("org.jetbrains.kotlin.multiplatform").version(kotlinVersion)
The way to pass a system property via command line is -DkotlinVersion=1.3.0
.
Upvotes: 1
Reputation: 97308
The plugins
block is evaluated separately from the rest of the build script, because the set of plugins you're using determines the classpath (and the name resolution scope) for the rest of the build script. Because of that, declarations outside of the plugins
block cannot be used inside that block.
Upvotes: 1