使用Gradle Kotlin DSL在复合包含构建中模拟多项目执行?

使用Gradle Kotlin DSL在复合包含构建中模拟多项目执行?,gradle,kotlin,composite,gradle-kotlin-dsl,Gradle,Kotlin,Composite,Gradle Kotlin Dsl,我正在简化设置,我必须说明我的问题,但包括结构的复杂性 使用Gradle的Kotlin DSL,我有一个复合构建,其中根项目为空,包含的两个构建都是并行的多项目构建,具有不同的结构,使用“容器”项目(也称为空目录,没有build.Gradle.kts文件)进行组织 . ├── app │   ├── common │   │   └── build.gradle.kts │   ├── js │   │   └── build.gradle.kts │   ├── jvm │   │   └──

我正在简化设置,我必须说明我的问题,但包括结构的复杂性

使用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)中的根复合项目中运行build,它模仿多项目执行的行为,在多项目执行中,项目下的所有内容依次执行任务

在Groovy中,可以在复合项目中的includedBuilds*.tasks*上使用spread操作符将其连接起来,但在Kotlin DSL中,我们只能访问task,task是单个TaskReference,无法获取task集合(TaskCollection或TaskCollection)或TaskReference集合

因此,在composite 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文件中,我尝试了两种不同的方法(很多,但这是两种方法):

基本上,尝试上面的变体只能构建和清理包含的构建的根项目,而不是子项目。这是虫子吗


我不想求助于需要对所包含构建的底层结构的了解来将其连接起来。这是不可持续的。我做错了什么?

好吧,我不知道发生了什么,也不知道为什么其他方法不起作用,但我找到了一种有效的方法,不需要我制造依赖于生命周期任务的合成任务

复合rootproject build.gradle.kts任务与原始问题中所述的任务保持相同:

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-es中的任务声明需要以以下方式收集和依赖任务:

tasks {
    val buildAll: GradleBuild by creating {
        dependsOn(getTasksByName("build", true))
    }

    val cleanAll: Delete by creating {
        dependsOn(getTasksByName("clean", true))
    }
}

这将递归地收集任务。虽然我以前的迭代所有子项目的技术也应该做到这一点,因为子项目包含所有子项目,但出于某种原因,它不起作用。不过这是真的!希望这能帮助其他人。

我意识到我可能引用的生命周期任务不是以这种方式存在的?(我不知道如何检查)。为了排除这种情况,我继续为每个包含的构建的subprojects{}块中的每个子项目创建了一个任务。随后,我让rootproject build/cleanall任务分别依赖于所有子项目任务。然后它给了我一个循环依赖性问题,引用:rootinclude:build循环依赖于:rootinclude:build。当我尝试在getByPath中使用绝对路径时,它告诉我项目不存在(并显示它正在相对地查找)。几乎是在按路径获取任务时,最初它将/仅/接受相对路径(我尝试了所有我能想到的方法,以防出现用户错误),然后在dependsOn中验证或使用它进行查找时,它实际上从包含的构建的根项目中执行所有操作。
tasks {
    val buildAll: GradleBuild by creating {
        dependsOn(getTasksByName("build", true))
    }

    val cleanAll: Delete by creating {
        dependsOn(getTasksByName("clean", true))
    }
}