Gradle命令列黑魔法

黃博文發表於2013-09-02

Gradle命令列黑魔法

毫無疑問,現在Gradle已經成為java世界最火的構建工具,風頭已經蓋過了冗餘的ant,落後的maven。Gradle是以Groovy語言編寫的一套構建指令碼的DSL,由於Groovy語法的優雅,所以導致Gradle天生就有簡潔、可讀性強、靈活等特性。

Gradle的命令列功能也非常強大。本人從maven轉到Gradle,深深被gradle強大的命令列功能折服。通過命令列來實現Gradle的各種特性,就像魔法師在表演魔法一樣。

  • 日誌輸出。 Gradle中的日期有6個層級。從高到低分別是 ERROR(錯誤資訊)、QUIET(重要資訊)、WARNGING(警告資訊)、LIFECYCLE(程式資訊)、INFO(一般資訊)、DEBUG(除錯資訊)。在執行gradle task時可以適時的調整資訊輸出等級,以便更方便的觀看執行結果。

    比如一個build.gradle有這樣一個task

1
2
3
task hello << {
     println 'hello world!'
}

加入-q與不加-q的輸出結果不同。

1
2
3
4
5
6
7
8
9
$ gradle hello
:hello
hello world!

BUILD SUCCESSFUL

Total time: 3.546 secs
$ gradle -q hello
hello world!
  • 堆疊跟蹤。如果執行gradle task失敗時,如果想得到更詳細的錯誤資訊,那麼就可以使用-s(或--stacktrace)來輸出詳細的錯誤堆疊。你還可以使用-S(或--full-stacktrace)來輸出全部堆疊資訊,不過一般不推薦這樣做,因為gradle是基於groovy語言,而groovy作為一門動態語言可能會輸出與你的錯誤程式碼毫不相關的資訊。

  • 跳過指定的測試。如果你在執行build的時候想跳過test task,那麼可以使用-x命令。

1
2
3
4
5
6
7
8
9
10
11
12
$ gradle build -x test
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:check
:build

BUILD SUCCESSFUL

Total time: 3.529 secs
  • 繼續執行task而忽略前面失敗的task。預設情況下,如果有某個task失敗,後續的task就不會繼續執行。但是有時候我們想執行所有的task來一次性得到所有的構建錯誤,那麼我們可以使用--continue命令。使用--continue命令後即使遇到某些task失敗也不會停止後續task的執行。但是需要注意的是如果某個task失敗了,那麼依賴於這個task的其他task依舊不會執行,因為這會帶來不安全的因素。

  • 呼叫task時使用短名或縮寫。如果一個task的名稱過程,那麼呼叫時可以只輸入部分名稱即可呼叫,無需輸入全名。

1
2
3
task helloWorld << {
     println 'hello world!'
}

比如呼叫helloWorld可以通過全名呼叫、字首呼叫或首字母呼叫。

1
2
3
4
5
6
$ gradle -q helloWorld
hello world!
$ gradle -q hell
hello world!
$ gradle -q hW
hello world!
  • 使用指定的gradle檔案呼叫task。預設情況下,如果你呼叫gradle task,那麼首先會尋找當前目錄下的build.gradle檔案,以及根據settings.gradle中的配置尋找子專案的build.gradle。但是有時候我們想指定使用某個gradle檔案,那麼可以使用-b命令。 比如當前目錄有個子目錄subproject1,裡面有個叫hello.gradle。
subproject1/hello.gradle
1
2
3
task helloWorld << {
     println 'hello world!'
}

那麼在當前目錄可以使用以下命令呼叫這個task。

1
2
3
4
5
6
7
$ gradle -b subproject1/hello.gradle  helloWorld
:helloWorld
hello world!

BUILD SUCCESSFUL

Total time: 3.752 secs
  • 使用指定的專案目錄呼叫task。前面已經說過,執行gradle的task預設會在當前目錄尋找build.gradle及settings.gradle檔案。如果我們想在任何地方執行某個專案的task,那麼可以使用-p來指定使用的專案。
1
gradle -q -b learnGradle helloWorld

