博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Gradle 1.12用户指南翻译——第五十九章. 组织构建逻辑
阅读量:7297 次
发布时间:2019-06-30

本文共 6484 字,大约阅读时间需要 21 分钟。

其他章节的翻译请参见:
http://blog.csdn.net/column/details/gradle-translation.html
翻译项目请关注Github上的地址:
https://github.com/msdx/gradledoc
本文翻译所在分支:
https://github.com/msdx/gradledoc/tree/1.12。
直接浏览双语版的文档请访问:
http://gradledoc.qiniudn.com/1.12/userguide/userguide.html。
另外,Android 手机用户可通过我写的一个程序浏览文档,带缓存功能的,目前0.6开发中版本兼容 Android 2.3以上系统,项目地址如下:
https://github.com/msdx/gradle-doc-apk
翻译不易,转载请注明本文在CSDN博客上的出处:

http://blog.csdn.net/maosidiaoxian/article/details/70880742

关于我对Gradle的翻译,以Github上的项目及http://gradledoc.qiniudn.com 上的文档为准。如发现翻译有误的地方,将首先在以上两个地方更新。因时间精力问题,博客中发表的译文基本不会同步修改。

另外,目前Gradle1.12版本的文档已经翻译完并进入校稿阶段,校稿的方式为到该项目https://github.com/msdx/gradledoc 提交issue或是pull request。校稿的结果不只是在此版本更新,也会用于改善Gradle下一版本(2.0)文档的翻译。

第五十九章. 组织构建逻辑

Gradle 提供了多种方式来组织你的构建逻辑。首先,你可以把你的构建逻辑直接放到一个任务的action闭包里。如果两个任务有相同的逻辑,你可以把这段逻辑抽取为一个方法。如果一个多项目构建中的多个项目有相同的逻辑,你可以把这个方法定义在父项目里。如果构建逻辑通过方法来正确建模比较复杂的话,你就要使用面向对象的模型了。[] 这对Gradle来说很简单。只需要把你的类放在一个确定的目录,Gradle会自动地对它们编译,并且把它们加入到你的构建脚本的classpath中。

下面是你可以组织你的构建逻辑的方法摘要:

  • POGOs。你可以直接在你的构建脚本中定义和使用普通的旧Groovy对象(POGOs)。别忘了构建脚本是用Groovy来写的,Groovy会向你提供许多优秀的方式来组织代码。

  • 。在一个多项目构建中,子项目会继承父项目的属性及方法。

  • 。在一个多项目构建中,一个项目(通常是根项目)可以把属性和方法注入到另一个项目中。

  • 。把你的构建的类的源码放到一个指定的目录中,然后Gradle会自动地编译它们,并把它们包含到你的构建脚本的classpath里。

  • 。Define common configuration in an external build, and apply the script to multiple projects, possibly across different builds.

  • 。把你的构建逻辑放到一个自定义任务中,然后在多个地方复用这个任务。

  • 。把你的构建逻辑放到一个自定义插件中,然后在多个项目应用这个插件 。这个插件必须在你的构建脚本的classpath中。你可以通过使用,或者是添加一个包含了该插件的,来获得这个插件。

  • 。从当前的构建中执行另一个Gradle构建。

  • 。直接在你的构架文件中使用外部libraries。

59.1. 继承的属性和方法

任何定义在一个项目的构建脚本中的属性和方法,对于它的所有子项目都是可见的。你可以通过这个方法去定义共同的配置,然后把构建逻辑抽取到可以被子项目重用的方法里。

示例59.1. 使用继承的属性和方法

build.gradle

srcDirName = 'src/java'def getSrcDir(project) {    return project.file(srcDirName)}

child/build.gradle

