#java #gradle #kotlin #gradle-kotlin-dsl
#java #gradle #kotlin #gradle-kotlin-dsl
Вопрос:
Я пытаюсь начать использовать Kotlin DSL с gradle в проекте со следующими ограничениями:
- Проект имеет разные модули (более того: иногда эти модули используют разные плагины, однако, если два проекта используют один и тот же плагин, то версии плагинов одинаковы).
- Проект имеет только внутренние корпоративные репозитории (например, мы не используем jcenter напрямую, мы используем для этого прокси).
Что мы имеем с Groovy:
- Некоторые общие элементы конфигурации исключены из отдельных сценариев. Пожалуйста, ознакомьтесь с приведенным ниже примером.
- Модули Gradle включают эти файлы.
В результате (просто основываясь на моем примере):
- Нам не нужно добавлять одни и те же строки кода в каждый модуль.
- Большинство проектов отличаются только списком зависимостей.
Я попытался воспроизвести то же самое с Gralde KTS и столкнулся со следующими трудностями:
- Я не могу применить плагин во включаемом файле и использовать его в модуле. В этом случае я получаю ошибку компиляции (поскольку типы плагинов не добавляются в скрипт модуля).
- Я не могу извлечь константы из чего-то общего, чтобы использовать их в каждом скрипте (root
build.gradle.kts
включительно). С Groovy я могу просто использовать переменную likespringBootVersion
, однако с помощью скрипта Kotlin я должен создать одно и то же свойство в каждом файле модуля. - Предварительно скомпилированные плагины для скриптов не работают без доступа к общедоступным репозиториям (например, я не могу настроить общий файл скрипта с идеей «просто используйте встроенную версию скрипта Kotlin по умолчанию, загрузите все зависимости с этих URL: …».
Включить пример файла:
apply plugin: 'kotlin'
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
Пример модуля Gradle:
apply from: "${rootDir}/gradle/include/kotlin-common-include.gradle"
dependencies {
compile project(':my.project.libraries.common')
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion
}
Вопросы:
- Как я могу поместить все распространенные константы (такие как версии зависимостей) в отдельный файл, чтобы включить их, просто используя что-то вроде
springBootVersion
илиConstants.springBootVersion
с проверками во время компиляции? - Как я могу извлечь плагин, применяемый к включаемым скриптам (чтобы избежать перегрузки скриптов модуля Gradle)?
- Как я могу использовать предварительно скомпилированные плагины для скриптов без доступа к общедоступным глобальным репозиториям?
Дополнительные ссылки:
Ответ №1:
В настоящее время в Kotlin DSL существуют ограничения (5.3), которые не позволяют проводить проверки во время компиляции повсюду. Для того, чтобы Kotlin DSL работал, он должен добавлять расширения поверх Gradle API, и он не может сделать это волшебным образом. Прежде всего, вам нужно просмотреть страницу Kotlin DSL Primer, чтобы понять это.
Как я могу извлечь плагин, применяемый к включаемым скриптам (чтобы избежать перегрузки скриптов модуля Gradle)?
Один из способов сделать это — использовать предварительно скомпилированные скрипты сборки с подключаемым модулем Kotlin DSL. Для того, чтобы это сделать, вам нужно переместить ваш скрипт в $rootDir/buildSrc
проект. Вот как это может выглядеть:
// $rootDir/buildSrc/build.gradle.kts
plugins {
`kotlin-dsl`
}
repositories {
maven {
url = uri("http://host:8082/artifactory/...")
}
}
Затем поместите ваш общий скрипт следующим образом:
// $rootDir/buildSrc/src/main/kotlin/common.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.21"
}
tasks.compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
tasks.compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Затем вы можете применить этот скрипт как к подобному плагину:
// $rootDir/build.gradle.kts
subprojects {
apply(id = "common")
}
Как я могу использовать предварительно скомпилированные плагины для скриптов без доступа к общедоступным глобальным репозиториям?
Настройка пользовательских репозиториев для плагина предварительно скомпилированных скриптов ничем не отличается от вашего обычного скрипта сборки. Сделайте это вот так:
// $rootDir/buildSrc/settings.gradle.kts
pluginManagement {
repositories.maven {
url = uri("http://host:8082/artifactory/...")
}
}
Другой способ, если вы не хотите использовать предварительно скомпилированные плагины, — явно настроить расширения. Вы можете сделать это следующим образом:
// $rootDir/gradle/common.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
И в основной скрипт:
// $rootDir/build.gradle.kts
subprojects {
apply {
plugin(KotlinPlatformJvmPlugin::class)
from("common.gradle.kts")
}
}
Как я могу поместить все распространенные константы (такие как версии зависимостей) в отдельный файл, чтобы включить их, просто используя что-то вроде springBootVersion или Constants.springBootVersion с проверками во время компиляции?
В настоящее время нет хорошего способа сделать это. Вы можете использовать дополнительные свойства, но это не гарантирует проверки во время компиляции. Что-то вроде этого:
// $rootDir/dependencies.gradle.kts
// this will try to take configuration from existing ones
val compile by configurations
val api by configurations
dependencies {
compile("commons-io:commons-io:1.2.3")
api("some.dep")
}
// This will put your version into extra extension
extra["springBootVersion"] = "1.2.3"
И вы можете использовать это следующим образом:
// $rootDir/build.gradle.kts
subprojects {
apply {
plugin<JavaLibraryPlugin>()
from("$rootDir/dependencies.gradle.kts")
}
И в вашем модуле:
// $rootDir/module/build.gradle.kts
// This will take existing dependency from extra
val springBootVersion: String by extra
dependencies {
compile("org.spring:boot:$springBootVersion")
}