這條命令是呼叫learnGradle這個專案下的helloWorld task。

  • 顯示task之間的依賴關係。眾所周知,使用gradle tasks可以列出當前所有可被使用的task,但是並沒有顯示task之間的依賴關係。我們可以加上--all來顯示 task的依賴關係。
1
2
3
4
5
6
7
8
9
10
11
$ gradle tasks --all
………………

Other tasks
-----------
task0
    task1
    task2
    task3

…………
從上面可以看出task0依賴task1、task2及task3。
  • 檢視指定階段的依賴關係。使用gradle dependencies 可以檢視專案中包的依賴關係。不過是列出了所有階段的依賴,如果專案中依賴複雜的話看起來有點頭痛。那麼可以使用--configuration來檢視指定階段的依賴情況。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ gradle -q dependencies

------------------------------------------------------------
Root project
------------------------------------------------------------

archives - Configuration for archive artifacts.
No dependencies

compile - Compile classpath for source set 'main'.
No dependencies

default - Configuration for default artifacts.
No dependencies

runtime - Runtime classpath for source set 'main'.
No dependencies

testCompile - Compile classpath for source set 'test'.
\--- junit:junit:4.11
     \--- org.hamcrest:hamcrest-core:1.3

testRuntime - Runtime classpath for source set 'test'.
\--- junit:junit:4.11
     \--- org.hamcrest:hamcrest-core:1.3

使用gradle -q dependencies --configuration testCompile可以只檢視testComiple的依賴。

1
2
3
4
5
6
7
8
9
$ gradle -q dependencies --configuration testCompile

------------------------------------------------------------
Root project
------------------------------------------------------------

testCompile - Compile classpath for source set 'test'.
\--- junit:junit:4.11
     \--- org.hamcrest:hamcrest-core:1.3
  • 檢視指定dependency的依賴情況。 假如我想檢視專案中有沒有引入junit,那些階段引入了junit,那麼可以使用dependecyInsight來檢視。
1
2
3
4
$ gradle dependencyInsight --dependency junit --configuration testCompile
:dependencyInsight
junit:junit:4.11
\--- testCompile

注意dependencyInsight預設只會檢視compile階段的依賴,如果要檢視其他階段可以使用--configuration來指定。

  • 使用--profile命令列可以產生build執行時間的報告。該報告儲存在build/report/profile目錄,名稱為build執行的時間。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ gradle build --profile
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build UP-TO-DATE

BUILD SUCCESSFUL

Total time: 3.726 secs

然後在build/report/profile目錄下可以看到build的report。

Gradle命令列黑魔法

這個報表非常有用,尤其是在在縮短build時間時可以快速定位那些耗時長的task。

  • 試執行build。如果你想知道某個task執行時那些task會被一起執行,但是你又不想真正的執行這些task,可以使用-m來試執行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ gradle -m build
:compileJava SKIPPED
:processResources SKIPPED
:classes SKIPPED
:jar SKIPPED
:assemble SKIPPED
:compileTestJava SKIPPED
:processTestResources SKIPPED
:testClasses SKIPPED
:test SKIPPED
:check SKIPPED
:build SKIPPED

BUILD SUCCESSFUL

Total time: 3.53 secs

這樣我們可以一目瞭然的看到那些task被執行了,又不需要花太多的時間。

  • Gradle的圖形介面。

其實Gradle自帶一個圖形介面來讓習慣gui操作的人來操作Gradle。開啟方式很簡單。

1
$ gradle --gui

這樣就會彈出一個gui介面。

Gradle命令列黑魔法

通過這個gui介面可以很方面的執行gradle的各種命令,還可以將常用的命令儲存為favorites。該gui的配置資訊預設被儲存在當前專案的gradle-app.setting檔案中。

注意使用gradle --gui會阻塞當前終端,可以使用gradle --gui&來實現後臺執行。

  • 重新編譯Gradle指令碼。第一次執行Gradle命令,會在專案更目錄下生成一個.gradle目錄來存放編譯後的指令碼。只有當構建指令碼發生修改時採用重新編譯。我們可以使用--recompile-scripts來強行重新編譯。

相關文章