我們先來(lái)學(xué)習(xí)一下gradle簡(jiǎn)單的腳本。
構(gòu)建第一個(gè)腳本
projects 和 tasks是 Gradle 中最重要的兩個(gè)概念蝇率。任何一個(gè) Gradle 構(gòu)建都是由一個(gè)或多個(gè) projects 組成宫盔。每個(gè) project 包括許多可構(gòu)建組成部分。 這完全取決于你要構(gòu)建些什么。舉個(gè)例子鞋诗,每個(gè) project 或許是一個(gè) jar 包或者一個(gè) web 應(yīng)用穴店,它也可以是一個(gè)由許多其他項(xiàng)目中產(chǎn)生的 jar 構(gòu)成的 zip 壓縮包撕捍。一個(gè) project 不必描述它只能進(jìn)行構(gòu)建操作。它也可以部署你的應(yīng)用或搭建你的環(huán)境泣洞。不要擔(dān)心它像聽(tīng)上去的那樣龐大卦洽。 Gradle 的 build-by-convention 可以讓您來(lái)具體定義一個(gè) project 到底該做什么。每個(gè) project 都由多個(gè) tasks 組成斜棚。每個(gè) task 都代表了構(gòu)建執(zhí)行過(guò)程中的一個(gè)原子性操作阀蒂。如編譯,打包弟蚀,生成 javadoc蚤霞,發(fā)布到某個(gè)倉(cāng)庫(kù)等操作。到目前為止义钉,可以發(fā)現(xiàn)我們可以在一個(gè) project 中定義一些簡(jiǎn)單任務(wù)昧绣。
類(lèi)似于Maven的pom.xml文件,每個(gè)Gradle項(xiàng)目都需要有一個(gè)對(duì)應(yīng)的配置文件捶闸,就叫build.gradle文件夜畴,當(dāng)在命令中執(zhí)行g(shù)radle命令時(shí),Gradle會(huì)去尋找名字為build.gradle的文件删壮,如果找不到贪绘,就會(huì)顯示幫助信息。比如我們新建一個(gè)空文件夾hello央碟,并在里面執(zhí)行一條類(lèi)似maven的清理命令 :
gradle? clean
我們來(lái)在hello文件夾中創(chuàng)建一個(gè)build.gradle文件税灌,在文件中定義一個(gè)獨(dú)立的任務(wù),在gradle中叫做task亿虽,也就是任務(wù)菱涤。在本例子中我們給任務(wù)起名為hello,任務(wù)要打印出經(jīng)典的Hello World洛勉,完成這些需要使用Gradle的通用語(yǔ)言Groovy粘秆,將println命令添加到task任務(wù)的 doLast中,具體的任務(wù)腳本十分簡(jiǎn)單收毫,如下:
然后在命令行中運(yùn)行該task:
gradle? -q? hello
使用Gradle打印字符串就是這么簡(jiǎn)單攻走!-q 參數(shù)的作用是殷勘,該參數(shù)用來(lái)控制 gradle 的日志級(jí)別,可以保證只輸出我們需要的內(nèi)容陋气。不加輸出的內(nèi)容就是:
上面的腳本定義了一個(gè)叫做 hello 的 task劳吠,并且給它添加了一個(gè)動(dòng)作。當(dāng)執(zhí)行 gradle hello 的時(shí)候, Gralde 便會(huì)去調(diào)用 hello 這個(gè)任務(wù)來(lái)執(zhí)行給定操作巩趁。這些操作其實(shí)就是一個(gè)用 groovy 書(shū)寫(xiě)的閉包痒玩。如果你覺(jué)得它看上去跟 Ant 中的 targets 很像,那么是對(duì)的议慰。Gradle 的 tasks 就相當(dāng)于 Ant 中的 targets蠢古。不過(guò)你會(huì)發(fā)現(xiàn)他功能更加強(qiáng)大。
下面用一種更簡(jiǎn)潔的方式來(lái)定義上面的 hello 任務(wù):
上面的腳本又一次采用閉包的方式來(lái)定義了一個(gè)叫做 hello 的任務(wù)别凹,我們將會(huì)更多的采用這種簡(jiǎn)單的風(fēng)格來(lái)定義任務(wù)草讶。查看運(yùn)行效果:
再來(lái)看一下gradle對(duì)ant任務(wù)的使用:
來(lái)運(yùn)行看一下效果:
gradle對(duì)ant有很好的集成,因?yàn)間radle使用的是Groovy炉菲,我們可以單獨(dú)定義一個(gè)方法調(diào)用:
可以看到堕战,效果是一樣的:
我們?cè)賮?lái)定義一個(gè)任務(wù):
gradle執(zhí)行哪個(gè)就會(huì)打印哪個(gè),另一個(gè)不會(huì)打优乃:
我們來(lái)讓一個(gè)task依賴(lài)于另一個(gè)task嘱丢,需要使用dependsOn關(guān)鍵字:
這樣就可以每次運(yùn)行rock任務(wù)就自動(dòng)先運(yùn)行helloant任務(wù),來(lái)看一下效果:
一個(gè)任務(wù)可以多次執(zhí)行祠饺,這種情況需要定義動(dòng)態(tài)task越驻,腳本可以在循環(huán)中使用Groovy在java.lang.Number中擴(kuò)展的times方法創(chuàng)建3個(gè)新的task,Groovy自動(dòng)暴露一個(gè)隱式的變量it來(lái)指定循環(huán)迭代的次數(shù)道偷,使用這個(gè)計(jì)數(shù)器構(gòu)建task的名字缀旁,對(duì)于第一輪迭代,task可以叫rock0勺鸦,以此類(lèi)推并巍。動(dòng)態(tài)定義如下:
我們看到把rock改成了動(dòng)態(tài)定義,外面使用了times定義了3次祝旷,里面使用了雙引號(hào)(必須)括起來(lái)后面加上了$it履澳,表示rock0,rock1怀跛,rock2等,后面的依賴(lài)依照順序依次依賴(lài)柄冲,我們來(lái)執(zhí)行一個(gè)rock1看一下:
可以看到把rock1和前面所有傳遞的依賴(lài)都執(zhí)行了一遍吻谋。rock2是最后一個(gè)任務(wù),我們來(lái)定義一個(gè)空任務(wù)现横,依賴(lài)rock2漓拾,這樣執(zhí)行空任務(wù)就能執(zhí)行所有的任務(wù):
注意空任務(wù)start中的冒號(hào)必須寫(xiě)上阁最,來(lái)執(zhí)行看看效果:
這就是task簡(jiǎn)單的定義和使用!
查看所有Task
上面的例子展示了如何使用gradle指定運(yùn)行一個(gè)task骇两,要運(yùn)行一個(gè)task就需要知道它的名字速种,來(lái)看gradle自帶的一個(gè)任務(wù),幫助我們查詢(xún)所有可用的task:
gradle? tasks
可以看到列出的信息不是很全低千,很多是說(shuō)明性質(zhì)的配阵,為了看到所有的task,我們需要在后面加上--all:
gradle? tasks? --all
我們看到了所有的task示血,包括我們自己定義的棋傍。
gradle提供了任務(wù)組的概念,可以看做是多個(gè)task的集群难审,每個(gè)構(gòu)建腳本都會(huì)暴露help tasks任務(wù)組(如上圖)瘫拣,如果某個(gè)task不屬于任何一個(gè)任務(wù)組,他就會(huì)顯示在other tasks中告喊。
排除一個(gè)任務(wù)
我們?cè)趫?zhí)行task的時(shí)候麸拄,可以指定排除一個(gè)任務(wù),比如我們排除任務(wù)rock0:
gradle? start? -x? rock0
可以看到只執(zhí)行了rock1黔姜,rock2和start三個(gè)任務(wù)拢切,rock0和helloant沒(méi)有執(zhí)行。gradle會(huì)排除指定任務(wù)和指定任務(wù)的依賴(lài)任務(wù)地淀,這個(gè)概念叫做智能排除失球。
構(gòu)建參數(shù)
我們執(zhí)行g(shù)radle命令可以控制日志級(jí)別,比如想打印info級(jí)別的選項(xiàng)帮毁,可以這樣執(zhí)行:
gradle? -i? start
想打印debug級(jí)別的日志实苞,可以這樣執(zhí)行(內(nèi)容過(guò)多,看一部分):
gradle? -d? start
想看warn級(jí)別的日志烈疚,可以這樣執(zhí)行:
gradle? -w? start
想打印錯(cuò)誤時(shí)的堆棧信息黔牵,可以這樣執(zhí)行(輸入一個(gè)沒(méi)有的task):
gradle? -s? start
各個(gè)參數(shù)也可以組合使用:
注意:參數(shù)選項(xiàng)寫(xiě)在中間或者最后都可以
其它重要的如下:
--help? ? ?打印出所有可用的命令行選項(xiàng),包括描述信息
-b爷肝,--build-file? ? ?gradle默認(rèn)構(gòu)建腳本是build.gradle猾浦,使用這個(gè)可以指定一個(gè)其它名字的腳本
--offline? ? ?離線(xiàn)模式運(yùn)行,僅僅在本地緩存中查詢(xún)依賴(lài)是否存在
-q? ? ?減少構(gòu)建出錯(cuò)時(shí)打印出來(lái)的錯(cuò)誤日志信息
Gradle守護(hù)進(jìn)程
當(dāng)gradle成為工作的一部分時(shí)灯抛,你會(huì)發(fā)現(xiàn)需要重復(fù)的構(gòu)建金赦。改變一個(gè)類(lèi)就需要構(gòu)建,然后部署对嚼,很多人喜歡測(cè)試驅(qū)動(dòng)的開(kāi)發(fā)方式夹抗,不斷的運(yùn)行單元測(cè)試。不管哪種方式纵竖,效率很重要漠烧,每次初始化一個(gè)構(gòu)建杏愤,JVM都要重啟一次,Gradle的依賴(lài)都要載入到類(lèi)加載器中已脓,還要建立項(xiàng)目對(duì)象模型珊楼,這個(gè)過(guò)程可能要花上好幾秒。Gradle守護(hù)進(jìn)程可以解決這個(gè)問(wèn)題度液!
守護(hù)進(jìn)行以后臺(tái)進(jìn)程方式運(yùn)行Gradle厕宗,一旦啟動(dòng),gradle命令就會(huì)在后續(xù)的構(gòu)建中重用之前創(chuàng)建的守護(hù)進(jìn)程恨诱,以避免啟動(dòng)時(shí)造成的開(kāi)銷(xiāo)媳瞪。在命令中啟用守護(hù)進(jìn)程很簡(jiǎn)單,在執(zhí)行task時(shí)加上--daemon即可照宝,啟動(dòng)守護(hù)進(jìn)程會(huì)話(huà)費(fèi)一點(diǎn)點(diǎn)時(shí)間蛇受,但是后續(xù)的命令都會(huì)重用守護(hù)進(jìn)程。
gradle? start? --daemon
守護(hù)進(jìn)程會(huì)在三個(gè)小時(shí)后過(guò)期厕鹃,如果不使用守護(hù)進(jìn)程兢仰,可以這樣執(zhí)行:
gradle start --no-daemon
要停止守護(hù)進(jìn)程,可以這樣執(zhí)行:
gradle? --stop