Gradle tip #3-Task顺序

我注意到我在使用Gradle的时候遇到的大多数问题都是和task的执行顺序有关的。很明显如果我的构建会工作的更好如果我的task都是在正确的时候执行。下面我们就深入了解一下如何更改task的执行顺序。

dependsOn

我认为最直接的方式来说明的你task的执行时依赖别的task的方法就是使用dependsOn方法。 
比如下面的场景,已经存在task A,我们要添加一个task B,它的执行必须要在A执行完之后: 
B->A 
这是一个很简单的场景,假定A和B的定义如下:

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> A << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from A'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> B << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from B'</span>}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

只需要简单的调用B.dependsOn A,就可以了。 
这意味着,只要我执行task B,task A都会先执行。

<code class="language-shell hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>gradle <span class="hljs-constant" style="box-sizing: border-box;">B</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:A</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">A</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:B</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">B</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

另外,你也可以在task的配置区中来声明它的依赖:

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> A << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from A'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> B {
    dependsOn A
    doLast {
        println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from B'</span>  
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

如果我们想要在已经存在的task依赖中插入我们的task该怎么做呢? 
insert task 
过程和刚才类似。假定已经存在如下的task依赖:

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> A << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from A'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> B << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from B'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> C << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from C'</span>}

B.dependsOn A
C.dependsOn B</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

加入我们的新的task

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> B1 << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from B1'</span>}
B1.dependsOn B
C.dependsOn B1</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

输出:

<code class="language-shell hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>gradle <span class="hljs-constant" style="box-sizing: border-box;">C</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:A</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">A</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:B</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">B</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:B1</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">B1</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:C</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">C</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

注意dependsOn把task添加到依赖的集合中,所以依赖多个task是没有问题的。 
multi depends

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> B1 << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from B1'</span>}
B1.dependsOn B
B1.dependsOn Q</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

输出:

<code class="language-shell hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>gradle <span class="hljs-constant" style="box-sizing: border-box;">B1</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:A</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">A</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:B</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">B</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:Q</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">Q</span>
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:B1</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">B1</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

mustRunAfter

现在假定我又一个task,它依赖于其他两个task。这里我使用一个真实的场景,我有两个task,一个单元测试的task,一个是UI测试的task。另外还有一个task是跑所有的测试的,它依赖于前面的两个task。 
all tests

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> unit << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from unit tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> ui << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from UI tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> tests << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from all tests!'</span>}

tests.dependsOn unit
tests.dependsOn ui</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

输出:

<code class="language-shell hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka$ gradle tests
:ui
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> UI tests
:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unit</span>
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unit</span> tests
:tests
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> all tests!</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

尽管unitest和UI test会子啊test task之前执行,但是unit和ui这两个task的执行顺序是不能保证的。虽然现在来看是按照字母表的顺序执行,但这是依赖于Gradle的实现的,你的代码中绝对不能依赖这种顺序。 
由于UI测试时间远比unit test时间长,因此我希望unit test先执行。一个解决办法就是让ui task依赖于unit task。 
ui->unit

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> unit << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from unit tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> ui << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from UI tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> tests << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from all tests!'</span>}

tests.dependsOn unit
tests.dependsOn ui
ui.dependsOn unit <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// <-- I added this dependency</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

输出:

<code class="language-shell hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka$ gradle tests
:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unit</span>
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unit</span> tests
:ui
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> UI tests
:tests
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> all tests!</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

现在unit test会在ui test之前执行了。 
但是这里有个很恶心的问题,我的ui测试其实并不依赖于unit test。我希望能够单独的执行ui test,但是这里每次我执行ui test,都会先执行unit test。 
这里就要用到mustRunAfter了。mustRunAfter并不会添加依赖,它只是告诉Gradle执行的优先级如果两个task同时存在。比如我们这里就可以指定ui.mustRunAfter unit,这样如果ui task和unit task同时存在,Gradle会先执行unit test,而如果只执行gradle ui,并不会去执行unit task。

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> unit << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from unit tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> ui << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from UI tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> tests << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from all tests!'</span>}

tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

输出:

<code class="language-groovy hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka$ gradle tests
:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unit</span>
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unit</span> tests
:ui
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> UI tests
:tests
Hello <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> all tests!</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

依赖关系如下图: 
mustRunAfter

mustRunAfter在Gradle2.4中目前还是实验性的功能。

finalizedBy

现在我们已经有两个task,unit和ui,假定这两个task都会输出测试报告,现在我想把这两个测试报告合并成一个: 
merge

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> unit << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from unit tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> ui << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from UI tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> tests << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from all tests!'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> mergeReports << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Merging test reports'</span>}

tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit
mergeReports.dependsOn tests</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

现在如果我想获得ui和unit的测试报告,执行task mergeReports就可以了。

<code class="language-shell hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>gradle mergeReports
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:unit</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from unit tests
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:ui</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">UI</span> tests
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:tests</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from all tests!
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:mergeReports</span>
<span class="hljs-constant" style="box-sizing: border-box;">Merging</span> test reports</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

这个task是能工作,但是看起来好笨啊。mergeReports从用户的角度来看感觉不是特别好。我希望执行tests task就可以获得测试报告,而不必知道mergeReports的存在。当然我可以把merge的逻辑挪到tests task中,但我不想把tests task搞的太臃肿,我还是继续把merge的逻辑放在mergeReports task中。 
finalizeBy来救场了。顾名思义,finalizeBy就是在task执行完之后要执行的task。修改我们的脚本如下:

<code class="language-groovy hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> unit << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from unit tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> ui << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from UI tests'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> tests << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Hello from all tests!'</span>}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">task</span> mergeReports << {println <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Merging test reports'</span>}

tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit
mergeReports.dependsOn tests

tests.finalizedBy mergeReports</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

现在执行tests task就可以拿到测试报告了:

<code class="language-shell hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">paveldudka<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>gradle tests
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:unit</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from unit tests
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:ui</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from <span class="hljs-constant" style="box-sizing: border-box;">UI</span> tests
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:tests</span>
<span class="hljs-constant" style="box-sizing: border-box;">Hello</span> from all tests!
<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:mergeReports</span>
<span class="hljs-constant" style="box-sizing: border-box;">Merging</span> test reports</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

注意,finalizedBy也是Gradle2.4的实验性功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值