& 160;& 160;& 160;& 160; "上一篇隨筆" 介紹了Gradle的安裝與任務管理,這篇著重介紹Gradle的內建任務(in built tasks)與自定義任務(custom tasks),藉助Gradle提供的眾多內建任務類型以及自己定製的任務類型,Java Web、Andro
上一篇隨筆介紹了Gradle的安裝與任務管理,這篇著重介紹Gradle的內建任務(in-built tasks)與自定義任務(custom tasks),藉助Gradle提供的眾多內建任務類型以及自己定製的任務類型,Java Web、Android等的開發、測試、部署將會變得非常容易。這篇隨筆提供的都是非常簡單的示例,但這對於讀懂Gradle腳本(例如常見的build.gradle)或者是書寫Gradle腳本相信是有幫助的。本文所有代碼測試環境為Gradle 2.11
如有錯誤,請不吝指出,非常感謝;如本文對您有幫助,右下角點個推薦吧~
1.內建任務類(in-built tasks)
Gradle在不斷地更新,其內建任務也在不斷地豐富,這一章節介紹Gradle中最常用的幾個內建任務類,這隻是Gradle眾多內建任務類中的一部分,拋磚引玉,更多方法可以參見Gradle官方文檔
1.1 複製(Copy)
項目開發和部署過程中,複製文件是很常見的工作,gradle為了簡化開發步驟提供了大量的內建任務類,Copy
便是其中之一
- 先看一段最簡單的代碼
// org.gradle.api.tasks.Copy
// 將in.txt從當前文件夾複製到abc文件夾(不存在則新建)
// 代碼中的路徑為相對路徑
task copyTask(type: Copy) {
from '.'
into 'abc'
include 'in.txt'
}
include 與 exclude
(1) include '*' => 包含所有的文件以及文件夾
(2) include/exclude '*.xml' => 包含/排除當前文件夾下xml類型文件
(3) include/exclude '*.txt','*.data' =>包含/排除多類文件,逗號隔開(4) include/exclude '**/*.xml' => 包含/排除所有文件夾下xml類型文件
with
// 定義一個copySpec,通常是重覆使用的語句
// 插入到Task中
def dataContent = copySpec {
from 'src'
include '*.data'
}
task copyTask(type: Copy) {
from('.') {
exclude '*.txt', '*.xml' //排除txt、xml類型的文件
}
into 'build'
include '*'
includeEmptyDirs = false
with dataContent
}
其他屬性
(1) caseSensitive => 大小寫敏感,true/false,預設為true
(2) includeEmptyDirs => 是否包含空文件夾,true/false,預設為true
(3) filter => 重用org.apache.tools.ant.filters.*的方法
(4) 更多參見官方文檔
1.2 重命名(Rename)
- 閉包方法
// rename(Closure closure)
// 執行gradle cT
// 將當前文件夾下的所有.txt文件複製到build/中,並將尾碼改為.data
task copyTask(type: Copy) {
from '.'
into 'build'
include '*.txt'
rename { String fileName ->
fileName.replace('.txt' , '.data')
}
}
- 正則表達式
// rename(String sourceRegEx, String replaceWith)
// 將所有以out開頭的文件複製到build/,並將out替換為output
// $指代正則表達式匹配的地方,從1開始
task copyTask(type: Copy) {
from '.'
into 'build'
include '*.txt'
rename 'out(.*)', 'output$1' //=> out.txt->output.txt
// rename '(.*)t(.*)', '$1output$2'
}
>> 原來的結構如下
--Test/
|--out.txt
|--build.gradle
>> 執行任務後結構
--Test/
|--build/
|--output.txt
|--out.txt
|--build.gradle
1.3 打包(Zip)
// 執行gradle zT
// 將src文件夾下所有文件打包到dest/文件夾下
task zipTask(type: Zip) {
File destDir = file('dest')
archiveName 'abc.zip'
from 'src'
destinationDir destDir
}
>> 原來的結構如下
--Test/
|--src/
|--hello.java
|--world.java
|--build.gradle
>> 執行任務後結構
--Test/
|--dest/
|--abc.zip // 解壓後為hello.java和world.java2個文件
|--src/
|--hello.java
|--world.java
|--build.gradle
1.4 刪除(delete)
項目打包時,往往需要刪除調試、測試時的臨時文件,例如輸出、日誌等,可以使用內建方法Delete
完成這個任務,使用也非常簡單
task deleteTask(type: Delete) {
delete 'out.txt','log.txt'
}
1.5 執行(Exec)
每次執行時,都要切換環境,敲入命令,gradle提供了Exec
內建方法去簡化調試、測試過程,可以根據需要編寫代碼
// Java Web開發,關閉Tomcat
task stopTomcat(type:Exec) {
workingDir '../tomcat/bin'
//linux下
commandLine './stop.sh'
// 重定向輸出到擴展屬性output,而不是控制台
// 當然可以改為輸出到文件
standardOutput = new ByteArrayOutputStream()
ext.output = {
return standardOutput.toString()
}
}
其他屬性
(1) args(args) =>命令參數,List <String>
(2) commandLine(args) =>命令,List <String>
(3) environment(name, value),=> 臨時添加一個環境變數,多個需Map
(4) workingDir(dir) => 工作目錄,file類型
(5) 更多參見官方文檔
2.定製任務(custom tasks)
Gradle支持大量的插件,例如war、java、gretty等,這些插件能夠自動化自動化編譯、打包等過程,但是有時由於項目需求,插件並不能滿足項目的需求,Gradle支持定製任務類去完成你的工作。接下來將介紹三種定製Gradle任務類的方法
2.1 創建build文件
// .../Test/build.gradle
println 'I Am A Custom Task'
class HelloTask extends DefaultTask {
String nickName = 'default'
@TaskAction
def action1() { println 'Step 3 I Am ' + name }
@TaskAction
def action2() { println 'Step 2 NickName Is ' + nickName }
}
task hello(type: HelloTask) {
nickName = 'gzdaijie'
doFirst { println 'Step 1' }
doLast { println 'Step 4' }
}
執行結果
C:\Users\gzd\Desktop\Test>gradle -q hello
I Am A Custom Task
Step 1
Step 2 NickName Is gzdaijie
Step 3 I Am hello
Step 4
- name是內置屬性,值為任務名稱,doFirst,doLast內置方法
- 擴展自類
DefaultTask
,@TaskAction
新增Action - 關於Task基礎知識的介紹,可以參考我的上一篇博客
2.2 創建buildSrc目錄
事實上,build.gradle文件中不適合寫類的定義,假設我們定製的每個Task類都寫在build.gradle中,那麼build.gradle文件將會變得很大,可讀性大大降低,但是又不想為此單獨創建一個工程,那麼將代碼寫在buildSrc文件夾中將是一個很好的選擇。
// 文件 HelloTask.groovy
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
class HelloTask extends DefaultTask {
String nickName = 'default'
@TaskAction
def action1() { println 'Step 3 I Am ' + name }
@TaskAction
def action2() { println 'Step 2 NickName Is ' + nickName }
}
// 文件 build.gradle
task hello(type: HelloTask) {
nickName = 'gzdaijie'
doFirst { println 'Step 1' }
doLast { println 'Step 4' }
}
新建文件 buildSrc/src/main/groovy/ch3/HelloTask.groovy
目錄結構如下
---Test/
|--build.gradle
|--buildSrc/
|--src/
|--main/
|--groovy/
|--ch3/
|--HelloTask.groovy
執行gradle -q hello
結果與2.1一致,build.gradle中的代碼顯得十分乾凈
2.3 創建獨立的groovy項目
新建一個groovy項目,命名為HelloTask,可以使用eclipse、IDEA等IDE,接下來純手工建項目吧~
- 新建文件~/HelloTask/src/main/groovy/HelloTask.groovy,將之前的HelloTask複製進去,然後在HelloTask/目錄下新建文件build.gradle,這裡我們同樣使用gradle來構建groovy項目。
// => HelloTask/build.gradle
// apply plugin 應用插件
apply plugin: 'groovy'
version=1.0
dependencies {
// 添加依賴
compile gradleApi()
compile localGroovy()
}
目錄結構如下
--HomeDir
|--Test
|--build.gradle
|--HelloTask
|--build.gradle
|--src
|--main
|--groovy
|--HelloTask.groovy
在HelloTask/ 下執行gradle build
你會發現該目錄下多了build/libs/HelloTask-1.0.jar
這就是我們編譯好的定製任務類
- 接下來在HelloTask/ 下執行
gradle build
,gradle會在src/main/groovy目錄下搜尋所有的類build - 回到Test/目錄,清空所有內容,只留下build.gradle,寫入以下內容
// => Test/build.gradle
// buildscript 配置導入路徑,包信息
buildscript {
repositories {
flatDir { dirs '../HelloTask/build/libs' }
}
dependencies { classpath group: 'ch3', name:'HelloTask',version:'1.0' }
}
task hello(type: HelloTask) {
nickName = 'gzdaijie'
doFirst { println 'Step 1' }
doLast { println 'Step 4' }
}
- 在Test/ 中執行gradle hello,效果和2.1、2.2完全一致
3.小結
1中介紹了常用的內建Task類,2.3中使用了Gradle創建了Groovy
項目,並用了buildscript
導入了編譯好的包,入門指南寫到這裡,build.gradle已經很接近使用IDE(例如Eclipse、IDEA、Andriod Studio)自動生成的build.gradle文件了,Gradle依賴管理的威力已經開始顯現。
實際項目開發中,更多地是導入maven倉庫,而不是自己寫依賴,但是希望這個指南能給希望瞭解Gradle的博友帶來幫助,喜歡就關註一下吧~