2017-04-07 56 views
2

我有一個多項目,並且在構建最後一個子項目後,我想處理所有jar。 所以我創建了根項目任務:在根項目中找不到路徑'build'的任務

task install(dependsOn: 'build', type: Copy) { 
    doLast { 
     println "exec install task" 
    } 
} 

當打電話./gradlew install在根目錄下,我面對這個錯誤:

FAILURE: Build failed with an exception. 

* What went wrong: 
Could not determine the dependencies of task ':install'. 
> Task with path 'build' not found in root project 'foo'. 

但是,調用./gradlew tasks顯示我以下任務:

:tasks 

------------------------------------------------------------ 
All tasks runnable from root project 
------------------------------------------------------------ 

Build tasks 
----------- 
assemble - Assembles the outputs of this project. 
build - Assembles and tests this project. 
... 

我該如何實現所需的功能?

回答

2

我假設你的根項目組織了構建,但沒有定義自己採取的構建行爲。 build任務通常由語言插件定義(大多數情況下通過apply plugin: 'java'),但如果您的根項目不使用任何一個,它將不會有任何build任務。

幫助任務tasks,您使用的描述,says

Displays the tasks runnable from root project 'projectReports' (some of the displayed tasks may belong to subprojects).

幫助任務followes相同的邏輯通過命令行任務的激活。您可以提供一個任務名稱,任何子項目中的名稱都將被執行(這就是爲什麼gradle build有效)。

但是,如果您定義了dependsOn依賴項,則給定字符串將作爲單個任務的任務路徑進行評估。由於每個任務名稱只能在項目中使用一次,因此該名稱對於根項目中的任務是唯一的,但如果考慮子項目,則可以找到許多任務。因此,可以使用語法:<projectName>:<taskName>來識別子項目中的任務。

現在,我們來面對您的具體問題:如果install任務應取決於一個子項目的build任務,則可以使用dependsOn ':<mySubproject>:build'。但我相信你想要的install任務依賴於每個子項目build任務,所以我想提出這個方法:

task install(type: Copy) { 
    dependsOn subprojects*.tasks*.findByName('build').minus(null) 
    doLast { 
     println "exec install task" 
    } 
} 

通過這種方式,爲每個註冊的子項目,findByName('build')被稱爲和結果(發現任務或null)被放入一個列表中,然後用作任務依賴列表。我添加了.minus(null)部分以刪除列表中的null條目,因爲我不確定Gradle如何處理依賴項集合中的這些條目。如果您確定,每個子項目都提供build任務,您也可以使用getByName('build')

編輯: OP發現的可以遞歸getTasksByName方法,甚至適合這種情況下比手動遍歷所有子項目更好:

dependsOn getTasksByName('build', true) 
+0

非常感謝你的解釋。我會盡快嘗試。將取決於子項目* .findByName('build')。minus(null)'只會導致一次調用'install'?如果我有子項目A,B和C,'install'應該在所有子項目的最後一個'build'完成後運行一次。 – user3105453

+0

是的,每個任務只執行一次。如果依賴多個其他任務,則在所有這些任務完成後執行。如果你肯定會100%確定,那麼子項目C的'build'任務將是__always__是最後一個,你可以使用'dependsOn':projectC:build'',但是我建議依賴每個任務和讓Gradle自己找出依賴關係樹。對於三個項目,您還可以通過'dependsOn'手動定義依賴關係:projectA:build',':projectB:build',':projectC:build''。 –

+1

我終於找到時間來嘗試你的解決方案。不幸的是,'findByName'似乎不起作用,但是這行代碼完成了我所期望的:'dependsOn subprojects * .getTasksByName(「build」,true)'。隨時更新您的解決方案,我很樂意接受它。非常感謝你。 – user3105453

相關問題