Gradle:从给定的任务中过滤并执行任务

Gradle: Filter and execute tasks from a given task

我想 运行 ./gradlew verifyProjectDebug 到 运行 验证任务的一个子集。

verifyProjectDebug 尝试提取项目中的任务子集并执行它们。

static def isValidTask(String name) {
    def isLint = name.matches("lint.*Debug")
    def isKtlint = name.matches("ktlint.*Debug.*Check")
    def isUnitTest = name.matches("test((?!Prod|Staging).)*DebugUnitTest")

    return (isLint || isKtlint || isUnitTest) && !name.contains("Prod")
}

task verifyProjectDebug() {
    group = "verification"
    description = "Runs lint, ktlint and tests for all debug non-production variants"

    doLast {
        getSubprojects()
                .collect { it.tasks }
                .flatten()
                .findAll { isValidTask(it.name) }
                .each { it.execute() }
    }
}

不幸的是,在任务上调用 .execute() 不会调用其依赖项,因此某些任务失败是因为未调用其依赖项。

gradle 有什么方法可以实现吗?非常感谢!

executeTaskclass的一个方法。您正试图绕过 Gradle 构建系统。执行任务不是简单的事情,也不是创建实例并调用execute。 Gradle 处理依赖注入、缓存、输入和输出处理,以及所有类型的东西。所以杠杆 Gradle.

1)

创建一个生命周期任务,它是您要执行的所有任务的父任务。

final def verifyProject = tasks.register("verifyProject")

生命周期任务是一个不做任何工作的任务,它只依赖于其他任务。

2)

您只能引用已经创建的任务。例如,在创建调试变体之前,您不能引用调试变体的 lint 任务。

在创建每个变体时对其进行处理,找到您要执行的所有任务并将它们连接到主任务。

android.applicationVariants.all {
    final def cappedVariantName = name.capitalize()

    // For every build variant that has build type "debug"...
    if (variant.buildType == "debug") {
        verifyProject.configure {
            dependsOn("lint$cappedVariantName")
            dependsOn("ktlint$cappedVariantName")
            dependsOn("test${cappedVariantName}UnitTest")
        }
    }
}

请验证您要执行的任务的名称。

现在您 运行 gradlew verifyProject 将执行此任务所依赖的所有任务。您负责依赖项。

如果您想在 Android 库模块中使用它,请将 android.applicationVariants 替换为 android.libraryVariants

代码在 Task Conviguration Avoidance 之后。这意味着您定义的任务不会被配置,除非您专门调用它们。这应该在 运行 构建时节省资源(CPU 和内存)。

3)

要为所有模块自动执行此操作,请选择以下一项或两项,并将其放入您的 根项目 build.gradle.

subprojects { project ->
    project.plugins.whenPluginAdded { plugin ->
        // For all libraries and only libraries:
        if (plugin instanceof com.android.build.gradle.LibraryPlugin) {
            project.android.libraryVariants.all { variant ->
                // See above.
            }
        }
        // For all apps and only apps:
        if (plugin instanceof com.android.build.gradle.AppPlugin) {
            project.android.applicationVariants.all { variant ->
                // See above.
            }
        }
    }
}

把它放在项目级别 gradle 文件中就可以了。

task verifyDebugProjects() {
    group = "verification"
    description = "Runs lint, ktlint and tests for all debug non-production variants"
}

static def isValidVerifyDebugTask(String name) {
    def isLint = name.matches("lint.*Debug")
    def isKtlint = name.matches("ktlint.*Debug.*Check")
    def isUnitTest = name.matches("test((?!Prod|Staging).)*DebugUnitTest")

    return (isLint || isKtlint || isUnitTest) && !name.contains("Prod")
}

gradle.projectsEvaluated {
    getSubprojects()
            .collect { it.tasks }
            .flatten()
            .findAll { isValidVerifyDebugTask(it.name) }
            .each { verifyDebugProjects.dependsOn it }
}