混合 Groovy/Kotlin DSL 多项目构建,Kotlin 如何读取 ext 变量
Mixed Groovy/Kotlin DSL multiproject build, How can Kotlin read ext variables
我正在探索将我们的 Groovy 基于 DSL 的构建文件转换为 Kotlin,并希望逐步执行此操作。但是,我无法弄清楚如何在子项目 build.gradle.kts
.
中读取顶层 build.gradle
中设置的 ext
变量
我的实验库可用here
它有这样的布局:
.
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── groovy
│ └── build.gradle
├── kts
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── java
│ └── xyz
│ └── abc
│ └── def
│ └── Main.java
└── settings.gradle
顶层文件定义了一个 ext
变量,其中包含像这样的通用库版本:
plugins {
id("java")
}
ext.libraries = [ shared: "xyz.abc.def:art:1.2" ]
有两个子项目,一个使用 Groovy DSL,一个使用 Kotlin DSL。他们都试图声明对 libraries.shared
.
的依赖
╰─➤ cat groovy/build.gradle
plugins {
id("java")
}
dependencies {
implementation(libraries.shared)
}
╰─➤ cat kts/build.gradle.kts
plugins {
id("java")
}
dependencies {
implementation(libraries.shared)
}
settings.gradle
包括两个项目。
╰─➤ cat settings.gradle
include "groovy"
include "kts"
当我 运行 ./gradlew projects
我得到这个错误:
Line 6: implementation(libraries.shared)
^ Unresolved reference: libraries
当 kts
子项目的包含被注释掉时它成功,显示 groovy
子项目。
我已经尝试了很多不同的东西来引用 libraries
,例如 project.extra
或 extra
,但到目前为止还没有找到任何有效的方法。
编辑:
在 Gradle API 文档中仔细研究后,我想到了这个,它有效但绝对可怕。
implementation((project.getParent()!!.extra.properties["libraries"]!! as HashMap<String, String>).get("shared")!!);
您可以在 kotlin 脚本中使用它
plugins {
java
}
val libraries: Map<String, String> by rootProject.extra
repositories {
mavenCentral()
}
dependencies {
implementation(libraries["shared"]!!)
}
编辑
如果您使用的是 Gradle 的当前(在撰写本文时为 7)版本,您可以尝试新版本的目录功能——在撰写本文时它处于预览状态,因此可能是道路坎坷...
为此,您可以从根项目中删除 ext.libraries
,并在 settings.gradle
中用它替换
enableFeaturePreview('VERSION_CATALOGS')
dependencyResolutionManagement {
versionCatalogs {
libs {
alias('shared').to('com.bloidonia:ascii-image:1.1')
}
}
}
然后在 Groovy 和 Kotlin DSL 构建脚本中,您可以通过以下方式引用这些依赖项:
implementation(libs.shared)
编辑 2 -- 喝咖啡后
啊哈,所以我认为这回答了 Jeff 在评论中的问题,并显示了替代方案
是的,我们可以像这样在根项目中添加一个 ext 函数:
ext.libraries = [ shared: "com.bloidonia:ascii-image:1.1" ]
ext.library = { String name ->
ext.libraries."$name"
}
然后在Kotlin项目中,我们可以做:
val library: groovy.lang.Closure<String> by rootProject.extra
dependencies {
implementation(library("shared"))
}
我正在探索将我们的 Groovy 基于 DSL 的构建文件转换为 Kotlin,并希望逐步执行此操作。但是,我无法弄清楚如何在子项目 build.gradle.kts
.
build.gradle
中设置的 ext
变量
我的实验库可用here
它有这样的布局:
.
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── groovy
│ └── build.gradle
├── kts
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── java
│ └── xyz
│ └── abc
│ └── def
│ └── Main.java
└── settings.gradle
顶层文件定义了一个 ext
变量,其中包含像这样的通用库版本:
plugins {
id("java")
}
ext.libraries = [ shared: "xyz.abc.def:art:1.2" ]
有两个子项目,一个使用 Groovy DSL,一个使用 Kotlin DSL。他们都试图声明对 libraries.shared
.
╰─➤ cat groovy/build.gradle
plugins {
id("java")
}
dependencies {
implementation(libraries.shared)
}
╰─➤ cat kts/build.gradle.kts
plugins {
id("java")
}
dependencies {
implementation(libraries.shared)
}
settings.gradle
包括两个项目。
╰─➤ cat settings.gradle
include "groovy"
include "kts"
当我 运行 ./gradlew projects
我得到这个错误:
Line 6: implementation(libraries.shared)
^ Unresolved reference: libraries
当 kts
子项目的包含被注释掉时它成功,显示 groovy
子项目。
我已经尝试了很多不同的东西来引用 libraries
,例如 project.extra
或 extra
,但到目前为止还没有找到任何有效的方法。
编辑:
在 Gradle API 文档中仔细研究后,我想到了这个,它有效但绝对可怕。
implementation((project.getParent()!!.extra.properties["libraries"]!! as HashMap<String, String>).get("shared")!!);
您可以在 kotlin 脚本中使用它
plugins {
java
}
val libraries: Map<String, String> by rootProject.extra
repositories {
mavenCentral()
}
dependencies {
implementation(libraries["shared"]!!)
}
编辑
如果您使用的是 Gradle 的当前(在撰写本文时为 7)版本,您可以尝试新版本的目录功能——在撰写本文时它处于预览状态,因此可能是道路坎坷...
为此,您可以从根项目中删除 ext.libraries
,并在 settings.gradle
enableFeaturePreview('VERSION_CATALOGS')
dependencyResolutionManagement {
versionCatalogs {
libs {
alias('shared').to('com.bloidonia:ascii-image:1.1')
}
}
}
然后在 Groovy 和 Kotlin DSL 构建脚本中,您可以通过以下方式引用这些依赖项:
implementation(libs.shared)
编辑 2 -- 喝咖啡后
啊哈,所以我认为这回答了 Jeff 在评论中的问题,并显示了替代方案
是的,我们可以像这样在根项目中添加一个 ext 函数:
ext.libraries = [ shared: "com.bloidonia:ascii-image:1.1" ]
ext.library = { String name ->
ext.libraries."$name"
}
然后在Kotlin项目中,我们可以做:
val library: groovy.lang.Closure<String> by rootProject.extra
dependencies {
implementation(library("shared"))
}