Gradle Kotlin DSL: определите версию Kotlin в уникальном месте

для описания сценариев сборки Gradle мы можем использовать Kotlin через build.gradle.kts файлы. Это общая проблема для глобального определения the Kotlin версия для использования, как в dependencies и в plugin раздел (довольно необычно иметь разные версии, используемые для данного случая).

рассмотрим следующий код (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
}

как видите, Котлин version (1.2.30 в данном случае) определяется два раза: dependencyVersion и pluginVersion, который очень часто ничем не отличается. Из-за ограничений DSL невозможно получить доступ к pluginVersion из-за plugins блокировать или получить доступ к dependencyVersion внутри plugins заблокировать.

как может строка версии,"1.2.30" быть извлеченным в одно место?

3 ответов


в более поздних версиях Gradle вам больше не нужно указывать версию вашего kotlin(stdlib|reflect|test) зависимости, плагин Kotlin автоматически настроит их для вас.

Что касается извлечения зависимости в одно место, есть два основных шаблона:

  • определите константы, которыми вы хотите поделиться в объекте в buildSrc/src/main/kotlin/ и используйте этот объект в своем скрипте сборки, код из buildSrc доступен для всего скрипта, включая plugins блок
  • используйте системное свойство, вы можете определить системное свойство в gradle.properties, предварив его имя с systemProp. и вы можете получить доступ к свойствам системы через System.getProperties(), например:

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

вы можете извлечь версию из класса плагина:

import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper

plugins {
    kotlin("jvm") version "1.2.0"
}

val kotlinVersion = plugins.getPlugin(KotlinPluginWrapper::class.java).kotlinPluginVersion

существует обходной путь, который ищет версию, определенную для плагин Котлин и присваивает это значение внешней переменной. Это демонстрирует следующее:

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
}

переменная kotlinVersion затем можно использовать в dependencies без дальнейших неприятностей.