Java 如何将我的Gradle插件中的任务执行链接到另一个插件的输出文件?

Java 如何将我的Gradle插件中的任务执行链接到另一个插件的输出文件?,java,gradle,gradle-plugin,Java,Gradle,Gradle Plugin,我正在尝试为Gradle编写一个插件,该插件将使用执行另一个任务(在另一个插件-java库发行版中定义)的文件结果执行一些操作。我可以通过任务类中的this.getProject().getTasks().getByName(“distZip”).getOutputs().getFiles().getSingleFile()轻松获取所需的文件 但是使用这种方法,无论文件在更高级别的任务中是否发生了更改,每次都将执行我的任务 我将getter方法注释为@InputFile。但不幸的是,格雷德尔仍然

我正在尝试为Gradle编写一个插件,该插件将使用执行另一个任务(在另一个插件-
java库发行版中定义)的文件结果执行一些操作。我可以通过任务类中的this.getProject().getTasks().getByName(“distZip”).getOutputs().getFiles().getSingleFile()
轻松获取所需的文件

但是使用这种方法,无论文件在更高级别的任务中是否发生了更改,每次都将执行我的任务

我将getter方法注释为
@InputFile
。但不幸的是,格雷德尔仍然没有将这个问题标记为最新的

公共类YcfPlugin实现插件{
@凌驾
公开作废申请(项目){
创建(“ycf”,YcfPluginExtension.class);
getPluginManager().apply(“java库分发”);
project.getTasks().register(“ycfCreateVersion”,YcfTaskCreateVersion.class);
}
}
抽象类YcfTask扩展了DefaultTask{
public static final String TASK_GROUP=“Some Description”;
YcfPluginExtension ycfExtension=this.getProject().getExtensions().getByType(YcfPluginExtension.class);
Logger Logger=this.getProject().getLogger();
公共YCTASK(){
this.setGroup(任务组);
}
}
公共类YcfTaskCreateVersion扩展了YcfTask{
私有文件fi;
公共YcfTaskCreateVersion(){
此.setDescription(“某些描述”);
this.dependsOn(this.getProject().getTasks().getByName(“distZip”));
}
@输入文件
公共文件getFi(){
返回此.getProject().getTasks().getByName(“distZip”).getOutputs().getFiles().getSingleFile();
}
@任务行动
公开募捐{
byte[]bytes=Files.readAllBytes(getFi().toPath());
//…处理文件内容
}
}

您当前的方法中存在一些误解:

  • 应在getter方法上使用
    @InputFile
    注释。getter方法不仅仅是以前缀
    get
    开头的方法。通常,它是一个返回(私有)字段值的方法。在您的示例中,有一个名为
    fi
    的字段,因此相应的getter方法
    getFi
    应该只返回该字段的值。顺便说一下,在您当前的代码中,
    fi
    字段根本不用

  • 很好,您知道应该使用什么值作为任务的输入(
    getProject().getTasks().getByName(“distZip”).getOutputs().getFiles().getSingleFile()
    ),但这不应该是任务类型实现的一部分。相反,任务类型应尽可能可配置。然后,您可以在插件代码中创建并配置此任务类型的一个实例:

    public class YcfTaskCreateVersion extends YcfTask {
        private File fi;
    
        @InputFile
        public File getFi() {
            return fi;
        }
    
        public void setFi(File fi) {
            this.fi = fi;
        }
    
        @TaskAction
        public void run() {
            // ...
        }
    }
    
    public class YcfPlugin implements Plugin<Project> {
        @Override
        public void apply(Project project) {
            // ...
    
            YcfTaskCreateVersion createVersionTask = project.getTasks()
                .register("ycfCreateVersion", YcfTaskCreateVersion.class);
            createVersionTask.setFi(project.getTasks().getByName("distZip")
                .getOutputs().getFiles().getSingleFile());
        }
    }
    
    此设置有一个很酷的地方:您可以直接传递任务
    distZip
    ,Gradle将自动提取文件输出。它甚至会检测到您正在使用一个任务的输出作为另一个任务的输入,因此Gradle会自动设置两个任务之间的任务相关性,您不必再使用
    dependsOn

    createVersionTask.setFi(project.getTasks().getByName("distZip"));
    
  • 让我们检查一下。有一节介绍最新的

    任务的输出没有改变

    • 任务有输出和输入,它们没有改变。看
    • 任务有操作,但任务告诉Gradle它没有更改其输出
    • 任务没有操作和某些依赖项,但所有依赖项都是最新的、跳过的或来自缓存的。另见
    • 任务没有操作,也没有依赖项
    如您所见,您的任务需要定义被认为是最新的输出。您可以用与输入文件相同的方式定义输出文件(字段、getter with
    @OutputFile
    和setter)。它们应该是可配置的,默认为
    build
    目录中的文件。或者,您可以使用
    onlyIf
    执行自定义检查是否应运行任务。如果
    onlyIf
    中的谓词返回
    false
    ,则任务将被跳过


  • 请在您的问题中添加更多代码。特别是,您应该添加自定义任务类型的代码,以及如何在插件中创建此任务类型的任务实例。好的!我从我的项目中添加了一些代码示例OK,谢谢。现在了解如何在任务中使用输入依赖项。如果我的任务实际上没有输出,我不会说我完全理解该怎么做。这只是对外部API的调用,将接收到的归档文件作为InputFile发送。
    createVersionTask.setFi(project.getTasks().getByName("distZip"));