我真的很想欣赏 Gradle 5,尤其是与新的 Kotlin DSL 结合使用,但我很难(在我看来)使用 Gradle 运行一个非常非常简单和通用的构建。
发布一个 Java 库,其中包含 Maven 默认目录布局中的多个相互依赖的子模块 作为高质量的 Maven Artifact/存储库 -point,简单的 Gradle 构建(即 DRY)。
因此:有一个根项目作为保护伞,它定义并包含所有通用配置(实际上除了真正的依赖项之外的所有配置)。
我将当前的“结果”移植到 a sample project on Github和 asked this question in the Gradle forum already .
目前,我未能声明在我的中央构建中提供标准-sources 和-javadoc Artifact 的必要任务。
例如,在多模块场景中,您在寻找基于 Kotlin DSL 的解决方案时会发现这三个“解决方案”都不再(不再)工作:
/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.ktsgroup = "de.bentolor.sampleproject.module2"
dependencies {
compile(project(":module1"))
}
最佳答案
试试这个:
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)
}
}
}
}
一些注意事项:
String 的 apply ,当你可以做一个类型安全的 apply<T>() 时?dependencies 中对 stings 使用调用,当您可以使用委托(delegate)时,委托(delegate)更少且可重构性更好。implementation instead of compile 为什么 sourceSets 在多模块项目中不起作用?
当您使用 Kotlin DSL 时,它会根据应用的插件为项目生成访问器。这是一个两步过程:首先 Gradle 处理插件(这就是为什么建议将它们放在 plugins block 中)并生成访问器,然后您可以在代码中使用它们(访问器生成为 Project 、 NamedDomainObjectContainer 等的 Kotlin 扩展) .但是,如果您正在配置子项目,则存在两个问题:
sourceSets 是 Kotlin DSL 为 child 生成的访问器之一。而且它在父级中不可用。您可以自己尝试一下:在 java 中只应用 subprojects 插件。 sourceSets 将在子构建脚本中可用,但在父脚本中不可用。
这也是为什么你可以在 child 中使用 java,但在父中配置时必须使用 configure<JavaPluginExtension>。
但是您可以使用委托(delegate)来获取域对象的引用,例如任务、源集、配置等。
关于java - Gradle 5 Kotlin DSL : Common Tasks & Maven Artifacts in multi-modules projects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53631780/