6

我正在阅读 Gradle 并对它非常感兴趣,特别是因为(看起来)它允许在构建过程中引入继承。例如,如果我有一个可以打包并部署到 Google App Engine 实例和 Amazon EC2 实例的 Java Web 应用程序,我需要一个复杂的构建,它可以采用相同的 Java、XML、PROPERTIES、CSS 和图像文件并打包/将它们部署到 2 个完全不同的打包文件WAR中。

GAE 应用程序对它们的打包方式非常具体;EC2(几乎)只要求您符合 servlet 规范。通过从SDK 附带的脚本中运行update命令来“部署”GAE 应用程序;appcfg.shEC2 有自己的方式来部署应用程序。关键是,对于两个 PaaS 提供商来说,它们是非常不同的打包/部署过程:

public abstract class PackageTask {
    // ...
}

// Package my Eclipse project for deployment to GAE.
public class AppEnginePackageTask extends PackageTask {
    // ...
}

// Package my Eclipse project for deployment to EC2 instances.
public class AmazonPackageTask extends PackageTask {
    // ...
}

public abstract class DeployTask {
    // ...
}

// Deployment to GAE.
public class AppEngineDeployTask extends DeployTask {
    // ...
}

// Deployment to EC2.
public class AmazonDeployTask extends DeployTask {
    // ...
}

然后,我可能有一个myapp.gradle构建文件来模板化任务的构建顺序:

clean()
compile()
package()
deploy()

...不知何故,我可以配置/注入AppEnginePackageTask/AppEngineDeployTask代替package()/deploy()用于基于 GAE 的构建,或者我可以配置/注入AmazonPackageTask/AmazoneDeployTask到那些模板化任务中。同样,我不确定如何做到这一点(或者即使 Gradle可以做到这一点),但这就是我所追求的。

我的理解是 Gradle 可以做到这一点。Ant 也可能被迫拥有以这种方式工作的高度模块化、优雅的构建,但是基于 XML,它需要一些技巧,而像 Groovy 这样的基于 OOP 的语言使这种构建更加简洁和简单。

但是,我看到的所有 Gradle 任务示例都采用以下形式:

task package(dependsOn: 'compile') {
    // ...
}

task deploy(dependsOn: 'package') {
    // ...
}

所以我问:这些看起来/感觉像非 OOP 任务定义。我对 Gradle(及其 OOP 本质)的理解是否从根本上不正确?我在这里想念什么?我如何才能完成这些“可配置/可注入构建模板”和基于继承的任务的概念?提前致谢!

编辑我用“”重新标记了这个问题,groovy因为 Gradle buildscripts 是用 Groovy DSL 编写的,而碰巧是 Groovy 大师(说快 5 倍)的人也可能会插话,即使他们对此知之甚少摇篮。

4

1 回答 1

3

如此处所述,有简单任务和增强任务。后者更加灵活和强大。

以下示例与您所描述的不完全一样,re:injection,但它说明了 OOP。

这是示例 build.gradle 文件。它避免了“包”,因为这是 Java/Groovy 中的关键字。“build”目标取决于“compile”和“doPack”的一些风格,取决于名为“pkgTarget”的属性。

task compile << { 
    println "compiling..." 
}

task build() << {
}

build.dependsOn { 
    compile
}

build.dependsOn { 

    if (pkgTarget == "Amazon") {
        task doPack(type: AmazonPackageTask)
    } else if (pkgTarget == "Google") {
        task doPack(type: GooglePackageTask)
    } else {
        task doPack(type: MyPackageTask) 
    }
}

稍后在同一文件中定义任务。(根据文档,此代码可以进入“build src”目录):

// ----- 

class MyPackageTask extends DefaultTask {
    def init() { println 'common stuff' }
    @TaskAction
    def doPackage() {
        println 'hello from MyPackageTask'
    }
}

class AmazonPackageTask extends MyPackageTask {
    @TaskAction
    def doPackage() {
        init()
        println 'hello from AmazonPackageTask'
    }
}

class GooglePackageTask extends MyPackageTask {
    @TaskAction
    def doPackage() {
        init()
        println 'hello from GooglePackageTask'
    }
}

这是 gradle.properties 文件:

pkgTarget=Amazon
于 2012-09-09T18:21:48.053 回答