Gradle自定义任务扩展Exec引发错误

问题描述

我的目的是通过在Gradle中创建自定义任务来运行docker save命令:

下面是我的build.gradle文件

class SaveTask extends Exec {
    @TaskAction
    void saveImage() {
        commandLine "bash","-c","docker save someimage:latest | gzip > someimage.tar.gz"
    }
}

// Create a task using the task type
task save(type: SaveTask)

运行任务时,出现以下错误

Execution Failed for task ':save'.
> execCommand == null!

有人可以建议我我要去哪里了吗

解决方法

您可能根本不需要创建自定义任务类型,只需将常规Exec任务类型用于任务save

task save(type: Exec) {
    commandLine "bash","-c","docker save someimage:latest | gzip > someimage.tar.gz"
}

您的方法失败的问题是Exec任务类型在内部定义了@TaskAction。该@TaskAction运行由commandLine定义的命令。在您的SaveTask任务类型中,定义了另一个@TaskAction,但它将在原始@TaskAction之后之后运行。这就是为什么commandLine对于原始@TaskAction仍然为空/空的原因。

如果您仍想创建自定义任务类型,例如因为您要定义一个将由多个任务使用的配置接口,所以请使用doFirst闭包来定义commandLine,因为它将在任何任务操作之前执行

class SaveTask extends Exec {
    String image

    SaveTask() {
        doFirst {
            commandLine "bash","docker save ${image} | gzip > someimage.tar.gz"
        }
    }
}

task saveImageA(type: SaveTask) {
    image = 'imageA:latest'
}

task saveImageB(type: SaveTask) {
    image = 'imageB:latest'
}
,

我修改了上面的代码,如下所示,它对我有用

class SaveTask extends Exec {
     

    SaveTask() {

            commandLine "bash","someimage:latest | gzip > someimage.tar.gz"

    }
}

task saveImageA(type: SaveTask)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...