首页 > 解决方案 > Gradle:从根项目任务中的子项目读取变量块

问题描述

我一直在研究如何在少数子项目中定义变量块build.gradle.kts,并从根项目中定义的任务中读取这些块build.gradle.kts

子项目1build.gradle.kts

dependencies {
    "implementation"("dependency.one:dep-one-api")
    ...
}

additionalProjectSpecificVars {
    val additionalOptions = listOf<String>("option1", "option2", ...)
    val additionalLocations = listOf<String>("$projectDir/location1/...", "$projectDir/location2/...")
}

根项目build.gradle.kts

subprojects {
    if (project.name.endsWith("-wsdl")) {
        apply(plugin = "no.nils.wsdl2java")

        dependencies {
            ...
        }

        tasks.withType<no.nils.wsdl2java.Wsdl2JavaTask> {
            generatedWsdlDir = file("$projectDir/generatedsources")
            wsdlDir = file("$projectDir/wsdl")
            wsdlsToGenerate = gatherWsdlFiles()
        }
    }
}

fun Project.gatherWsdlFiles() : List<ArrayList<String>> {

    // 2-D Array
    var wsdlsToGenerateList = listOf<ArrayList<String>>()

    // Gather all the files in the WSDL directory
    val wsdlCollection = layout.files({
        file("$projectDir/wsdl").listFiles()
    })

    // Filter out only the .wsdl files
    val wsdlOnlyFiles: FileCollection = wsdlCollection.filter { file: File ->
        file.name.endsWith(".wsdl")
    }

    // Iterate the files collection and add the cxf-parameters
    wsdlOnlyFiles.forEach { wsdl: File ->

        val wsdlArray = listOf<String>(
                "-xjc-Xnamespace-prefix",
                "-xjc-XhashCode",
                "-xjc-Xequals",
                "-xjc-XtoString",
                wsdl.name)

        wsdlsToGenerateList.plus(wsdlArray)
    }


    // Read and add the other options from the subprojects 
    // additionalProjectSpecificVars block here and add to
    // wsdlsToGenerateList list


    return wsdlsToGenerateList
}

我已经尝试过project.ext,project.extragradle.ext,但这些似乎是如果您想读取已在 rootProject 中设置的属性,而不是相反。

Gradle v.6.2.2

标签: gradlekotlingradle-kotlin-dsl

解决方案


好的,所以我解决这个问题的方法是使用extra[]属性,但仅限于特定的构建阶段。

在我的根目录build.gradle.kts中,我更新了上述if语句以在项目评估步骤之后添加属性。如果我在这个阶段没有包括它们,它们就不存在。然后我将这三个值作为参数传递给我的gatherWsdlFiles()函数。

subprojects {
    if (project.name.endsWith("-wsdl")) {
        apply {
            plugin("no.nils.wsdl2java")
        }

        dependencies {
            ...

            "wsdl2java"("...")
        }

        wsdl2javaExt {
            deleteGeneratedSourcesOnClean = true
        }

        tasks.withType<no.nils.wsdl2java.Wsdl2JavaTask> {

            afterEvaluate {
                val wsdlLocations = extra["wsdlLocations"] as List<String>
                val wsdlBindings = extra["wsdlBindings"] as List<String>
                val wsdlAdditionalOptions = extra["wsdlAdditionalOptions"] as List<String>

                generatedWsdlDir = file("$projectDir/generatedsources")
                wsdlDir = file("$projectDir/wsdl")
                wsdlsToGenerate = gatherWsdlFiles(wsdlLocations, wsdlBindings, wsdlAdditionalOptions)
            }

            tasks.named("compileJava") {
                dependsOn("wsdl2java")
                sourceSets {
                    main {
                        java {
                            srcDirs(listOf("generatedsources"))
                        }
                    }
                }
            }
        }
    }
}

然后,在我的每个-wsdl子项目中,我将三个extra属性添加到build.gradle.kts文件中,每个属性都具有该项目的相关值。如果不需要值,那么我只是初始化了一个空列表。(使用emptyList()失败与Not enough information to infer type variable T

extra["wsdlLocations"] = listOf("$projectDir/wsdl/wsdl_1.wsdl")
extra["wsdlBindings"] = mutableListOf<String>()
extra["wsdlAdditionalOptions"] = listOf(
        "-p",
        "http://www.csapi.org/wsdl/blah.service",
        "-p",
        "http://www.csapi.org/wsdl/blah._interface")

dependencies {
    "implementation"("dependency.one:dep-one-api")
}

推荐阅读