13

我正在编写一个 gradle 构建文件,它将为我们的产品安装一个基本的开发域。基本上所有的真实代码都将在自定义插件和自定义任务中。涉及的几个步骤是相当重复的(多个 sudo 调用,多个用户添加),我想将常见的东西封装到一个任务中。

例如:

task('addDBUser', type:AddUser) {
    username = joeUser
}

task('startService', type:SudoExec) {
    workingDir = "not/too/relevant"
    commandLine = "/etc/init.d/coolService start"
}

我想尽可能整洁地重用 Exec 为我提供的各种功能(stdin、stdout 等),同时自动提供样板文件(“sudo ...”)。我很确定我可以扩展 Exec 而不是 DefaultTask,但我不知道触发实际操作的标准方式。用我需要的东西修改 commandLine 属性似乎很容易,但是当我希望 Exec 实际运行时,没有通用的“run()”或类似的东西可以使用。

我是否打开 Exec 来确定哪个方法是它的工作方法,然后直接调用它?还是有更通用的方法来实现我的目标?

4

2 回答 2

15

要查看为任务执行的方法,您可以检查源Exec并搜索标有 的方法@TaskAction。事实证明,这是exec()方法,但通常您不想手动调用任务操作,而是让 Gradle 为您完成。我认为最好的想法是将方法/设置器添加到您的自定义任务中。它可能看起来像这样:

task addUser(type: AddUser) {
    username = 'fromGradle'
}


class SudoExec extends Exec {

    void sudoCommand(Object... arguments) {
        executable 'sudo'
        args = arguments.toList()
    }
}

class AddUser extends SudoExec {

    void setUsername(String username) {
        sudoCommand('useradd', username)
    }
}
于 2013-04-20T12:55:13.413 回答
1

此代码能够处理多个参数,因为它不挂钩任何特定参数的设置器,而是使用惰性 GString 评估。

task vagrantfile (type:Vagrantfile) {
    account 'vagrant'
    password 'vagrant'
}

class Vagrantfile extends Copy {
    String account
    String password

    def Vagrantfile() {
        from 'templates/'
        into 'build/'
        include 'Vagrantfile.ubuntu.tpl'
        rename {'Vagrantfile'}
        expand (account:"${->account}", password:"${->password}")
    }
}
于 2015-04-19T19:08:28.133 回答