1. 程式人生 > >Gradle基礎:5:task的依賴與執行條件

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能夠實現非常靈活的用法,可以在具體專案中進行不斷實踐。