Hantsy
Hantsy

Reputation: 9321

ext in buildscript can not be recognised by Gradle Kotlin DSL

In these days, I am trying to write some codes to experience the Spring reactive features and kotlin extension in Spring 5, and I also prepared a gradle Kotlin DSL build.gradle.kt to configure the gradle build.

The build.gradle.kt is converted from Spring Boot template codes generated by http://start.spring.io.

But the ext in the buildscript can not be detected by Gradle.

buildscript {
  ext { }
}

The ext will cause Gradle build error.

To make the variables in classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") and compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlinVersion") work, I added the variables in the hard way.

val kotlinVersion = "1.1.4"
val springBootVersion = "2.0.0.M3"

But I have to declare them in global top location and duplicate them in the buildscript.

Code: https://github.com/hantsy/spring-reactive-sample/blob/master/kotlin-gradle/build.gradle.kts

Is there a graceful approach to make ext work?

Update: There are some ugly approaches:

  1. From Gradle Kotlin DSL example, https://github.com/gradle/kotlin-dsl/tree/master/samples/project-properties, declares the properties in gradel.properties.

     kotlinVersion = 1.1.4
     springBootVersion = 2.0.0.M3
    

    And use it in build.gradle.kts.

     buildScript{
        val kotlinVersion by project
    
     }
      val kotlinVersion by project //another declare out of buildscript block.
    
  2. Similar with above declare them in buildScript block:

     buildScript{
        extra["kotlinVersion"] = "1.1.4"
        extra["springBootVersion"] = "2.0.0.M3"
        val kotlinVersion: String by extra
    
     }
      val kotlinVersion: String by extra//another declare out of buildscript block.
    

How can I avoid the duplication of val kotlinVersion: String by extra?

Update(2023-7-5): The latest Gradle supports libs.versions.toml file to declare dependency versions in a central place, it is also can be recognized by GitHub dependabot. see: https://docs.gradle.org/current/userguide/platforms.html

Upvotes: 100

Views: 61831

Answers (13)

BeCase
BeCase

Reputation: 161

As you mentioned above, you can use:

buildScript{
    extra["compose_version"] = "1.6.7"
}

To specify version of dependency in file build.gradle.kts of parent project.

And use this version in build.gradle.kts subprojects as:

dependencies {
    implementation("androidx.compose.ui:ui:${property("compose_version")}")
}

Upvotes: 0

babay
babay

Reputation: 4844

As far as I can see, the best way is to use Version Catalogs. You define a versionCatalogs in settings.gradle.kts, describe every required library in it, add a label to each library, and then use that library label in build.gradle files.

For example:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }

    versionCatalogs {
        create("libs") {
            library("rxandroid", "io.reactivex.rxjava2:rxandroid:2.1.0")
            library("rxjava", "io.reactivex.rxjava2:rxjava:2.2.4")
            library("commons-lang3", "org.apache.commons", "commons-lang3").version {
                strictly("[3.8, 4.0[")
                prefer("3.9")
            }
        }
    }
}

Then sync you project, so labels will be generated. and then add to your build.gragle:

dependencies {
    implementation(libs.rxjava)
    implementation(libs.rxandroid)
    implementation(libs.commons.lang3)
}

And you can move versionCatalogs to separate file and then include it. And you can use separate object with lib versions, if you like:

dependency.gradle.kts:

object LibVersions {
    const val rxJava =    "2.2.4"
    const val rxAndroid = "2.1.0"
}

dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            library("rxandroid", "io.reactivex.rxjava2:rxandroid:${LibVersions.rxAndroid}")
            library("rxjava", "io.reactivex.rxjava2:rxjava:${LibVersions.rxAndroid}")
            library("timber", "com.jakewharton.timber:timber:5.0.1")
        }
    }
}

settings.gradle.kts

buildscript {
    apply("dependency.gradle.kts")
}

You can read more here: https://docs.gradle.org/current/userguide/platforms.html

Upvotes: 1

Min2
Min2

Reputation: 10971

Between, from latest code style above will not work, only with some bits and pieces. However, added a plugins block if someone needs a way to handle the same in the .kts file system.

/build.gradle.kts:

