Gradle Kotlin DSL: Определите версию Kotlin в уникальном месте
Для описания скриптов сборки Gradle мы можем использовать Kotlin через build.gradle.kts
файлы. Общей проблемой для глобально определить версию Kotlin, которая будет использоваться, как в dependencies
, так и в разделе build 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
}
Как вы можете видеть, kotlin version
(1.2.30 в этом случае) определяется дважды: dependencyVersion
и pluginVersion
, что очень часто не отличается. Из-за ограничений DSL невозможно получить доступ к pluginVersion
извне блока plugins
или получить доступ к dependencyVersion
из блока plugins
.
Как строка версии "1.2.30"
может быть извлечена в одно место?
Ответы
Ответ 1
В более поздних версиях Gradle вам больше не нужно указывать версию зависимостей kotlin(stdlib|reflect|test)
, плагин Kotlin автоматически настроит их для вас.
Как для извлечения зависимости к одному месту, существуют два основных шаблона:
- определите константы, которые вы хотите использовать в объекте в
buildSrc/src/main/kotlin/
, и используйте этот объект в своей сборке script, код из buildSrc
доступен для всего script, включая блок 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
Ответ 2
Вы можете извлечь версию из класса плагина:
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
plugins {
kotlin("jvm") version "1.2.0"
}
val kotlinVersion = plugins.getPlugin(KotlinPluginWrapper::class.java).kotlinPluginVersion
Ответ 3
Доступно обходное решение, которое ищет версию, определенную для плагина kotlin, и присваивает это внешней переменной. Это демонстрирует следующее:
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
без дополнительных проблем.
Ответ 4
Я только что наткнулся на использование классов Kotlin в моем build.gradle.kts
.
Я должен был:
- создайте модуль с именем
buildSrc
с src/main/kotlin
и build.gradle.kts
в его корне.
include("buildSrc")
в settings.gradle.kts
buildSrc/build.gradle.kts
очень минимальный:
plugins {
'kotlin-dsl'
}
repositories {
jcenter()
}
В buildSrc/src/main/kotlin
я добавил 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://[email protected]/${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 = "[email protected]"
И 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"
}
Так что я мог бы использовать его в своем корне build.gradle.kts
как
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)
}
}
}
}
}
Я вполне доволен этим, но когда все сводится к автоматическому увеличению version
, я могу отступить, чтобы сохранить его в gradle.properties
.