java如何将我的Gradle插件中的任务执行链接到另一个插件的输出文件?
我正在尝试为Gradle编写一个插件,该插件将使用执行另一个任务(在另一个插件中定义)的文件结果执行一些操作。我可以通过任务类中的this.getProject().getTasks().getByName("distZip").getOutputs().getFiles().getSingleFile()
轻松获得所需的文件
但使用这种方法,无论文件在更高级别的任务中是否发生了更改,每次都会执行我的任务
我将getter方法注释为@InputFile
。但不幸的是,格雷德尔仍然没有将这个问题标记为^{
public class YcfPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getExtensions().create("ycf", YcfPluginExtension.class);
project.getPluginManager().apply("java-library-distribution");
project.getTasks().register("ycfCreateVersion", YcfTaskCreateVersion.class);
}
}
abstract class YcfTask extends DefaultTask {
public static final String TASK_GROUP = "Some Description";
YcfPluginExtension ycfExtension = this.getProject().getExtensions().getByType(YcfPluginExtension.class);
Logger logger = this.getProject().getLogger();
public YcfTask() {
this.setGroup(TASK_GROUP);
}
}
public class YcfTaskCreateVersion extends YcfTask {
private File fi;
public YcfTaskCreateVersion() {
this.setDescription("Some description");
this.dependsOn(this.getProject().getTasks().getByName("distZip"));
}
@InputFile
public File getFi() {
return this.getProject().getTasks().getByName("distZip").getOutputs().getFiles().getSingleFile();
}
@TaskAction
public void run() {
byte[] bytes = Files.readAllBytes(getFi().toPath());
//..do something with file content
}
}
# 1 楼答案
你目前的做法有一些误解:
应该在getter方法上使用
@InputFile
注释。getter方法不仅仅是以前缀get
开头的方法。通常,它是一个返回(私有)字段值的方法。在您的示例中,有一个名为fi
的字段,因此相应的getter方法getFi
应该只返回该字段的值。顺便说一下,在您当前的代码中,fi
字段根本没有使用很好,您知道应该使用什么值作为任务的输入(
getProject().getTasks().getByName("distZip").getOutputs().getFiles().getSingleFile()
),但这不应该是任务类型实现的一部分。相反,任务类型应该尽可能可配置。然后,您可以在插件代码中创建并配置此任务类型的一个实例:遗憾的是,上面的代码无法工作,因为在创建任务时(应用插件时),任务
distZip
(甚至可能是任务)的输出将不可用。但这不是一个大问题,因为Gradle支持这个用例。您可以将字段的类型更改为Object
,这样不仅可以传入File
类型的对象。任务执行时,将检查是否传递了文件(或可能转换为文件的内容)这个设置有一个很酷的地方:你可以直接传递任务
distZip
,Gradle会自动提取文件输出。它甚至会检测到您正在使用一个任务的输出作为另一个任务的输入,因此Gradle会自动设置两个任务之间的任务依赖关系,您不必再使用dependsOn
:让我们检查一下Gradle documentation on task outcomes。有一节是关于
UP-TO-DATE
:正如您所见,您的任务需要定义最新的输出。可以用与输入文件相同的方式定义输出文件(字段、getter with
@OutputFile
和setter)。它们应该是可配置的,默认为build
目录中的文件。或者,您可以使用onlyIf
来实现一个自定义检查,检查是否应该运行该任务。如果onlyIf
内的谓词返回false
,则任务将是SKIPPED