web-dev-qa-db-fra.com

Gradle Kotlin DSL: Définissez la version Kotlin dans un lieu unique

Pour décrire les scripts de construction Gradle, nous pouvons utiliser Kotlin via build.gradle.kts des dossiers. C'est un problème commun de définir globalement la version de Kotlin à utiliser, à la fois dans la section dependencies et aussi dans la section build plugin (Il est assez rare d'avoir des versions différentes utilisé pour le cas donné).

Considérez le code suivant (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
}

Comme vous pouvez le voir, la kotlin version (1.2.30 dans ce cas) est définie deux fois : dependencyVersion et pluginVersion, qui très souvent ne diffère pas. En raison des restrictions DSL, il est impossible d'accéder au pluginVersion depuis l'extérieur du bloc plugins ou d'accéder au dependencyVersion depuis le bloc plugins.

Comment la chaîne de version, "1.2.30" être extrait à un seul endroit?

20
s1m0nw1

Dans les versions ultérieures de Gradle, vous n'avez plus besoin de spécifier la version de vos dépendances kotlin(stdlib|reflect|test), le plugin Kotlin les configurera automatiquement pour vous.

Quant à l'extraction de la dépendance vers un seul endroit, il existe deux schémas principaux:

  • définissez les constantes que vous souhaitez partager dans un objet dans buildSrc/src/main/kotlin/ et utilisez cet objet dans votre script de génération, le code de buildSrc est disponible pour tout le script, y compris le bloc plugins
  • utilisez une propriété système, vous pouvez définir une propriété système dans gradle.properties en préfixant son nom avec systemProp. et vous pouvez accéder aux propriétés système via System.getProperties(), par exemple:

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

Vous pouvez extraire la version de la classe du plugin:

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

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

val kotlinVersion = plugins.getPlugin(KotlinPluginWrapper::class.Java).kotlinPluginVersion
5
Ingo Kegel

Il existe une solution de contournement disponible, qui recherche la version définie pour le plugin kotlin et l'assigne à la variable externe. Ce qui suit le démontre:

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
}

La variable kotlinVersion peut alors être utilisée sans problème dans le dependencies.

1
s1m0nw1

Réponse au commentaire @ s1m0nw1 (trop long pour le commentaire): Non, vous ne pouvez pas utiliser les éléments buildSrc/src dans buildSrc/build.gradle. J'ai eu exactement ce problème lorsque j'ai écrit un plugin basé sur Android et j'ai besoin de Android dépendance du plugin gradle dans buildsSrc mais je déclare également cette dépendance dans le projet. J'avais donc deux emplacements différents et deux versions à maintenir .

J'ai résolu cela en créant un fichier gradle.properties dans le répertoire buildSrc. J'y ai créé un accessoire androidGradlePluginVersion=3.6.0-rc02

buildSrc/build.gradle:

val androidGradlePluginVersion: String by project
dependencies {
    implementation("com.Android.tools.build:gradle:$androidGradlePluginVersion")

buildSrc/src /.../ Versions.kt:

var Android_PLUGIN = loadAndroidGradlePluginVersion()

Utilisation pour les accessoires:

fun loadAndroidGradlePluginVersion(): String {
    Properties().apply { load(FileInputStream(GRADLE_PROPERTIES)) }.let {
        return it.getProperty(Android_PLUGIN_VERSION_PROP)
    }

    error("Provide $Android_PLUGIN_VERSION_PROP in $GRADLE_PROPERTIES")
} 
0
Kostek