Gradle Kotlin DSL: Identify a Kotlin Version in a Unique Location

To describe Gradle build scripts, we can use Kotlin through build.gradle.kts files. Common problem to globally identify version of Kotlin, which will be used both in dependencies and in the build plugin section (it is rather unusual to use different versions for this case).

Consider the following code (Gradle 4.3.1):

 plugins { var pluginVersion = "1.2.30" kotlin("jvm").version(kotlinVersion) // more } var dependencyVersion = "1.2.30" dependencies { compile(kotlin("stdlib", kotlinVersion)) compile(kotlin("reflect", kotlinVersion)) testCompile(kotlin("test", kotlinVersion)) // more } 

As you can see, the kotlin version (1.2.30 in this case) is defined twice: dependencyVersion and pluginVersion , which very often is no different . Due to DSL restrictions, it is not possible to access pluginVersion from outside the plugins block or to access dependencyVersion from the plugins block.

How can the version string "1.2.30" be extracted in one place?

+18
source share
4 answers

In later versions of Gradle, you no longer need to specify the version of kotlin(stdlib|reflect|test) dependencies kotlin(stdlib|reflect|test) , the Kotlin plugin will automatically configure them for you.

As for extracting dependencies to one place, there are two main patterns:

  • define the constants that you want to use in the object in buildSrc/src/main/kotlin/ , and use this object in your build script, the code from buildSrc is available for the whole script, including the plugins block
  • use the system property, you can define the system property in gradle.properties by specifying its name on systemProp. , and you can access the system properties through System.getProperties() , for example:

     // build.gradle.kts plugins { val kotlinVersion by System.getProperties() println("Kotlin version is $kotlinVersion") } // gradle.properties systemProp.kotlinVersion=1.2.20 
+12
source

You can extract the version from the plugin class:

 import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper plugins { kotlin("jvm") version "1.2.0" } val kotlinVersion = plugins.getPlugin(KotlinPluginWrapper::class.java).kotlinPluginVersion 
+5
source

A workaround is available that looks for the version specific to the kotlin plugin and assigns this to an external variable. This demonstrates the following:

 val kotlinVersion: String? by extra { buildscript.configurations["classpath"] .resolvedConfiguration.firstLevelModuleDependencies .find { it.moduleName == "kotlin-gradle-plugin" }?.moduleVersion } plugins { kotlin("jvm").version("1.2.30") //more } 

Now the kotlinVersion variable can be used in dependencies without additional problems.

+1
source

I just came across using Kotlin classes in my build.gradle.kts .

I had to:

  • create a module called buildSrc with src/main/kotlin and build.gradle.kts in its root.
  • include("buildSrc") in settings.gradle.kts

buildSrc/build.gradle.kts very minimal:

 plugins { 'kotlin-dsl' } repositories { jcenter() } 

In buildSrc/src/main/kotlin I added Config.kt

 const val GROUP_ID = "my-company" const val VERSION = "0.1.0-SNAPSHOT" const val POM_NAME = "my-library-name" const val POM_DESCRIPTION = "A library doing stuff." const val POM_URL = "https://github.com/${GROUP_ID}/${POM_NAME}/" const val POM_SCM_URL = POM_URL const val POM_SCM_CONNECTION = "scm:git:git://github.com/${GROUP_ID}/${POM_NAME}.git" const val POM_SCM_DEV_CONNECTION = "scm:git:ssh:// git@github.com /${GROUP_ID}/${POM_NAME}.git" const val POM_LICENCE_NAME = "The Apache Software License, Version 2.0" const val POM_LICENCE_URL = "http://www.apache.org/licenses/LICENSE-2.0.txt" const val POM_LICENCE_DIST = "repo" const val POM_DEVELOPER_ID = "me" const val POM_DEVELOPER_NAME = "meeee" const val POM_DEVELOPER_EMAIL = " me@foo.com " 

And Dependencies.kt

 @file:Suppress("MemberVisibilityCanBePrivate") object Jvm { const val version = "1.8" } object Kotlin { const val version = "1.3.50" const val stdlibJdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" const val jvmId = "jvm" const val kaptId = "kapt" } object MavenPublish { const val id = "maven-publish" } object Arrow { const val version = "0.10.1" const val core = "io.arrow-kt:arrow-core:$version" const val syntax = "io.arrow-kt:arrow-syntax:$version" const val optics = "io.arrow-kt:arrow-optics:$version" const val fx = "io.arrow-kt:arrow-fx:$version" const val meta = "io.arrow-kt:arrow-meta:$version" } object Versions { const val version = "0.27.0" const val versions = "com.github.ben-manes:gradle-versions-plugin:$version" const val id = "com.github.ben-manes.versions" } 

So that I could use it in my root build.gradle.kts as

 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin(Kotlin.jvmId) version Kotlin.version kotlin(Kotlin.kaptId) version Kotlin.version id(Versions.id) version Versions.version id(MavenPublish.id) } group = GROUP_ID version = VERSION repositories { mavenCentral() jcenter() } dependencies { implementation(Kotlin.stdlibJdk8) implementation(Arrow.core) implementation(Arrow.syntax) kapt(Arrow.meta) } tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = Jvm.version } publishing { publications { create<MavenPublication>("mavenJava") { @Suppress("UnstableApiUsage") pom { name.set(POM_NAME) description.set(POM_DESCRIPTION) url.set(POM_URL) licenses { license { name.set(POM_LICENCE_NAME) url.set(POM_LICENCE_URL) distribution.set(POM_LICENCE_DIST) } } developers { developer { id.set(POM_DEVELOPER_ID) name.set(POM_DEVELOPER_NAME) email.set(POM_DEVELOPER_EMAIL) } } scm { connection.set(POM_SCM_CONNECTION) developerConnection.set(POM_SCM_DEV_CONNECTION) url.set(POM_SCM_URL) } } } } } 

I am quite happy with this, but when it comes down to automatically increasing version , I can gradle.properties to save it in gradle.properties .

0
source

Source: https://habr.com/ru/post/1273783/


All Articles