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

Gradle技术问题:如何在任务配置中引用另一任务的输入?

在Gradle任务配置中引用另一个任务的输入

问题简述

我想在Gradle任务的配置过程中,引用另一个任务的输入值,让两个任务使用相同的输入内容。

已尝试的方案

我在/tmp/foo目录下编写了示例build.gradle文件,尝试让task2复用task1的输入:

task task1 {
    def myInput = projectDir // (or any other directory)
    inputs.dir(myInput).withPropertyName('t1Input')
    doLast {
        println myInput
    }
}

task task2 {
    dependsOn task1
    def myInput = task1.inputs.properties['t1Input']
    inputs.dir(myInput).withPropertyName('t2Input')
    doLast {
        println myInput
    }
}

执行命令./gradlew --console=verbose --warning-mode=all task2后,出现了如下报错:

> Task :task1
/tmp/foo

> Task :task2
A problem was found with the configuration of task ':task2'.
Registering invalid inputs and outputs via TaskInputs and TaskOutputs methods has been deprecated and is scheduled to be removed in Gradle 5.0.
- No value has been specified for property 't2Input'.
null

看起来通过task1.inputs.properties['t1Input']无法获取到task1中定义的输入属性,我使用的是Gradle 4.6版本。


解决方案

方法1:抽离共享变量

最简单直接的方式是把输入值定义为项目级的共享变量,让两个任务直接引用这个变量,完全避免任务间的输入依赖:

// 把共享输入抽成项目级变量
def sharedInput = projectDir

task task1 {
    inputs.dir(sharedInput).withPropertyName('t1Input')
    doLast {
        println sharedInput
    }
}

task task2 {
    dependsOn task1
    inputs.dir(sharedInput).withPropertyName('t2Input')
    doLast {
        println sharedInput
    }
}

这种方式逻辑清晰,也降低了任务间的耦合度。

方法2:通过TaskInputs的文件集合获取

如果你确实需要从task1的输入中读取值,可以使用task1.inputs.files来访问——inputs.properties并不是获取自定义输入值的正确途径,它主要用于Gradle内部属性管理,而非你通过withPropertyName设置的友好标识。修改后的代码如下:

task task1 {
    def myInput = projectDir
    inputs.dir(myInput).withPropertyName('t1Input')
    doLast {
        println myInput
    }
}

task task2 {
    dependsOn task1
    // 因为我们知道输入是单个目录,所以用singleFile获取
    def myInput = task1.inputs.files.singleFile
    inputs.dir(myInput).withPropertyName('t2Input')
    doLast {
        println myInput
    }
}

如果task1有多个输入,可以遍历task1.inputs.files集合来获取全部内容。

方法3:给任务添加自定义属性

你也可以给task1添加一个自定义属性来存储输入值,让task2直接引用这个属性,这种方式的依赖关系更明确:

task task1 {
    // 给任务添加自定义属性存储输入值
    ext.myInput = projectDir
    inputs.dir(ext.myInput).withPropertyName('t1Input')
    doLast {
        println myInput
    }
}

task task2 {
    dependsOn task1
    def myInput = task1.myInput
    inputs.dir(myInput).withPropertyName('t2Input')
    doLast {
        println myInput
    }
}

原方案失败的原因

你之前用的task1.inputs.properties['t1Input']之所以返回null,是因为inputs.properties这个Map并不是用来存储你通过withPropertyName设置的标识的。withPropertyName的作用只是在Gradle的增量构建报告、错误提示中给输入一个易读的名称,而非作为键来访问输入值。再加上在Gradle的配置阶段,task1的输入还未被完全解析,所以通过这种方式根本拿不到预期的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:45:23