我刚刚为数据库迁移测试了Flyway
,并对其功能和工作流程感到惊喜。
但是,有一个问题:Flyway
还可以执行clean
任务,从而有效地从您正在访问的架构中删除所有表和过程。
例如,这个子任务应该可以在开发环境中运行,但不能在生产环境中运行:有人可能会误解其含义并错误地杀死生产数据库。
是否可以禁用(或简单删除)插件的子任务?我可以这样做:
flywayClean {
enabled = project.hasProperty('devenv')
if(!enabled) {
throw new StopExecutionException("Disabled on production servers.")
}
}
但不幸的是,这会阻止构建完成。理想情况下,我想在专门运行任务时从另一个任务或命令行中抛出 only 这样的异常。
我可以使用Gradle执行此操作吗?
编辑:
发布问题后不久,我注意到flyway
配置选项还包含cleanDisabled
选项,可以完全按照我的意愿执行。因此,不必删除问题:如果插件本身没有这样的选项,这通常是可能的吗?
答案 0 :(得分:1)
Yes, each task in Gradle has a list of closures to be executed when the task is run. You can add any closure to the head of that list by adding a 'doFirst' closure.
Do not use the enabled variable but check directly on the property. Or else you will get
Cannot call Task.setEnabled(boolean) on task ':flywayClean' after task has started execution.
And throw a regular Exception if you want the complete run to fail, StopExecutionException will only stop the current task from executing the rest of the task closures with no error message.
flywayClean {
doFirst{
if(!project.hasProperty('devenv')) {
throw new Exception("Disabled on production ervers.")
}
}
}
Alternative:
Another way to do this is to skip the task based on condition. Here you can change the enabled variable since we have not started the task execution. Remember to print a reason to the user so he understands why the task is skipped.
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
}
}
}