如何在内部使用sh脚本顺序执行gradle任务

时间:2019-02-08 10:45:06

标签: gradle

我有2个gradle任务,一个取决于另一个。

第一个任务使用sh脚本从远程服务器获取数据库转储。第二个任务解析先前任务的转储。

问题在于第二个任务比第一个任务完成的转储脚本开始得早。因此,当第二个任务开始工作时,还没有文件。

任务:

task getDumpFromRemotePostgres(type: Exec) {

    executable = "/bin/sh"
    println 'started task getDumpFromRemotePostgres'

    def dumpScript = './createSqliteDb/scripts/dump_db_script.sh'
    def dbDumpFileName = 'dump.sql'
    args += [dumpScript]

    println 'finished task getDumpFromRemotePostgres'       
}


task patchPostgresDumpFile(type: Exec) {
    dependsOn getDumpFromRemotePostgres

    executable = "/bin/sh"

    println 'started task patchPostgresDumpFile'

    def dbDumpFileName = 'dump.sql'
    File dumpFile = file(dbDumpFileName)
    def line
    dumpFile.withReader { reader ->
        while ((line = reader.readLine()) != null) {

       //parse and modify
    }

    println 'finished task patchPostgresDumpFile'
}

脚本:dump_db_script.sh:

echo "dump script started"

pg_dump --data-only --inserts --dbname=postgresql://user:pas@server/base_name > dump.sql

echo "dump script finished"

以下是控制台日志(如果我删除访问文件行):

started task getDumpFromRemotePostgres
finished task getDumpFromRemotePostgres
started task patchPostgresDumpFile
finished task patchPostgresDumpFile

> Task :getDumpFromRemotePostgres
dump script started
dump script finished

有什么办法解决问题吗?

尝试过doLast {...},但一无所获

1 个答案:

答案 0 :(得分:2)

看来,这全都归因于不同的生命周期阶段。您可以详细了解here

首先,当您创建类型为Exec或没有类型<<的任务时,其主体中的所有内容均为任务配置,并在构建的配置阶段执行。这就是为什么在输出中首先显示诸如started task getDumpFromRemotePostgres之类的消息的原因。

第二件事是您正在运行的可执行文件在所有任务的配置均已完成之后,在执行阶段执行。这就是为什么dump script started在完成所有配置后出现的原因。

在您的情况下,您不需要将patchPostgresDumpFile声明为Exec任务,因为您实际上没有调用任何可执行文件,但是需要运行一些逻辑。为此,您必须将此逻辑移至doLast闭包,以在执行阶段运行它。像这样:

task patchPostgresDumpFile() {
    dependsOn getDumpFromRemotePostgres

    doLast {
      println 'started task patchPostgresDumpFile'

        def dbDumpFileName = 'dump.sql'
        File dumpFile = file(dbDumpFileName)
        def line
        dumpFile.withReader { reader ->
            while ((line = reader.readLine()) != null) {

           //parse and modify
        }

        println 'finished task patchPostgresDumpFile'
    }

}

请注意,您的消息started task getDumpFromRemotePostgres实际上并不意味着此任务正在运行,而是正在配置。如果您希望在执行前后有一条消息,请将它们移至任务配置闭包中的doFirstdoLast闭包中。