Gradle基礎:5:task的依賴與執行條件
在使用maven的時候,compile/test/install的先後順序和依賴關係都十分清晰,而在前面的例子中,可以通過gradle compile和gradle test來進行不同的任務執行,但是實際這些任務之間是有依賴關係的,就像我們在maven裡面執行mvn install之前會做什麼那樣,這篇文章會繼續來介紹task之間的依賴與執行條件。
示例介紹
這篇文章會通過對上文的例子進行重新改寫,來介紹gradle對於task操作的依賴和執行條件,還是如下4個任務:
事前準備
修改之前的程式碼示例如下所示,對前文中的task的<<使用方式進行了修改,以消除warning資訊
- 程式碼示例
liumiaocn:hello liumiao$ cat build.gradle println "[phase:configuration] build.gradle ..." task compile { group 'compile' description 'compile task' println "[phase:configuration] compile" doFirst { println "[phase:execution] compile :doFirst()" } } tasks.create(name: 'test') { group 'test' description 'test task' println "[phase:configuration] test" doLast { println "[phase:execution] test:doLast()" } } tasks.create("packaging") { group 'packaging' description 'packaging task' println "[phase:configuration] packaging" doLast { println "[phase:execution] packaging:doLast()" } } class Install extends DefaultTask{ String installObjectName @TaskAction void checkObject() { println "[phase:execution] install:checkObject (${installObjectName})" } @TaskAction void installObject() { println "[phase:execution] install:installObject (${installObjectName})" } } task install(type: Install) { group 'install' description 'install task' installObjectName 'test.jar' println "[phase:configuration] install" doFirst { println "[phase:execution] install:doFirst()" } doLast { println "[phase:execution] install:doLast()" } } liumiaocn:hello liumiao$
- 執行確認
liumiaocn:hello liumiao$ gradle compile test packaging install [Phase: initialization] : settings executed... > Configure project : [phase:configuration] build.gradle ... [phase:configuration] compile [phase:configuration] test [phase:configuration] packaging [phase:configuration] install > Task :compile [phase:execution] compile :doFirst() > Task :test [phase:execution] test:doLast() > Task :packaging [phase:execution] packaging:doLast() > Task :install [phase:execution] install:doFirst() [phase:execution] install:installObject (test.jar) [phase:execution] install:checkObject (test.jar) [phase:execution] install:doLast() BUILD SUCCESSFUL in 0s 4 actionable tasks: 4 executed liumiaocn:hello liumiao$
依賴設定
前面準備的例子有一個主要的問題,task之間的依賴關係實際是沒有的,上文顯示的執行順序實際是因為輸入的順序產生的,在gradle裡面也非常容易地通過dependsOn進行依賴關係的設定,這裡將常用的方式進行整理如下:
方式1: 通過()傳入
tasks.create(name: 'test',dependsOn: compile) {
group 'test'
description 'test task'
println "[phase:configuration] test"
doLast {
println "[phase:execution] test:doLast()"
}
}
執行結果確認資訊如下,可以看到test在執行時compile的任務被事先執行了
liumiaocn:hello liumiao$ gradle test
[Phase: initialization] : settings executed...
> Configure project :
[phase:configuration] build.gradle ...
[phase:configuration] compile
[phase:configuration] test
[phase:configuration] packaging
[phase:configuration] install
> Task :compile
[phase:execution] compile :doFirst()
> Task :test
[phase:execution] test:doLast()
BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
liumiaocn:hello liumiao$
方式2: 在{}中設定
{}中設定的是任務的配置程式碼或者執行階段程式碼的詳細資訊,在這裡可以進行設定,比如:
tasks.create("packaging") {
group 'packaging'
description 'packaging task'
dependsOn test
println "[phase:configuration] packaging"
doLast {
println "[phase:execution] packaging:doLast()"
}
}
執行結果確認資訊如下,注意由於test任務依賴於compile,所以在執行packaging的時候,會同時執行:
liumiaocn:hello liumiao$ gradle packaging
[Phase: initialization] : settings executed...
> Configure project :
[phase:configuration] build.gradle ...
[phase:configuration] compile
[phase:configuration] test
[phase:configuration] packaging
[phase:configuration] install
> Task :compile
[phase:execution] compile :doFirst()
> Task :test
[phase:execution] test:doLast()
> Task :packaging
[phase:execution] packaging:doLast()
BUILD SUCCESSFUL in 0s
3 actionable tasks: 3 executed
liumiaocn:hello liumiao$
方式3: 在{}外設定
當然也可以在{}進行指定,由於在{}之外,缺乏上下文,自然需要指定是誰依賴誰,而不是像前兩種方式那樣只需要設定依賴物件即可。
task install(type: Install) {
group 'install'
description 'install task'
installObjectName 'test.jar'
println "[phase:configuration] install"
doFirst {
println "[phase:execution] install:doFirst()"
}
doLast {
println "[phase:execution] install:doLast()"
}
}
install.dependsOn packaging
這樣執行起來,依賴關係就完整了。
liumiaocn:hello liumiao$ gradle install
[Phase: initialization] : settings executed...
> Configure project :
[phase:configuration] build.gradle ...
[phase:configuration] compile
[phase:configuration] test
[phase:configuration] packaging
[phase:configuration] install
> Task :compile
[phase:execution] compile :doFirst()
> Task :test
[phase:execution] test:doLast()
> Task :packaging
[phase:execution] packaging:doLast()
> Task :install
[phase:execution] install:doFirst()
[phase:execution] install:installObject (test.jar)
[phase:execution] install:checkObject (test.jar)
[phase:execution] install:doLast()
BUILD SUCCESSFUL in 0s
4 actionable tasks: 4 executed
liumiaocn:hello liumiao$
程式碼示例
liumiaocn:hello liumiao$ cat build.gradle
println "[phase:configuration] build.gradle ..."
task compile {
group 'compile'
description 'compile task'
println "[phase:configuration] compile"
doFirst {
println "[phase:execution] compile :doFirst()"
}
}
tasks.create(name: 'test',dependsOn: compile) {
group 'test'
description 'test task'
println "[phase:configuration] test"
doLast {
println "[phase:execution] test:doLast()"
}
}
tasks.create("packaging") {
group 'packaging'
description 'packaging task'
dependsOn test
println "[phase:configuration] packaging"
doLast {
println "[phase:execution] packaging:doLast()"
}
}
class Install extends DefaultTask{
String installObjectName
@TaskAction
void checkObject() {
println "[phase:execution] install:checkObject (${installObjectName})"
}
@TaskAction
void installObject() {
println "[phase:execution] install:installObject (${installObjectName})"
}
}
task install(type: Install) {
group 'install'
description 'install task'
installObjectName 'test.jar'
println "[phase:configuration] install"
doFirst {
println "[phase:execution] install:doFirst()"
}
doLast {
println "[phase:execution] install:doLast()"
}
}
install.dependsOn packaging
liumiaocn:hello liumiao$
enable屬性
在前文介紹task常用屬性和方法時,還提及到一個enable屬性,這裡通過示例來演示一下使用方式:
tasks.create("packaging") {
group 'packaging'
description 'packaging task'
dependsOn test
enabled false
println "[phase:configuration] packaging"
doLast {
println "[phase:execution] packaging:doLast()"
}
}
這樣執行起來,由於enabled被設定為false,執行的過程則被跳過了
雖然執行過程被跳過了,但是配置還是會執行的,這個需要注意一下。
liumiaocn:hello liumiao$ gradle install
[Phase: initialization] : settings executed...
> Configure project :
[phase:configuration] build.gradle ...
[phase:configuration] compile
[phase:configuration] test
[phase:configuration] packaging
[phase:configuration] install
> Task :compile
[phase:execution] compile :doFirst()
> Task :test
[phase:execution] test:doLast()
> Task :install
[phase:execution] install:doFirst()
[phase:execution] install:installObject (test.jar)
[phase:execution] install:checkObject (test.jar)
[phase:execution] install:doLast()
BUILD SUCCESSFUL in 0s
3 actionable tasks: 3 executed
liumiaocn:hello liumiao$
當然使用方式也有很多種,比如也可以使用packaging.enabled = false在{}外設定,這裡就不再贅述了。
onlyIf屬性
onlyIf屬性進行條件判斷,比如install任務根據packaging的enabled是否為true進行判斷當前install任務是否執行的時候,即可加上如下設定即可
install.onlyIf { packaging.enabled }
這樣在執行的時候,packaging的enabled如果是false的話,install也不會執行了
liumiaocn:hello liumiao$ gradle install
[Phase: initialization] : settings executed...
> Configure project :
[phase:configuration] build.gradle ...
[phase:configuration] compile
[phase:configuration] test
[phase:configuration] packaging
[phase:configuration] install
> Task :compile
[phase:execution] compile :doFirst()
> Task :test
[phase:execution] test:doLast()
BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
liumiaocn:hello liumiao$
程式碼示例
由於演示enabled和onlyIf屬性,程式碼略有變化,再次貼出如下:
liumiaocn:hello liumiao$ cat build.gradle
println "[phase:configuration] build.gradle ..."
task compile {
group 'compile'
description 'compile task'
println "[phase:configuration] compile"
doFirst {
println "[phase:execution] compile :doFirst()"
}
}
tasks.create(name: 'test',dependsOn: compile) {
group 'test'
description 'test task'
println "[phase:configuration] test"
doLast {
println "[phase:execution] test:doLast()"
}
}
tasks.create("packaging") {
group 'packaging'
description 'packaging task'
dependsOn test
enabled false
println "[phase:configuration] packaging"
doLast {
println "[phase:execution] packaging:doLast()"
}
}
class Install extends DefaultTask{
String installObjectName
@TaskAction
void checkObject() {
println "[phase:execution] install:checkObject (${installObjectName})"
}
@TaskAction
void installObject() {
println "[phase:execution] install:installObject (${installObjectName})"
}
}
task install(type: Install) {
group 'install'
description 'install task'
installObjectName 'test.jar'
println "[phase:configuration] install"
doFirst {
println "[phase:execution] install:doFirst()"
}
doLast {
println "[phase:execution] install:doLast()"
}
}
install.dependsOn packaging
install.onlyIf { packaging.enabled }
liumiaocn:hello liumiao$
總結
使用gradle的dependsOn/enabled/onlyIf等特性,結合groovy語言進行簡單編碼,gradle能夠實現非常靈活的用法,可以在具體專案中進行不斷實踐。