簡體   English   中英

Gradle 5 Kotlin DSL:多模塊項目中的常見任務和Maven工件

[英]Gradle 5 Kotlin DSL: Common Tasks & Maven Artifacts in multi-modules projects

我真的很想欣賞Gradle 5,特別是結合新的Kotlin DSL,但是我很難(在我看來)一個非常非常簡單和常見的構建與Gradle一起運行。

任務

在Maven默認目錄布局中將具有多個相互依賴的子模塊 的Java庫 作為高質量的Maven工件/存儲庫發布到一個簡單的Gradle構建(即DRY )中。

因此:將根項目作為傘來定義和包含所有常見配置(實際上除了真正的依賴項之外)。

我目前的掙扎

我將當前的“結果”移植到Github的示例項目中,已在Gradle論壇中提出此問題

目前,我沒有宣布在我的中心版本中提供標准-sources-javadoc工件的必要任務。

例如,在尋找基於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.kts

group = "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)
            }
        }
    }
}

幾點說明:

  • 為什么要使用基於Stringapply ,當你可以做一個類型安全的apply<T>()
  • 為什么在可以使用委托時使用對dependencies stings進行調用,這樣可以減少hacky和更好的可重構性。
  • 考慮使用implementation而不是compile

為什么sourceSets不能在多模塊項目中工作?

當您使用Kotlin DSL時,它會根據應用的插件為項目生成訪問器。 這是一個兩步過程:首先是Gradle處理插件(這就是為什么建議將它們放在plugins塊中)並生成訪問器,然后您可以在代碼中使用它們(訪問器生成為Project Kotlin擴展, NamedDomainObjectContainer等) 。 但是,如果您正在配置子項目,則有兩個問題:

  • 父項目在子項之前進行評估,因此父項中不知道子項的擴展名。
  • 應用於父級和子級的插件集是不同的,您需要在父級中使用子級訪問器。

sourceSets是Kotlin DSL為兒童生成的訪問者之一。 它只是在父母身上沒有。 您可以自己嘗試:在subprojects僅應用java插件。 sourceSets將在子構建腳本中提供,但不在父級中。

這也是您可以在子configure<JavaPluginExtension>使用java原因,但在父節點中配置它時必須使用configure<JavaPluginExtension>

但您可以使用委托來獲取域對象的引用,例如任務,源集,配置等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM