2013-09-10 237 views
11

我在build.gradle如下:如何在執行Gradle任務的依賴關係之前做些事情?

task aoeu << { 
    println "**************************** during" 
} 

tasks.publish.dependsOn(aoeu) 

tasks.publish.doFirst { 
    println "************************* before" 
} 

tasks.publish.doLast { 
    println "************************* after" 
} 

它的輸出是:

:aoeu 
**************************** during 
:publish 
************************* before 
************************* after 

但我真正需要的是爲「中」到「前」和「後」之間發生。如何才能做到這一點? 「發佈」應該依賴於「之前」嗎?如果是這樣,我怎麼能保證它發生在其他依賴之前?

回答

4
task snth << { 
    println "************************* before" 
} 

task aoeu << { 
    println "**************************** during aoeu" 
} 
publish.dependsOn(aoeu) 

task ueoa << { 
    println "**************************** during ueoa" 
} 
publish.dependsOn(ueoa) 

publish.doLast { 
    println "************************* after" 
} 

publish.dependsOn.each { dependency -> 
    if (dependency instanceof Task) { 
     dependency.dependsOn(aoeu) 
    } 
} 

將輸出:

:snth 
************************* before 
:aoeu 
**************************** during aoeu 
:ueoa 
**************************** during ueoa 
:publish 
************************* after 

如果你想添加的依賴遞歸:

def recursivelyAddDependsOn(Task parent, Task dependsOn) { 
    if (!parent.equals(dependsOn)) { 
     parent.dependsOn(dependsOn) 

     def tasks = parent.dependsOn.findAll { dependency -> 
      dependency instanceof Task 
     } 
     tasks.each { task -> 
      recursivelyAddDependsOn(task, dependsOn) 
     } 
    } 
} 

recursivelyAddDependsOn(publish, snth) 

而更多功能的解決方案是:

def recursivelyApplyToTaskDependencies(Task parent, Closure closure) { 
    closure(parent) 

    parent.dependsOn.findAll { dependency -> 
     dependency instanceof Task 
    }.each { task -> 
     recursivelyApplyToTaskDependencies(task, closure) 
    } 
} 

def recursivelyAddTaskDependency(Task parent, Task dependency) { 
    def addTaskDependency = { p -> 
     if (!p.name.equals(dependency.name)) { 
      p.dependsOn(dependency) 
     } 
    } 

    recursivelyApplyToTaskDependencies(parent, addTaskDependency) 
} 

recursivelyAddTaskDependency(publish, snth) 
+1

既然「'''」運算符已被棄用,我們需要使用doFirst和doLast。 – will

11

據我所知,你的代碼應該可以正常工作,但它不會。應在0​​(執行階段)之前運行的配置階段執行 doFirst。 BTW這個代碼工作正常:

彼得Niederwiser寫到這裏https://stackoverflow.com/a/9204159/2069368doFirst運行在執行階段的第一條語句(doLast之前),這樣您的代碼工作正常。這個例子會告訴你執行順序gradle這個編譯:

task publish { 
    println "(1) before (run in configuration phase)" // this will run before gradle dependencies 
} 

task aoeu << { 
    println "(2) during (run in execution phase as last statement)" 
} 

tasks.publish.dependsOn(aoeu) 
tasks.publish.doLast { 
    println "(4) after (run in execution phase as last statement)" 
} 

tasks.publish.doFirst { 
    println "(3) after (run in execution phase as FORST statement - before doLast/<<)" 
} 

它將返回

C:\>gradle publish 
(1) before (run in configuration phase) 
:aoeu 
(2) during (run in execution phase as last statement) 
:publish 
(3) after (run in execution phase as FORST statement - before doLast/<<) 
(4) after (run in execution phase as last statement) 

[更新]

這裏http://gradle.1045684.n5.nabble.com/task-run-order-lt-lt-syntax-doLast-doFirst-etc-td3337481.html是很好的例子很好的問題,顯示執行順序。

閱讀this article關於gradle生命週期,它會幫助你理解它。

[更新] 如果你想在publish執行階段運行任務aoeu可以調用publish.doFirstaoeu.execute。但據我所知,不應該這樣做。

task publish { 
} 

task aoeu << { 
    println "(2) during (run in execution phase as last statement)" 
} 

tasks.publish.doLast { 
    println "(3) after (run in execution phase as last statement)" 
} 

tasks.publish.doFirst { 
    println "(1) after (run in execution phase as FORST statement - before doLast/<<)" 
    aoeu.execute() 
} 

將返回

C:\>gradle publish 
:publish 
(1) after (run in execution phase as FORST statement - before doLast/<<) 
(2) during (run in execution phase as last statement) 
(3) after (run in execution phase as last statement) 

當我看到你想在publish任務的途中跑aoeu。我認爲最好的辦法做到這一點將是將publish任務分成兩個單獨的任務,並使用depends,mustRunAfter來控制執行順序。請看下面的例子:

task publishInit << { 
    println '(1)' 
} 

task aoeu << { 
    println '(2)' 
} 

task publish << { 
    println '(3)' 
} 

publish.dependsOn publishInit 
publish.dependsOn aoeu 
aoeu.mustRunAfter publishInit 

它將返回

C:\>gradle publish 
:publishInit 
(1) 
:aoeu 
(2) 
:publish 
(3) 
+0

所以''之前'可以放在'發佈'配置。我想盡量縮短「之前」和「期間」之間的時間。有沒有其他的方法可以在執行階段的''期間'之前發生'before'? –

+0

我編輯了我的答案。但請記住調用'execute()'是錯誤的。我記得它將在gradle 2.0 api中被刪除(但我不確定)。爲什麼你不能只使用依賴關係?奇怪的是你想在另一箇中間調用任務。嘗試重構你的構建。如果你想在另一箇中間調用它,只需將另一個任務分成兩個獨立的任務。 – pepuch

+1

從郵件列表文章引用:「每個任務都有一系列操作,按任務執行時指定的順序運行... doFirst()方法配置任務以在序列的開始處添加操作。doLast()和<<方法將任務配置爲在序列末尾添加一個動作。 –