Gradle脚本Kotlin中的锅炉项目配置

我正在尝试改进我们的项目共享他们的配置的方式。 我们有许多不同的多模块gradle项目,用于我们的所有库和微服务(即许多git仓库)。

我的主要目标是:

  • 为了不让我的Nexus存储库URL在每个项目中都重复(另外,我可以放心地认为它不会改变)
  • 为了让我的定制Gradle插件可以用最少的样板/重复(每个项目都可以使用它们,而且项目唯一关心的是它使用的版本)
  • 没有什么魔力 – 开发人员应该很明白怎样配置一切

我目前的解决方案是一个定制的gradle分发与初始化脚本:

  • mavenLocal()和我们的Nexus存储库添加到项目回购(非常类似于Gradle 初始化脚本文档示例 ,除了添加回购以及验证它们)
  • 配置允许我们的gradle插件添加到buildscript类路径的扩展(使用此解决方法 )。 它还将我们的Nexus回购作为buildscript回购添加,因为这是插件托管的地方。 我们有很多插件(建立在Netflix优秀的星云插件上 ),用于各种样板:标准项目设置(kotlin设置,测试设置等),发布,发布,文档等等,这意味着我们的项目build.gradle文件非常多只是为了依赖。

虽然这种方法可行,但是允许可重复的构建(不同于我们之前的应用从URL构建脚本的设置),并且允许离线工作,这确实使它有点神奇,我想知道如果我能做得更好。

这一切都是由github上的Gradle开发人员最近阅读了一个评论(我不确定在哪里),指出构建应该在不依赖于init脚本的情况下工作,也就是说,init脚本应该像记录的例子那样做 – 防止未经授权的回购等

我的想法是编写一些扩展函数,允许我将Nexus repo和插件添加到构建中,看起来像是构建到gradle中的(类似于gradle脚本提供的扩展函数gradleScriptKotlin()gradleScriptKotlinApi()科特林)

所以我在一个kotlin gradle项目中创建了我的扩展函数:

 package com.example import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.dsl.RepositoryHandler import org.gradle.api.artifacts.repositories.MavenArtifactRepository fun RepositoryHandler.myNexus(): MavenArtifactRepository { return maven { with(it) { name = "Nexus" setUrl("https://example.com/repository/maven-public") } } } fun DependencyHandler.myPlugins(version: String) : Any { return "com.example:my-gradle-plugins:$version" } 

计划在我的项目build.gradle.kts使用它们如下:

 import com.example.myNexus import com.example.myPlugins buildscript { repositories { myNexus() } dependencies { classpath(myPlugins(version = "1.2.3")) } } 

但是,在buildscript脚本块中使用Gradle时无法看到我的函数(无法编译脚本)。 在正常的项目回购/依赖项中使用它们可以很好地工作(它们是可见的,按预期工作)。

如果这工作,我希望捆绑到我的自定义分配的jar,这意味着我的初始化脚本可以做简单的验证,而不是隐藏了神奇的插件和回购配置。 扩展函数不需要改变,所以当插件改变时不需要发布新的Gradle发行版。

我试过的:

  • 将我的jar添加到测试项目的buildscript类路径(即buildscript.dependencies ) – 不起作用(也许这不起作用的设计,因为它似乎不是正确的添加依赖到建立buildscript在同一个块)
  • 把这些函数放在buildSrc (这对于正常的项目deps / repos而言,而不是buildscript ,但是不是真正的解决方案,因为它只是移动样板)
  • 将jar放入发行版的lib文件夹中

所以我的问题归结为:

  • 是我想实现的可能(是否有可能使自定义类/功能可见的buildScript块)?
  • 是否有更好的方法来分享这个样板配置跨越多个单独的项目?

在我的构建中,我一直在做这样的事情

 buildscript { applyFrom("${rootProject.projectDir}/sharedValues.gradle.kts") val configureRepository: (Any) -> Unit by extra configureRepository.invoke(repositories) } 

在我的sharedValues.gradle.kts文件中,我有这样的代码:

 /** * This method configures the repository handler to add all of the maven repos that your company relies upon. * When trying to pull this method out of the [ExtraPropertiesExtension] use the following code: * * For Kotlin: * ```kotlin * val configureRepository : (Any) -> Unit by extra * configureRepository.invoke(repositories) * ``` * Any other casting will cause a compiler error. * * For Groovy: * ```groovy * def configureRepository = project.configureRepository * configureRepository.invoke(repositories) * ``` * * @param repoHandler The RepositoryHandler to be configured with the company repositories. */ fun repositoryConfigurer(repoHandler : RepositoryHandler) { repoHandler.apply { // Do stuff here } } var configureRepository : (RepositoryHandler) -> Unit by extra configureRepository = this::repositoryConfigurer 

我遵循类似的模式来配置插件的分辨率策略。

关于这种模式的buildSrc是,您在sharedValues.gradle.kts配置的任何东西都可以从buildSrc项目中使用,这意味着您可以重新使用存储库声明。