task show << {    // Use inherited property    println 'srcDirName: ' + srcDirName    // Use inherited method    File srcDir = getSrcDir(project)    println 'srcDir: ' + rootProject.relativePath(srcDir)}

gradle -q show 的输出结果

> gradle -q showsrcDirName: src/javasrcDir: child/src/java

59.2. 注入配置

你可以使用在 和 所论述的配置注入技术,来向不同的项目注入属性和方法。通常来说,它是比继承更好的选择,有好几个原因:注入是显示地存在于构建脚本中的,你可以向不同的项目注入不同的逻辑,并且你可以注入任意一种配置,例如仓库,插件,任务等等。下面是展示注入的例子。

示例59.2. 使用注入的属性和方法

build.gradle

subprojects {    // Inject a property and method    srcDirName = 'src/java'    srcDir = { file(srcDirName) }    // Inject a task    task show << {        println 'project: ' + project.path        println 'srcDirName: ' + srcDirName        File srcDir = srcDir()        println 'srcDir: ' + rootProject.relativePath(srcDir)    }}// Inject special case configuration into a particular projectproject(':child2') {    srcDirName = "$srcDirName/legacy"}

child1/build.gradle

// Use injected property and method. Here, we override the injected valuesrcDirName = 'java'def dir = srcDir()

gradle -q show 的输出结果

> gradle -q showproject: :child1srcDirName: javasrcDir: child1/javaproject: :child2srcDirName: src/java/legacysrcDir: child2/src/java/legacy

59.3. 在buildSrc 项目中的构建源代码

当你运行Gradle时,它会检查buildSrc目录是否存在。然后Gradle会自动的编译和测试它的代码,并且把它们加入到你的构建脚本的classpath中。你不需要再提供任何进一步的指示。这可以是用于添加你的自定义任务和插件的好地方。

对于多项目构建,它们可能只有一个buildSrc目录,在根项目的目录中。

下面列出的是Gradle应用到 buildSrc 项目的默认构建脚本。

图 59.1. 默认的buildSrc构建脚本

apply plugin: 'groovy'dependencies {    compile gradleApi()    compile localGroovy()}

这意味着你可以只把你的构建源代码放到这个目录当中,并且保留一个 Java/Groovy 项目的约定布局(见)。

如果你需要更多的灵活性,你可以提供你自己的build.gradle。Gradle配置了一个默认的构建脚本,无论是否有脚本被指定。这意味着,你只需声明你所需要的额外的东西。下面是一个例子。请注意,此示例不需要声明对 Gradle API的依赖,因为这由默认的构建脚本完成:

示例 59.3. 自定义buildSrc构建脚本

buildSrc/build.gradle

repositories {    mavenCentral()}dependencies {    testCompile 'junit:junit:4.11'}

The buildSrc project can be a multi-project build. 这就像其他常规的Gradle多项目构建。但是,你需要使你想要的所有项目在buildSrc的根项目的实际构建runtime依赖的classpath上。 你可以通过把它添加到每一个你想导出的项目的配置上来完成:

示例 59.4. 将子项目添加到根 buildSrc 项目

buildSrc/build.gradle

rootProject.dependencies {  runtime project(path)}

注意: 此例子的代码可以在Gradle的二进制文件或源码中的 samples/multiProjectBuildSrc 里看到。

59.4. 从一个构建中运行另一个Gradle构建

你可以使用 任务。你可以通过使用 dir 或 buildFile 属性来指定执行哪一个构建,以及使用 tasks 属性来指定执行哪一个任务。

示例 59.5. 从一个构建运行另一个构建

build.gradle

task build(type: GradleBuild) {    buildFile = 'other.gradle'    tasks = ['hello']}

other.gradle

task hello << {    println "hello from the other build."}

gradle -q build的输出结果

> gradle -q buildhello from the other build.

59.5. 构建脚本的外部依赖

如果你的构建脚本需要使用一些外部库,你可以在这个构建脚本的把它们添加到该脚本的classpath中。你可以通过使用buildscript()方法,传入一个定义构建脚本classpath的闭包。

示例 59.6. 声明构建脚本的外部依赖

build.gradle

buildscript {    repositories {        mavenCentral()    }    dependencies {        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'    }}

这个传给buildscript() 方法的闭包配置了一个 实例。你可以通过添加依赖到classpath 配置来定义构建脚本的classpath。这和你定义Java编译classpath是同样的。你可以使用在 描述的除了项目依赖之外的任何依赖类型。

声明了构建脚本的classpath之后,你可以使用构建脚本中的类,就像classpath上的任何其他类一样。下面的示例将添加到前面的示例中,并使用构建脚本classpath中的类。

示例 59.7. 具有外部依赖的构建脚本

build.gradle

import org.apache.commons.codec.binary.Base64buildscript {    repositories {        mavenCentral()    }    dependencies {        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'    }}task encode << {    def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())    println new String(encodedString)}

gradle -q encode的输出结果

> gradle -q encodeaGVsbG8gd29ybGQK

对于多项目构建,定义在一个项目的构建脚本中的依赖,是可以在所有子项目的构建脚本中用的。

59.6. Ant 可选依赖

For reasons we don't fully understand yet, external dependencies are not picked up by Ant's optional tasks. 但是你可以很容易地通过另一种方法做到。[]

示例 59.8. Ant 的可选依赖

build.gradle

configurations {    ftpAntTask}dependencies {    ftpAntTask("org.apache.ant:ant-commons-net:1.9.3") {        module("commons-net:commons-net:1.4.1") {            dependencies "oro:oro:2.0.8:jar"        }    }}task ftp << {    ant {        taskdef(name: 'ftp',                classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',                classpath: configurations.ftpAntTask.asPath)        ftp(server: "ftp.apache.org", userid: "anonymous", password: "me@myorg.com") {            fileset(dir: "htdocs/manual")        }    }}

这对于客户端模块的用法也是一个很好的例子。在这个用例中,针对 ant-commons-net 任务的Maven中央仓的POM没有提供正确的信息。

59.7. 总结

Gradle 提供了多种组织你的构建逻辑的方式。你可以选择最适合你的领域的方式,并在不必要的间界引用之间找到平衡,避免冗余和难以维护的代码库。It is our experience that even very complex custom build logic is rarely shared between different builds. Other build tools enforce a separation of this build logic into a separate project. Gradle为你节省了这些不必要的开销和间接引用。


[] 这范围可能是从一个类到一些非常复杂的东西。

[] 事实上,我们认为这是更好的解决方案。仅当你的构建脚本和Ant的可选任务需要相同的 library时,你才需要定义它两次。在这种情况下,如果Ant 的可选任务会自动地获取在 gradesettings中定义的classpath,就很好。

你可能感兴趣的文章
Struts2配置文件【代码库】
查看>>
【火炉炼AI】机器学习007-用随机森林构建共享单车需求预测模型
查看>>
Base64编码及Android的应用
查看>>
ES6之---读懂let才能少踩坑
查看>>
Gradle 之 Android 中的应用
查看>>
String是一个很普通的类 - Java那些事儿
查看>>
Android Message解析
查看>>
什么是EOS(不一样的角度看柚子)
查看>>
LeetCode算法系列_0862_和至少为K的最短子数组
查看>>
响应式编程入门:实现电梯调度模拟器
查看>>
网络小黑揭秘系列之黑产江湖黑吃黑—中国菜刀的隐形把手
查看>>
Hacking PostgreSQL
查看>>
函数一致连续性的感性认识
查看>>
微信小程序填坑心路
查看>>
leetcode 58. Length of Last Word 题解【C++/Java/Python/JS】
查看>>
ArrayList分析
查看>>
图片加载之SDWebImage(上)
查看>>
android 打包出现错误Error: ResourceName
查看>>
ApacheCN 翻译活动进度公告 2019.2.18
查看>>
【刷算法】两个链表的第一个公共结点
查看>>