Viktor
Viktor

Reputation: 1338

Why I cannot access project properties in "plugins" section of build.gradle.kts with Gradle Kotlin DSL (5.0)?

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

Answers (4)

Gombal
Gombal

Reputation: 149

Properties can be accessed by:

project.properties["kotlinVersion"]

Upvotes: -1

TehBilly
TehBilly

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

hotkey
hotkey

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

yole
yole

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

Related Questions