第6章 构建脚本基础(6.6-6.14)
6.6动态任务
Groovy不仅仅能够定义一个任务做什么,例如,它也能够动态的创建任务。
例子6.8任务的动态定义
build.gradle
4.times { counter -> task "task$counter" << { println "I'm task number $counter" }}
使用gradle -q task1 ,输出如下:
> gradle -q task1
I'm task number 1
6.7操作存在的任务
一旦任务被创建,它就可以通过api来访问,这是与Ant不同的,如,创建额外的依赖。
例子6.9通过API访问任务--增加依赖
build.gradle
4.times { counter -> task "task$counter" << { println "I'm task number $counter" }}task0.dependsOn task2, task3
> gradle -q task0
I'm task number 2
I'm task number 3
I'm task number 0
或者你可以为一个现存的任务添加行为
例子6.10通过API访问任务--增加行为
build.gradle
task hello << { println 'Hello Earth'}hello.doFirst { println 'Hello Venus'}hello.doLast { println 'Hello Mars'}hello << { println 'Hello Jupiter'}
> gradle -q hello
Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
doFirst 和 doLast 可以被多次执行。它们在任务动作列表的开始和结束加入动作。当任务执行的时候, 在动作列表里的动作将被按顺序执行。 << 操作符仅仅是 doLast 的一个别名。
6.8快捷标记
正如你已经注意到了,在之前的例子中,有一个快捷标记来访问存在的任务,每一个任务都可以作为构建脚本的属性。
例子6.11将任务作为构建脚本的属性来访问
build.gradle
task hello << { println 'Hello world!'}hello.doLast { println "Greetings from the $hello.name task."}
> gradle -q hello
Hello world!
Greetings from the hello task.
这使代码很有可读性,特别是当使用了由插件(如编译)提供的任务时。
6.9附加任务属性
可以在给任务添加自定义属性,如添加一个叫myProperty的属性,然后给这个属性设置一个初始值,从这一点来看,该属性可以被读取和设置,就像一个预定义的属性一样。
例子6.12给任务添加附加属性
build.gradle
task myTask { ext.myProperty = "myValue"}task printTaskProperties << { println myTask.myProperty}
> gradle -q printTaskProperties
myValue
附加属性不只是限于任务,在13.4.2中将会了解到更多相关的内容。
6.10使用Ant任务
Ant任务是Gradle的一等公民。Gradle 通过 Groovy为Ant 任务提供了出色的集成。Groovy有很好的AntBuilder,在Gradle使用 Ant任务和在build.xml中使用一样的便利,甚至是更加强大。下面的例子,你可以学习如何去执行ant任务,以及如何访问ant属性。
例子6.13使用AntBuilder执行ant.loadfile目标
build.gradle
task loadfile << { def files = file('../antLoadfileResources').listFiles().sort() files.each {File file -> if(file.isFile()){ ant.loadfile(srcFile:file,property:file.name) println "*** $file.name ***" println "${ant.properties[file.name]}" } }}
> gradle -q loadfile
*** agile.manifesto.txt ***
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
*** gradle.manifesto.txt ***
Make the impossible possible, make the possible easy and make the easy elegant.
(inspired by Moshe Feldenkrais)
在build脚本中你可以用Ant脚本做很多事情。你将会在第17章中学习到更多相关内容。
6.11使用方法
Gradle可以衡量你组织构建逻辑的能力,第一个级别就是使用方法。
例子6.14使用方法来组织你的构建逻辑
build.gradle
task checksum <<{ fileList('../').each {File file -> ant.checksum(file:file,property:"cs_$file.name") println "$file.name Checksum: ${ant.properties["cs_$file.name"]}" }}task loadfile <<{ fileList("./").each {File file -> ant.loadfile(srcFile:file,property:file.name) println "i'm fond of $file.name" }}File[] fileList(String dir){ file(dir).listFiles({file->file.isFile()} as FileFilter).sort()}> gradle -q loadfile
I'm fond of agile.manifesto.txt
I'm fond of gradle.manifesto.txt
之后你将会看到,上面定义的那种方法能在多项目构建中被子项目共享,如果你的构建逻辑变得更加复杂,Gradle为你提供了非常便利的方式去组织你的构建逻辑。我们会用一整个章节去阐述“组织构建逻辑”这一主题。参考59章节。
6.12默认任务
Gradle允许为你的构建定义一个或多个默认任务。
例子6.15定义默认任务
build.gradle
defaultTasks 'clean' ,'run'task clean <<{ println "default cleaning"}task run <<{ println "default running"}task other<<{ println "other"}
> gradle -q
Default Cleaning!
Default Running!
上面的命令相当于“gradleclean run”,在多项目构建中,每个子项目可以有自己特有的默认任务,如果一个子项目没有指定其默认任务,它会使用其父项目的默认任务作为自己的默认任务。
6.13DAG配置
我们之后会详细描述(参考55章,构建的生命周期),gradle有配置阶段和执行阶段。在配置阶段之后,Gradle知道了应该被执行的所有任务,gradle提供了一个“钩子(hook)”去利用这些信息。一个用法就是,检查发布的任务时候在将要执行的任务之中,然后据此给某些变量赋不同的值。
在接下来的例子中,“distribution ”和“release”任务的执行会导致变量“version”具有不同的值。
例子6.16不同的结果取决于选择的任务
build.gradle
task distribution <<{ println "we build the zip with version=$version"}task release(dependsOn:'distribution')<<{ println 'we release now'}gradle.taskGraph.whenReady {taskGraph -> if(taskGraph.hasTask(release)){ version = '1.0' }else{ version='1.0-SNAPSHOT' }}
> gradle -q distribution
We build the zip with version=1.0-SNAPSHOT
> gradle -q release
We build the zip with version=1.0
We release now
重要的是,whenReady在release任务执行之前就已经影响了release任务,即使release不是首要任务。(首要任务指传递给gradle命令的任务)
6.14下一步去哪里
在这整个第六章节里,我们对任务进行了初探,这并不是任务的全部,如果你想要跳到更多的细节,请参见第15章节。