我正在简化设置,我必须说明我的问题,但也包括了结构的复杂性。
使用 Gradle 的 Kotlin DSL 我有一个复合构建,其中根项目为空,并且两个包含的构建都是并行的多项目构建,具有不同的结构,这些结构利用“容器”项目(也称为空目录,没有build.gradle.kts 文件)用于组织目的。
.
├── app
│ ├── common
│ │ └── build.gradle.kts
│ ├── js
│ │ └── build.gradle.kts
│ ├── jvm
│ │ └── build.gradle.kts
│ ├── build.gradle.kts
│ └── settings.gradle.kts
├── library
│ ├── core
│ │ ├── common
│ │ │ └── build.gradle.kts
│ │ ├── js
│ │ │ └── build.gradle.kts
│ │ └── jvm
│ │ └── build.gradle.kts
│ ├── other-component
│ │ ├── common
│ │ │ └── build.gradle.kts
│ │ ├── js
│ │ │ └── build.gradle.kts
│ │ └── jvm
│ │ └── build.gradle.kts
│ ├── util
│ │ ├── util1
│ │ │ ├── common
│ │ │ │ └── build.gradle.kts
│ │ │ ├── js
│ │ │ │ └── build.gradle.kts
│ │ │ └── jvm
│ │ │ └── build.gradle.kts
│ │ └── util2
│ │ ├── common
│ │ │ └── build.gradle.kts
│ │ ├── js
│ │ │ └── build.gradle.kts
│ │ └── jvm
│ │ └── build.gradle.kts
│ ├── build.gradle.kts
│ └── settings.gradle.kts
├── build.gradle.kts
└── settings.gradle.kts
我的愿望是能够在 IDE (Intellij) 内的根复合项目中运行构建,并且它模仿多项目执行的行为,其中该项目下的所有内容依次执行任务。
在 Groovy 中,只需在复合项目中的includedBuilds*.tasks* 上使用扩展运算符即可将其连接起来,但在 Kotlin DSL 中,我们只能访问任务,这是一个单一的 TaskReference,无法访问获取任务集合(TaskCollection 或任务集合)或任务引用集合。
因此,在复合 build.gradle.kts 的 rootProject 中,我有:
tasks {
val clean by getting {
gradle.includedBuilds.forEach { this.dependsOn(it.task(":cleanAll")) }
}
val build by getting {
gradle.includedBuilds.forEach { this.dependsOn(it.task(":buildAll")) }
}
}
然后在其中一个包含的构建 build.gradle.kts 文件中,我尝试以两种不同的方式连接它们(很多,但这是两种方法):
// Variation 1
tasks {
val buildAll : GradleBuild by creating {
this.dependsOn(tasks.getByPath(":build"))
}
val cleanAll : Delete by creating {
this.dependsOn(tasks.getByPath(":clean"))
}
}
// Variation 2
tasks {
val buildAll: GradleBuild by creating {
subprojects.forEach {
this.dependsOn(it.tasks.getByPath(":build"))
}
}
val cleanAll: Delete by creating {
subprojects.forEach {
this.dependsOn(it.tasks.getByPath(":clean"))
}
}
}
// Variation 2.b
tasks {
val buildAll: GradleBuild by creating {
this.dependsOn(subprojects.mapNotNull(it.tasks.getByPath(":build")))
}
val cleanAll: Delete by creating {
this.dependsOn(subprojects.mapNotNull(it.tasks.getByPath(":clean")))
}
}
// I even used different ways to try and get the tasks such as it.tasks["root:library:build"], it.tasks[":library:build"], and it.tasks["library:build"] since I know that the included builds are executed in an isolated fashion. None of these worked
// The result was when I used absolute paths, gradle spat back that these tasks didn't exist (I assumed because they were lifecycle tasks).
基本上,尝试上述变体仅构建并清理了所包含构建的根项目,而不是子项目。这是一个错误吗?
我不想求助于所包含构建的底层结构的知识来连接它。那将是不可持续的。我做错了什么?
最佳答案
我使用以下代码来实现此目的。首先,创建一个settings.gradle.kts
在以编程方式搜索构建的根目录中包含:
rootDir.walk().filter {
it != rootDir && !it.name.startsWith(".") && it.resolve("build.gradle.kts").isFile
}.forEach(::includeBuild)
然后创建一个build.gradle.kts
根目录中的文件,“转发”所有形式 all<TASK>
的根任务调用至<INCLUDED_BUILD>:<TASK>
:
tasks.addRule("Pattern: all<TASK>") {
val taskName = this
val taskPrefix = "all"
if (startsWith(taskPrefix)) {
task(taskName) {
gradle.includedBuilds.forEach { build ->
val buildTaskName = taskName.removePrefix(taskPrefix).decapitalize()
dependsOn(build.task(":$buildTaskName"))
}
}
}
}
这样,运行./gradlew allAssemble
在根项目上将有效执行assemble
所有包含的构建上的任务。
关于gradle - 使用 Gradle Kotlin DSL 在复合包含构建中模拟多项目执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51756055/