В нашей команде много проектов, созданных с помощью Gradle. Некоторые части в файлах Gradle одинаковы. Например, мы используем Java 11 во всех наших проектах. Итак, моя идея заключалась в том, чтобы разделить мои файлы build.gradle на общую часть, которая затем синхронизируется из центрального репозитория в каждый проект Gradle, в то время как конкретные части проекта остаются в build.gradle.
построить.градле:
plugins {
id 'java'
//...
}
apply from: "common.gradle.kts"
dependencies {
// ...
}
обыкновенный.градле.ктс
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}
test {
useJUnitPlatform()
}
Теперь я получаю сообщение об ошибке от Gradle
* Where:
Script '/Users/.../common.gradle.kts' line: 4
* What went wrong:
Script compilation errors:
Line 04: java {
^ Expression 'java' cannot be invoked as a function. The function 'invoke()' is not found
Line 04: java {
^ Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public val PluginDependenciesSpec.java: PluginDependencySpec defined in org.gradle.kotlin.dsl
Line 05: toolchain {
^ Unresolved reference: toolchain
Line 06: languageVersion = JavaLanguageVersion.of(11)
^ Unresolved reference: languageVersion
Line 09: test {
^ Unresolved reference: test
Line 10: useJUnitPlatform()
^ Unresolved reference: useJUnitPlatform
6 errors
Для некоторых конфигураций я нашел альтернативу, использующую более общий API, который работает, хотя поиск соответствующих альтернатив требует больших усилий, и в конце концов никто не может гарантировать, что они делают то же самое:
tasks.withType<JavaCompile> {
options.release.set(11)
}
Итак, остается вопрос: почему я не могу использовать функции DSL java
или test
в моем внешнем файле common.gradle.kts?
Кажется, это должно что-то делать с использованием сценария Kotlin, по крайней мере, если я использую Groovy для своего внешнего сценария, он работает.
В вашем common.gradle.kts
, java { }
создается вспомогательная функция Kotlin DSL. Gradle не знает о помощниках Kotlin DSL, если только
apply(from = "...")
Понимание того, когда доступны методы доступа к моделям с типобезопасностью
Only the main project build scripts and precompiled project script plugins have type-safe model accessors. Initialization scripts, settings scripts, script plugins do not. These limitations will be removed in a future Gradle release.
https://docs.gradle.org/current/userguide/implementing_gradle_plugins.html#reacting_to_plugins
Все еще возможно иметь свой common.gradle.kts
, но для этого необходимо настроить плагин Java без DSL Kotlin.
// common.gradle.kts
plugins.withType(JavaBasePlugin::class).configureEach {
// the project has the Java plugin
project.extensions.getByType<JavaPluginExtension>().apply {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
}
Это немного более неуклюже, потому что помощники Kotlin DSL недоступны.
Если вы хотите создать соглашения для одного проекта, то стандартным способом является создание подключаемых модулей соглашений buildSrc.
https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources
Это лучше всего подходит для проектов, которые имеют много подпроектов.
// $projectRoot/buildSrc/src/main/kotlin/java-convention.gradle.kts
plugins {
java
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}
test {
useJUnitPlatform()
}
См. ответ здесь для более подробной информации: https://stackoverflow.com/a/71892685/4161471
https://docs.gradle.org/current/userguide/implementing_gradle_plugins.html
Можно обмениваться подключаемыми модулями соглашений между проектами, если у вас есть репозиторий Maven для развертывания ваших подключаемых модулей.
Можно даже создать свой собственный дистрибутив Gradle, поэтому плагины включены вместе с оболочкой Gradle! https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:custom_gradle_distribution
Однако я бы посоветовал против этих подходов. Как правило, время, потраченное на создание общих плагинов, никогда не будет меньше, чем просто копирование и вставка плагинов соглашения buildSrc. И что еще более важно, лучше всего, чтобы проекты были независимыми. Хотя обмен соглашениями о сборке кажется хорошей идеей, он вводит зависимости, которые затрудняют отслеживание проблем, и затрудняет обновление общих плагинов, поскольку вы не уверены, какие могут быть последствия. В этой статье объясняется больше https://phauer.com/2016/dont-share-libraries-среди микросервисов/