forked from DONGChuan/GradleUserGuide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
第15章仍有部分还未翻译
- Loading branch information
Showing
14 changed files
with
411 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
# More about Tasks | ||
# 深入了解 Tasks | ||
|
||
在这本教程的一开始 (第 6 章, 构建脚本基础) 你已经学习了如何创建简单的任务. 然后你也学习了如何给这些任务加入额外的行为, 如何在任务之间建立依赖关系. 这些都是对于简单的任务来说的. Gradle 可以创建更为强大复杂的任务. 这些任务可以有它们自己的属性和方法. 这一点正是和 Ant targets 不一样的地方. 这些强大的任务既可以由你自己创建也可以使用 Gradle 内建好的. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# 给 task 加入描述 | ||
|
||
你可以给你的任务加入一段描述性的文字. 它将会在任务执行的时候显示出来. | ||
|
||
**例子 15.18. 给任务加入描述** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
task copy(type: Copy) { | ||
description 'Copies the resource directory to the target directory.' | ||
from 'resources' | ||
into 'target' | ||
include('**/*.txt', '**/*.xml', '**/*.properties') | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# 给 task 加入依赖 | ||
|
||
有许多种加入依赖的方式. 在 6.5 小节, “任务依赖”里, 你已经学习了如何使用任务的名称定义依赖. 任务名称可以指向同一个项目里的任务, 或者其他项目里的任务. 为了指向其他项目, 你必须在任务的名称前加入项目的路径. 下面的例子给 projectA:taskX 加入依赖 projectB:taskY : | ||
|
||
**例子 15.11. 从另外一个项目给任务加入依赖** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
project('projectA') { | ||
task taskX(dependsOn: ':projectB:taskY') << { | ||
println 'taskX' | ||
} | ||
} | ||
project('projectB') { | ||
task taskY << { | ||
println 'taskY' | ||
} | ||
} | ||
``` | ||
|
||
**gradle -q taskX** 的输出 | ||
|
||
``` | ||
> gradle -q taskX | ||
taskY | ||
taskX | ||
``` | ||
|
||
除了使用任务名称, 你也可以定义一个依赖对象y: | ||
|
||
**例子 15.12. 通过任务对象加入依赖** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
task taskX << { | ||
println 'taskX' | ||
} | ||
task taskY << { | ||
println 'taskY' | ||
} | ||
taskX.dependsOn taskY | ||
``` | ||
|
||
**gradle -q taskX** 的输出 | ||
|
||
``` | ||
> gradle -q taskX | ||
taskY | ||
taskX | ||
``` | ||
|
||
更加先进的用法, 你可以通过闭包定义一个任务依赖. 闭包只能返回一个单独的 Task 或者 Task 对象的 collection, 这些返回的任务就将被当做依赖. 接下来的例子给 taskX 加入了一个复杂的依赖, 所有以 lib 开头的任务都将在 taskX 之前执行: | ||
|
||
**例子 15.13. 通过闭包加入依赖** | ||
|
||
**build.gradle** | ||
``` | ||
task taskX << { | ||
println 'taskX' | ||
} | ||
taskX.dependsOn { | ||
tasks.findAll { task -> task.name.startsWith('lib') } | ||
} | ||
task lib1 << { | ||
println 'lib1' | ||
} | ||
task lib2 << { | ||
println 'lib2' | ||
} | ||
task notALib << { | ||
println 'notALib' | ||
} | ||
``` | ||
|
||
**gradle -q taskX** 的输出 | ||
|
||
``` | ||
> gradle -q taskX | ||
lib1 | ||
lib2 | ||
taskX | ||
``` | ||
|
||
|
||
For more information about task dependencies, see the Task API. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# 配置 tasks | ||
|
||
举一个例子, 让我们看一看 Gradle 自带的 Copy task. 为了创建一个 Copy task, 你需要在你的构建脚本里先声明它: | ||
|
||
**例子 15.7. 创建一个 copy task** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
task myCopy(type: Copy) | ||
``` | ||
|
||
它创建了一个没有默认行为的 copy task. 这个 task 可以通过它的 API 来配置(参考 [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html)). 接下来例子展示了不同的实现方法. | ||
|
||
补充说明一下, 这个 task 的名字是 “myCopy”, 但是它是 “Copy” 类(type). 你可以有许多同样 type 不同名字的 tasks. 这个在实现特定类型的所有任务的 cross-cutting concerns 时特别有用. | ||
|
||
**例子 15.8. 配置一个任务 - 不同的方法** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
Copy myCopy = task(myCopy, type: Copy) | ||
myCopy.from 'resources' | ||
myCopy.into 'target' | ||
myCopy.include('**/*.txt', '**/*.xml', '**/*.properties') | ||
``` | ||
|
||
这个我们通过 Java 配置对象是一样的形式. 但是你每次都必须在语句里重复上下文 (myCopy). 这种方式可能读起来并不是那么的漂亮. | ||
|
||
下面一种方式就解决了这个问题. 是公认的最具可读性的方式. | ||
|
||
**例子 15.9. 配置一个任务 - 通过闭包 closure** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
task myCopy(type: Copy) | ||
myCopy { | ||
from 'resources' | ||
into 'target' | ||
include('**/*.txt', '**/*.xml', '**/*.properties') | ||
} | ||
``` | ||
|
||
上面例子里的第三行是 tasks.getByName() 方法的一个简洁的写法. 特别要注意的是, 如果你通过闭包的形式来实现 getByName() 方法, 这个闭包会在 task 配置的时候执行而不是在 task 运行的时候执行. | ||
|
||
你也可以直接在定义 task 时使用闭包. | ||
|
||
**例子 15.10. 通过定义一个任务** | ||
|
||
``` | ||
build.gradle | ||
task copy(type: Copy) { | ||
from 'resources' | ||
into 'target' | ||
include('**/*.txt', '**/*.xml', '**/*.properties') | ||
} | ||
``` | ||
|
||
请不要忘了构建的各个阶段. | ||
|
||
一个任务有配置和动作. 当使用 << 时, 你只是简单的使用捷径定义了动作. 定义在配置区域的代码只会在构建的配置阶段执行, 而且不论执行哪个任务. 可以参考第 55 章, The Build Lifecycle for more details about the build lifecycle. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# 定义 tasks | ||
|
||
我们已经在第 6 章学习了定义任务的形式. 这些出现了些小的变化来适应某些特殊的情况. 对比发现任务名被括号括起来了. 因为之前定义简单任务的形式在表达式里是不起作用的. | ||
|
||
**例子 15.1. 定义 tasks** | ||
|
||
**build.gradle** | ||
``` | ||
task(hello) << { | ||
println "hello" | ||
} | ||
task(copy, type: Copy) { | ||
from(file('srcDir')) | ||
into(buildDir) | ||
} | ||
``` | ||
你也可以使用 strings 来定义任务的名字: | ||
|
||
**例子 15.2. 例子 tasks - 使用 strings 来定义任务的名字** | ||
|
||
**build.gradle** | ||
``` | ||
task('hello') << | ||
{ | ||
println "hello" | ||
} | ||
task('copy', type: Copy) { | ||
from(file('srcDir')) | ||
into(buildDir) | ||
} | ||
``` | ||
|
||
还有另外一种语法形式来定义任务, 更加直观: | ||
|
||
**例子 15.3. 另外一种语法形式** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
tasks.create(name: 'hello') << { | ||
println "hello" | ||
} | ||
tasks.create(name: 'copy', type: Copy) { | ||
from(file('srcDir')) | ||
into(buildDir) | ||
} | ||
``` | ||
|
||
这里实际上我们把任务加入到 tasks collection 中. 可以看一看 [TaskContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskContainer.html) 来深入了解下. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# 定位 tasks | ||
|
||
你经常需要定位你定义的 tasks, 举个例子, 为了配置它们或者使用它们作为依赖. 有许多种方式都可以来实现定位. 首先, 每一个任务都必须是一个 project 的有效属性, 使用任务名来作为属性名: | ||
|
||
**例子 15.4. 通过属性获取 tasks** | ||
|
||
**build.gradle** | ||
``` | ||
task hello | ||
println hello.name | ||
println project.hello.name | ||
``` | ||
|
||
Tasks 也可以通过 tasks collection 来得到. | ||
|
||
**例子 15.5. 通过 tasks collection 获取 tasks** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
task hello | ||
println tasks.hello.name | ||
println tasks['hello'].name | ||
``` | ||
|
||
You can access tasks from any project using the task's path using the tasks.getByPath() method. You can call the getByPath() method with a task name, or a relative path, or an absolute path. | ||
|
||
**例子 15.6. 通过路径获取 tasks** | ||
|
||
**build.gradle** | ||
|
||
``` | ||
project(':projectA') { | ||
task hello | ||
} | ||
task hello | ||
println tasks.getByPath('hello').path | ||
println tasks.getByPath(':hello').path | ||
println tasks.getByPath('projectA:hello').path | ||
println tasks.getByPath(':projectA:hello').path | ||
``` | ||
|
||
**gradle -q hello** 的输出 | ||
|
||
``` | ||
> gradle -q hello | ||
:hello | ||
:hello | ||
:projectA:hello | ||
:projectA:hello | ||
``` | ||
参考 | ||
[TaskContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/TaskContainer.html) 可以知道跟多关于定位 tasks 的选项. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Ordering tasks | ||
|
||
Task ordering is an incubating feature. Please be aware that this feature may change in later Gradle versions. | ||
In some cases it is useful to control the order in which 2 tasks will execute, without introducing an explicit dependency between those tasks. The primary difference between a task ordering and a task dependency is that an ordering rule does not influence which tasks will be executed, only the order in which they will be executed. | ||
|
||
Task ordering can be useful in a number of scenarios: | ||
|
||
Enforce sequential ordering of tasks: eg. 'build' never runs before 'clean'. | ||
Run build validations early in the build: eg. validate I have the correct credentials before starting the work for a release build. | ||
Get feedback faster by running quick verification tasks before long verification tasks: eg. unit tests should run before integration tests. | ||
A task that aggregates the results of all tasks of a particular type: eg. test report task combines the outputs of all executed test tasks. | ||
There are two ordering rules available: “must run after” and “should run after”. | ||
|
||
When you use the “must run after” ordering rule you specify that taskB must always run after taskA, whenever both taskA and taskB will be run. This is expressed as taskB.mustRunAfter(taskA). The “should run after” ordering rule is similar but less strict as it will be ignored in two situations. Firstly if using that rule introduces an ordering cycle. Secondly when using parallel execution and all dependencies of a task have been satisfied apart from the “should run after” task, then this task will be run regardless of whether its “should run after” dependencies have been run or not. You should use “should run after” where the ordering is helpful but not strictly required. | ||
|
||
With these rules present it is still possible to execute taskA without taskB and vice-versa. | ||
|
||
Example 14.14. Adding a 'must run after' task ordering | ||
|
||
build.gradle | ||
task taskX << { | ||
println 'taskX' | ||
} | ||
task taskY << { | ||
println 'taskY' | ||
} | ||
taskY.mustRunAfter taskX | ||
Output of gradle -q taskY taskX | ||
> gradle -q taskY taskX | ||
taskX | ||
taskY | ||
Example 14.15. Adding a 'should run after' task ordering | ||
|
||
build.gradle | ||
task taskX << { | ||
println 'taskX' | ||
} | ||
task taskY << { | ||
println 'taskY' | ||
} | ||
taskY.shouldRunAfter taskX | ||
Output of gradle -q taskY taskX | ||
> gradle -q taskY taskX | ||
taskX | ||
taskY | ||
In the examples above, it is still possible to execute taskY without causing taskX to run: | ||
|
||
Example 14.16. Task ordering does not imply task execution | ||
|
||
Output of gradle -q taskY | ||
> gradle -q taskY | ||
taskY | ||
To specify a “must run after” or “should run after” ordering between 2 tasks, you use the Task.mustRunAfter() and Task.shouldRunAfter() methods. These methods accept a task instance, a task name or any other input accepted by Task.dependsOn(). | ||
|
||
Note that “B.mustRunAfter(A)” or “B.shouldRunAfter(A)” does not imply any execution dependency between the tasks: | ||
|
||
It is possible to execute tasks A and B independently. The ordering rule only has an effect when both tasks are scheduled for execution. | ||
When run with --continue, it is possible for B to execute in the event that A fails. | ||
As mentioned before, the “should run after” ordering rule will be ignored if it introduces an ordering cycle: | ||
|
||
Example 14.17. A 'should run after' task ordering is ignored if it introduces an ordering cycle | ||
|
||
build.gradle | ||
task taskX << { | ||
println 'taskX' | ||
} | ||
task taskY << { | ||
println 'taskY' | ||
} | ||
task taskZ << { | ||
println 'taskZ' | ||
} | ||
taskX.dependsOn taskY | ||
taskY.dependsOn taskZ | ||
taskZ.shouldRunAfter taskX | ||
Output of gradle -q taskX | ||
> gradle -q taskX | ||
taskZ | ||
taskY | ||
taskX |
Oops, something went wrong.