buildscript {
    extra.apply {
        set("compose_ui_version", "1.2.0")
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.

plugins {
    id("com.android.application") version "7.4.0" apply false
    id("com.android.library") version "7.4.0" apply false
    id("org.jetbrains.kotlin.android") version "1.7.0" apply false
}

/app/build.gradle.kts:

dependencies {
    val composeUiVersion = rootProject.extra["compose_ui_version"]
    implementation("androidx.compose.ui:ui:$composeUiVersion")
    implementation("androidx.compose.ui:ui-tooling-preview:$composeUiVersion")
    androidTestImplementation ("androidx.compose.ui:ui-test-junit4:$composeUiVersion")
    debugImplementation ("androidx.compose.ui:ui-tooling:$composeUiVersion")
    debugImplementation ("androidx.compose.ui:ui-test-manifest:$composeUiVersion")
}

Upvotes: 2

Eva
Eva

Reputation: 4710

Set it like this:

val kotlinVersion by extra("1.1.4")

Use it like this:

val kotlinVersion: String by rootProject.extra

Upvotes: 2

solidsnack
solidsnack

Reputation: 1689

In Kotlin, the way to do this is with by extra or an ext block.

With by extra:

val kotlinVersion = "95" by extra
val kotlinCompiler = true by extra

With ext:

ext {
    set("kotlinVersion", "95")
    set("kotlinCompiler", true)
}

Upvotes: 4

顾小兔
顾小兔

Reputation: 41

val junitVersion by extra("4.13.2")
testImplementation("junit:junit:$junitVersion")

Upvotes: 4

Blundell
Blundell

Reputation: 76534

None of these answers felt clear to me. So here's my explanation:

/build.gradle.kts:

buildscript {
    extra.apply {
        set("compose_version", "1.0.3")
    }
    ...
}

/app/build.gradle.kts:

val composeVersion = rootProject.extra["compose_version"]
implementation("androidx.compose.ui:ui:$composeVersion")
implementation("androidx.compose.material:material:$composeVersion")

Upvotes: 26

sergiosua
sergiosua

Reputation: 364

It's a possibility to define global properties within gradle.properties:

xyzVersion=1.0.0

And then use them in your module's build.gradle.kts:

val xyzVersion: String by project

Upvotes: 0

Eugene Popovich
Eugene Popovich

Reputation: 3483

It is possible to use constants defined in .kt file in .gradle.kts files.

create buildSrc folder in root folder of your project

create buildSrc/build.gradle.kts file with the following content

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

create file buildSrc/src/main/kotlin/Constants.kt with the following content

object Constants {
    const val kotlinVersion = "1.3.70"
    const val targetSdkVersion = 28
}

Synchronize. Now you may reference created constants in various .gradle.kts files like this

...
classpath(kotlin("gradle-plugin", version = Constants.kotlinVersion))
...

...
targetSdkVersion(Constants.targetSdkVersion)
...

Upvotes: 36

Per Christian Henden
Per Christian Henden

Reputation: 1595

There is a new possibility with Kotlin we can use:

object DependencyVersions {
    const val JETTY_VERSION = "9.4.12.v20180830"
}

dependencies{
    implementation("org.eclipse.jetty:jettyserver:${DependencyVersions.JETTY_VERSION}")
}

Here, DependencyVersions is a name I chose. You can choose another name, like "MyProjectVariables". This is a way to avoid using the extra or ext properties.

Upvotes: 17

Shashi Bhushan
Shashi Bhushan

Reputation: 1350

With Kotlin DSL ext has been changed to extra and it can be used under buildscript.

Eg :-

buildscript {
    // Define versions in a single place
    extra.apply{
        set("minSdkVersion", 26)
        set("targetSdkVersion", 27)
    }
}

Upvotes: 58

nuamehas
nuamehas

Reputation: 614

Global properties in kotlin-gradle-dsl:
https://stackoverflow.com/a/53594357/3557894


Kotlin version is embedded into kotlin-gradle-dsl.
You can use dependecies with embedded version as follows:

implementation(embeddedKotlin("stdlib-jdk7"))

classpath(embeddedKotlin("gradle-plugin"))

Upvotes: 6

kamil zych
kamil zych

Reputation: 1712

What is working for me is using ext in allprojects instead of buildscript, so in your top-level build.gradle.kts

allprojects {
  ext {
    set("supportLibraryVersion", "26.0.1")
  }
}

then you can use it in build.gradle.kts files in modules like this:

val supportLibraryVersion = ext.get("supportLibraryVersion") as String

Upvotes: 25

Related Questions