You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle自定义UnitTestTask获取外部配置属性始终为null问题

问题根源

你遇到的问题是配置阶段执行顺序导致的:

  • 在插件中注册UnitTestTask时,属于Gradle配置阶段的早期逻辑,此时用户通过tasks.withType<UnitTestTask>设置variantsToExclude的代码还未执行,直接取variantsToExclude.orNull必然是null。
  • 同时你直接计算unitTestTasks并设置finalizedBy属于即时计算,后续variantsToExclude被赋值后,任务集合也不会更新。
解决方案:用Gradle懒加载API延迟任务集合计算

Gradle提供了Provider API实现懒加载,让任务集合的计算延迟到真正需要的时候(比如任务执行前、依赖解析时),此时variantsToExclude已经被用户配置赋值。

修改插件中的Task注册代码如下:

override fun apply(project: Project) {
    // 假设已定义以下常量
    val UNIT_TEST_TASK_NAME = "unitTestTask"
    val KOVER_REPORT_TASK_NAME = "koverXmlReport"

    project.tasks.register<UnitTestTask>(UNIT_TEST_TASK_NAME) { task ->
        // 用provider包装任务筛选逻辑,延迟执行
        val unitTestTasksProvider = project.provider {
            val variants = task.variantsToExclude.orNull
            project.allprojects.flatMap { subProject ->
                subProject.tasks.matching { subTask ->
                    if (variants?.isNotEmpty() == true) {
                        // Kotlin字符串中转义字符需双反斜杠,修正原正则的\b为\\b
                        subTask.name.matches("\\b(koverXmlReport\\w+)\\b".toRegex()) &&
                        variants.none { variant -> subTask.name.contains(variant) }
                    } else {
                        subTask.name == KOVER_REPORT_TASK_NAME
                    }
                }
            }
        }

        // 将懒加载的Provider传给finalizedBy,Gradle自动处理依赖
        finalizedBy(unitTestTasksProvider)

        // 打印逻辑移到任务执行前的doFirst阶段,确保拿到正确结果
        task.doFirst {
            val tasksToExecute = unitTestTasksProvider.get()
            println("tasks to execute: $tasksToExecute")
        }
    }
}
关键修改点说明
  1. 用project.provider包装逻辑:
    内部代码不会立即执行,只会在Gradle需要确定任务依赖或任务即将执行时运行,此时用户的variantsToExclude配置已生效。
  2. 修正正则转义问题:
    原代码中的"\b"会被解析为退格字符,必须改为"\\b"才能正确匹配单词边界。
  3. 打印逻辑移至doFirst:
    原println在配置阶段执行,无法拿到正确任务集合,移到doFirst可在任务执行前输出正确结果。
额外注意事项

确保用户的配置代码(tasks.withType<UnitTestTask>)在插件应用之后执行,通常用户的build.gradle.kts会先声明plugins { id("你的插件ID") }再配置任务,这个顺序无需调整。

内容的提问来源于stack exchange,提问作者Itoun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:55:18