Gradle:根据环境或其他因素将插件子任务标记为不可运行 属性

Gradle: Mark a plugin subtask as non-runnable depending on environment or other property

我刚刚测试了 Flyway 数据库迁移,对其功能和工作流程感到惊喜。

但是,存在一个问题:Flyway 也可以执行一项 clean 任务,该任务有效地从您正在访问的架构中删除所有表和过程。

例如,此子任务应该 运行在开发环境中可用,但在生产环境中不可用:有人可能误解了它的含义并错误地杀死了生产数据库。

是否可以禁用(或简单地删除)插件的子任务?我可以这样做:

flywayClean {
    enabled = project.hasProperty('devenv')
    if(!enabled) {
        throw new StopExecutionException("Disabled on production servers.")
    }
}

但不幸的是,这会阻止构建完成。理想情况下,我想抛出这样的异常 only 当任务具体是 运行 时,无论是从另一个任务还是从命令行。

我可以用 Gradle 做这个吗?


编辑

发布问题后不久,我注意到 flyway 配置选项还包括一个 cleanDisabled 选项,它可以完全按照我的意愿执行。为了不必删除问题:如果插件本身没有这样的选项,这通常是可能的吗?

是的,Gradle中的每个任务都有一个闭包列表,当任务是运行时要执行。您可以通过添加 'doFirst' 闭包来将任何闭包添加到该列表的头部。

不要使用已启用的变量,而是直接检查 属性。否则你会得到

Cannot call Task.setEnabled(boolean) on task ':flywayClean' after task has started execution.

如果您希望整个 运行 失败,则抛出常规异常,StopExecutionException 只会停止当前任务执行其余的任务闭包,而不会出现错误消息。

flywayClean {
    doFirst{
        if(!project.hasProperty('devenv')) {
            throw new Exception("Disabled on production ervers.")
        }
    }
}

选择:

另一种方法是根据条件跳过任务。由于我们尚未开始执行任务,因此您可以在此处更改启用变量。请记住向用户打印原因,以便他了解为什么跳过该任务。

gradle.taskGraph.whenReady { taskGraph ->
    if (!project.hasProperty('devenv')){
        taskGraph.allTasks.find {it.name == 'flywayClean'}.each{
            println 'Disabling flywayClean due to missing property "devenv"'
            it.enabled = false
        }
    }
}