Gradle 5 Kotlin DSL:多模块项目中的常见任务和 Maven 工件
Posted
技术标签:
【中文标题】Gradle 5 Kotlin DSL:多模块项目中的常见任务和 Maven 工件【英文标题】:Gradle 5 Kotlin DSL: Common Tasks & Maven Artifacts in multi-modules projects 【发布时间】:2019-05-06 23:48:06 【问题描述】:我真的很想感谢 Gradle 5,尤其是与新的 Kotlin DSL 结合使用,但我很难(在我眼中)获得一个使用 Gradle 运行的非常、非常简单和通用的构建。
任务
发布一个 Java 库,其中包含 Maven 默认目录布局中的多个相互依赖的子模块作为高质量的 Maven 工件/存储库 -point,简单的 Gradle 构建(即 DRY)。
因此:有一个根项目作为定义 & 包含所有通用配置(实际上除了真正的依赖项之外的所有配置)的保护伞。
我目前的挣扎
我将当前的“结果”移植到 a sample project on Github 和 asked this question in the Gradle forum already。
目前,我未能声明在我的 central 构建中提供标准 -sources
和 -javadoc
工件的必要任务。
例如,您在寻找基于 Kotlin DSL 的解决方案时会发现这三个“解决方案”在多模块场景中都不起作用(不再):
https://***.com/a/48070667 https://***.com/a/52596969/1237653 甚至官方的"Maven Publish" documentation 也只能在单模块场景中工作。不完整的解决方案 (/build.gradle.kts
)
完整示例见 Github:https://github.com/bentolor/gradle-maven-multimodule-kotlindsl
subprojects
apply(plugin = "java-library")
apply(plugin = "maven-publish")
group = "de.bentolor.sampleproject"
version = "0.1.0"
repositories
jcenter()
dependencies
// Dependencies used in EVERY module
"compile"("commons-logging:commons-logging:1.2")
"testImplementation"("junit:junit:4.12")
tasks
// not working
/*register("sourcesJar", Jar::class.java)
from(sourceSets.main.get().allJava)
classifier = "sources"
*/
// not working, eiher
/* task<Jar>("sourcesJar")
from(sourceSets.main.get().allJava)
classifier = "sources"
*/
configure<JavaPluginExtension>
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
configure<PublishingExtension>
publications
create<MavenPublication>(project.name)
from(components["java"])
// won't work, beause inaccessible declaration in `tasks`-Block
//add("archives", javadocJar)
//add("archives", sourcesJar)
repositories
mavenLocal()
示例子模块/module2/build.gradle.kts
group = "de.bentolor.sampleproject.module2"
dependencies
compile(project(":module1"))
【问题讨论】:
【参考方案1】:试试这个:
subprojects
apply<JavaLibraryPlugin>()
apply<MavenPublishPlugin>()
group = "de.bentolor.sampleproject"
version = "0.1.0"
repositories
jcenter()
dependencies
val implementation by configurations
val testImplementation by configurations
implementation("commons-logging:commons-logging:1.2")
testImplementation("junit:junit:4.12")
// This will work, but as long as these tasks are need only for publishing you can declare them inplace later where you need
// tasks
// val sourcesJar by creating(Jar::class)
// val sourceSets: SourceSetContainer by project
// from(sourceSets["main"].allJava)
// classifier = "sources"
//
// val javadoc by getting(Javadoc::class)
// val javadocJar by creating(Jar::class)
// from(javadoc)
// classifier = "javadoc"
//
//
configure<JavaPluginExtension>
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
configure<PublishingExtension>
publications
create<MavenPublication>(project.name)
from(components["java"])
// If you configured them before
// val sourcesJar by tasks.getting(Jar::class)
// val javadocJar by tasks.getting(Jar::class)
val sourcesJar by tasks.creating(Jar::class)
val sourceSets: SourceSetContainer by project
from(sourceSets["main"].allJava)
classifier = "sources"
val javadocJar by tasks.creating(Jar::class)
from(tasks.get("javadoc"))
classifier = "javadoc"
artifact(sourcesJar)
artifact(javadocJar)
几点说明:
既然可以使用类型安全的apply<T>()
,为什么还要使用基于String
的apply
?
为什么要在 dependencies
中对 stings 使用调用,而您可以使用委托,这样可以减少 hacky 并更好地重构。
考虑使用implementation
instead of compile
为什么sourceSets
在多模块项目中不起作用?
当您使用 Kotlin DSL 时,它会根据应用的插件为项目生成访问器。这是一个两步过程:首先 Gradle 处理插件(这就是为什么建议将它们放在 plugins
块中)并生成访问器,然后您可以在代码中使用它们(访问器生成为 Project
的 Kotlin 扩展,@ 987654332@ 等)。但是如果你配置子项目有两个问题:
sourceSets
是 Kotlin DSL 为孩子生成的访问器之一。它只是在父母中不可用。您可以自己尝试:仅在subprojects
中应用java
插件。 sourceSets
将在子构建脚本中可用,但在父脚本中不可用。
这也是为什么您可以在子级中使用java
,但在父级中配置时必须使用configure<JavaPluginExtension>
。
但您可以使用委托来获取域对象的引用,例如任务、源集、配置等。
【讨论】:
以上是关于Gradle 5 Kotlin DSL:多模块项目中的常见任务和 Maven 工件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 gradle 5.0.0 中将 bootRepackage 任务转换为 kotlin DSL?
gradle kotlin dsl:如何创建使用插件类的共享函数?
如何将 Gradle 中的原生 JUnit 5 支持与 Kotlin DSL 结合使用?
isCoreLibraryDesugaringEnabled 在 gradle kotlin dsl / kts 中不起作用