How to get ext.* variables into plugins block in build.gradle.kts

10k views Asked by At

My build file looks like this:

val nexusBaseUri: String by extra
val gradle_version: String by extra
val kotlin_version: String by extra

buildscript {
    val nexusBaseUri by extra { "https://mynexusserver/nexus" }
    val gradle_version by extra { "4.1" }
    val kotlin_version by extra { "1.1.4-3" }
    val springBoot_version by extra { "2.0.0.M3" }

    repositories {
        maven { url = uri("$nexusBaseUri/repository/public") }
        jcenter()
        maven { url = uri("http://repo.spring.io/snapshot") }
        maven { url = uri("http://repo.spring.io/milestone") }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBoot_version")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version")
    }
}

plugins {
    application
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    // the following line causes a problem
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    kotlin("jvm", kotlin_version)
}

apply {
    plugin("kotlin-spring")
    plugin("org.springframework.boot")
    plugin("io.spring.dependency-management")
}

application {
    mainClassName = "eqip.fid.FdmlInterpreterDeveloperAppKt"
}

repositories {
    maven { url = uri("$nexusBaseUri/content/groups/public") }
    jcenter()
    maven { url = uri("http://repo.spring.io/snapshot") }
    maven { url = uri("http://repo.spring.io/milestone") }
}

dependencies {
    compile(kotlin("stdlib"))
    compile("org.springframework.boot:spring-boot-starter-web")
}

tasks {
    "wrapper"(Wrapper::class) {
        gradleVersion = gradle_version
    }
}

The error I get in IntelliJ IDEA is

'val kotlin_version: String' can't be called in this context by implicit receiver. Use the explicit one if necessary

How do I fix this?

2

There are 2 answers

3
s1m0nw1 On

You can define a version inside plugins and then make this version accessible outside of the block, e.g. in the dependencies section.

plugins {
    kotlin("jvm").version("1.1.61")
}

//This is necessary to make the version accessible in other places
val kotlinVersion: String? by extra {
    buildscript.configurations["classpath"]
            .resolvedConfiguration.firstLevelModuleDependencies
            .find { it.moduleName == "kotlin-gradle-plugin" }?.moduleVersion
}

dependencies {
    compile(kotlin("stdlib", kotlinVersion))
}

for version 1.2+, you will have to replace with kotlin-gradle-plugin org.jetbrains.kotlin.jvm.gradle.plugin

0
cesards On

I've been doing some tests around defining properties inside and outside the project buildscript block and it doesn't seem to work. The working and recommended solution if you want to have access to dependency-related properties is defining a buildSrc module (check this github repo) and then adding a Kotlin File/Class with the desired properties (versions, strings...). Something like:

object Dependency {

    object Foundation {

        const val KOTLIN = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Version.Global.KOTLIN}"
        const val RANDOM_VERSION = "1.2.3"
    }

You could have access to anything declared in your buildSrc module because components declared in there are resolved during the Initialization phase if I'm not mistaken. Usage example as it follows:

plugins {
    val kotlin = Dependency.Foundation.KOTLIN
    kotlin("kapt").version(Dependency.Foundation.RANDOM_VERSION)
}

More info here.