1. Taskfile 是什么
Taskfile 通過 yaml 來描述各種執(zhí)行任務(wù), 其核心采用 go 編寫; 相較于 Makefile 的 tab 分割和 bash 結(jié)合語法 Taskfile 顯得更加現(xiàn)代化和易于使用(雖然會變成 yaml 工程師). Taskfile 內(nèi)置了動態(tài)變量、操作系統(tǒng)等環(huán)境變量識別等高級功能都更貼合現(xiàn)代化的 Coding 方式。
總體來說如果你是一個(gè)對 Makefile 不太熟悉的人, 又期望通過類似 Makefile 的工具完成一些批量任務(wù), 那么相對于 Makefile 來說 Taskfile 會更加便于入門, 學(xué)習(xí)曲線更低且速度也足夠快。
2. 安裝及使用
安裝 go-task
對于 mac 用戶來說官方提供了 brew 安裝方式:
$brewinstallgo-task/tap/go-task
對于 Linux 用戶, 官方提供了部分 Linux 發(fā)行版的安裝包, 但由于其只有一個(gè)二進(jìn)制文件, 所以官方也提供了快速安裝腳本:
#ForDefaultInstallationto./binwithdebuglogging
$sh-c"$(curl--locationhttps://taskfile.dev/install.sh)"---d
#ForInstallationTo/usr/local/binforuserwideaccesswithdebuglogging
#Mayrequiresudosh
$sh-c"$(curl--locationhttps://taskfile.dev/install.sh)"---d-b/usr/local/bin
如果本地已經(jīng)有了 Go 語言開發(fā)環(huán)境也可以直接通過 go 命令安裝:
$goinstallgithub.com/go-task/task/v3/cmd/task@latest
快速開始
安裝完成后, 只需要編寫一個(gè)Taskfile.yml
的 yaml 文件, 然后就可以通過task
命令運(yùn)行相應(yīng)的任務(wù):
version:'3'
tasks:
build:
cmds:
-echo"執(zhí)行build任務(wù)"
docker:
cmds:
-echo"打包docker鏡像"
如果需要設(shè)置默認(rèn)執(zhí)行任務(wù), 只需要?jiǎng)?chuàng)建一個(gè)名字為default
的任務(wù)即可:
version:'3'
tasks:
default:
cmds:
-echo"這是默認(rèn)任務(wù)"
build:
cmds:
-echo"執(zhí)行build任務(wù)"
docker:
cmds:
-echo"打包docker鏡像"
3. 進(jìn)階使用
環(huán)境變量
Taskfile 支持引用三種環(huán)境變量:
- Shell 環(huán)境變量
- Taskfile 內(nèi)定義的環(huán)境變量
- 變量文件內(nèi)定義的環(huán)境變量
如果需要引用 Shell 內(nèi)的環(huán)境變量只需要使用$ 變量名
方式直接引用即可:
version:'3'
tasks:
default:
cmds:
-echo"$ABCD"
同樣在 Taskfile 內(nèi)也可以定義環(huán)境變量:
version:'3'
env:
TENV2:"t2"#全局環(huán)境變量
tasks:
default:
cmds:
-echo"$TENV1"
-echo"$TENV2"
env:
TENV1:"t1"#單個(gè)task環(huán)境變量
除了這種直接引用變量的方式, Taskfile 也支持類似 docker-compose 一樣讀取 env 文件來加載環(huán)境變量;Taskfile 會默認(rèn)加載同級目錄下的.env
文件, 也可以在 Taskfile 內(nèi)通過dotenv
命令來配置特定文件:
version:'3'
dotenv:[".env",".testenv"]
tasks:
default:
cmds:
-echo"$ABCD"
-echo"$TESTENV"
增強(qiáng)變量
除了標(biāo)準(zhǔn)的環(huán)境變量以外, 在 Taskfile 中還內(nèi)置了一種使用更加廣泛的增強(qiáng)變量vars
; 該變量模式可以通過 go 的模版引擎進(jìn)行讀取(插值引用), 且具有環(huán)境變量不具備的特殊特性. 以下為 vars 變量的示例:
version:'3'
#全局var變量
vars:
GLOBAL_VAR:"globalvar"
tasks:
testvar:
#taskvar變量
vars:
TASK_VAR:"taskvar"
cmds:
-"echo{{.GLOBAL_VAR}}"
-"echo{{.TASK_VAR}}"
除了上面與環(huán)境變量類似的使用以外, vars 增強(qiáng)變量還支持動態(tài)定義; 常見的場景, 比如我們想每次 task 執(zhí)行時(shí)都獲取當(dāng)前的 git commit id, 此時(shí)可以使用 vars 的動態(tài)定義特性:
version:'3'
tasks:
build:
cmds:
-gobuild-ldflags="-Xmain.Version={{.GIT_COMMIT}}"main.go
vars:
#每次任務(wù)執(zhí)行時(shí),GIT_COMMIT都會調(diào)用shell命令來生成這個(gè)變量
GIT_COMMIT:
sh:gitlog-n1--format=%h
vars 變量還內(nèi)置了一些特殊的預(yù)定義變量, 例如{{.TASK}}
變量永遠(yuǎn)表示當(dāng)前的任務(wù)名稱、{{.CLI_ARGS}}
可以引用命令行輸入等.
version:'3'
tasks:
yarn:
cmds:
-yarn{{.CLI_ARGS}}
此時(shí)如果執(zhí)行task yarn -- install
, 那么{{.CLI_ARGS}}
值將會變成install
從而執(zhí)行yarn install
命令.
除此之外, vars 變量還具備一些其他特性, 比如跨任務(wù)引用時(shí)可進(jìn)行覆蓋傳遞等, 這些特性將會在后面介紹.
執(zhí)行目錄
Taskfile 內(nèi)定義的 task 默認(rèn)在當(dāng)前目錄下執(zhí)行, 如果期望在其他目錄執(zhí)行, 無需手動編寫cd
等命令, 可以直接通過配置dir
參數(shù)來設(shè)置執(zhí)行目錄:
version:'3'
tasks:
test1:
dir:/tmp#在指定目錄執(zhí)行
cmds:
-"ls"
任務(wù)依賴
在 CI 等環(huán)境的使用中, 我們常常需要定義任務(wù)的執(zhí)行順序和依賴關(guān)系; Taskfile 中通過deps
配置來提供任務(wù)依賴關(guān)系的支持:
version:'3'
tasks:
build-jar:
cmds:
-echo"編譯jar包..."
build-static:
cmds:
-echo"編譯前端UI..."
build-docker:
deps:[build-jar,build-static]
cmds:
-echo"打包docker鏡像..."
任務(wù)調(diào)用
當(dāng)我們在 Taskfile 中定義了多個(gè)任務(wù)時(shí), 很可能一些任務(wù)具有一定的相似性, 此時(shí)我們可以通過任務(wù)互相調(diào)用和 vars 變量動態(tài)覆蓋的方式來定義模版 Task:
version:'3'
tasks:
docker:
cmds:
#-dockerbuild-t{{.IMAGE_NAME}}{{.BUILD_CONTEXT}}
-echo{{.IMAGE_NAME}}{{.BUILD_CONTEXT}}
build-backend:
cmds:
-task:docker#引用其他task
vars:{#動態(tài)傳入變量
IMAGE_NAME:"backend",
BUILD_CONTEXT:"maven/target"
}
build-frontend:
cmds:
-task:docker
vars:{
IMAGE_NAME:"frontend",
BUILD_CONTEXT:"public"
}
default:#default用于在命令行不顯示輸入任何task名稱時(shí)調(diào)用
cmds:
-task:build-backend
-task:build-frontend
引入其他文件
Taskfile 支持通過includes
關(guān)鍵字來引入其他 Taskfile, 從而方便 Taskfile 的結(jié)構(gòu)化處理.
需要注意的是, 由于引入的文件中可能會包含多特 task, 所以在使用時(shí)需要對引入的文件進(jìn)行命名, 且通過命名引用目標(biāo) task:
version:'3'
includes:
file1:./file1.yaml#直接引用yaml文件
dir2:./dir2#引用目錄時(shí)默認(rèn)引用該目錄下的Taskfile.yaml
在引入其他 Taskfile 時(shí),默認(rèn)情況下會在當(dāng)前主 Taskfile 目錄下執(zhí)行命令, 我們同樣可以通過dir
參數(shù)來控制引入的 Taskfile 內(nèi)的 task 在特定目錄下執(zhí)行:
version:'3'
includes:
dir1:./dirtest.yaml#直接在當(dāng)前目錄執(zhí)行
dir2:
taskfile:./dirtest.yaml
dir:/tmp#在指定目錄執(zhí)行
defer 處理
熟悉 go 語言的同學(xué)應(yīng)該知道, go 里面有個(gè)很方便的關(guān)鍵字defer
; 該指令用于定義在最終代碼收尾時(shí)要執(zhí)行的動作, 常見的比如資源清理等. Taskfile 中同樣支持了該指令, 可以方便我們在任務(wù)執(zhí)行期間完成一些清理操作:
version:'3'
tasks:
default:#default用于在命令行不顯示輸入任何task名稱時(shí)調(diào)用
cmds:
-wget-qhttps://github.com/containerd/nerdctl/releases/download/v0.19.0/nerdctl-full-0.19.0-linux-amd64.tar.gz
#定義清理動作
-defer:rm-fnerdctl-full-0.19.0-linux-amd64.tar.gz
-tar-zxfnerdctl-full-0.19.0-linux-amd64.tar.gz
當(dāng)然, defer 指令除了直接寫命令以外, 還可以引用其他 task 完成清理:
version:'3'
tasks:
cleanup:
cmds:
-rm-f{{.FILE}}
default:#default用于在命令行不顯示輸入任何task名稱時(shí)調(diào)用
cmds:
-wget-qhttps://github.com/containerd/nerdctl/releases/download/v0.19.0/nerdctl-full-0.19.0-linux-amd64.tar.gz
#引用其他task進(jìn)行清理,同時(shí)也可以傳遞動態(tài)變量
-defer:{task:cleanup,vars:{FILE:nerdctl-full-0.19.0-linux-amd64.tar.gz}}
-tar-zxfnerdctl-full-0.19.0-linux-amd64.tar.gz
4. 高級應(yīng)用
動態(tài)檢測
輸出檢測
在某些時(shí)候, 一些任務(wù)我們可能期望進(jìn)行緩存處理, 比如說已經(jīng)下載好了文件就不要重復(fù)運(yùn)行下載; 針對于這種需求, Taskfile 允許我們定義源文件和生成的文件, 通過這組文件的 hash 值來確定是否需要執(zhí)行該任務(wù):
version:'3'
tasks:
default:
cmds:
-wget-qhttps://github.com/containerd/nerdctl/releases/download/v0.19.0/nerdctl-full-0.19.0-linux-amd64.tar.gz
sources:
-testfile
generates:
-nerdctl-full-0.19.0-linux-amd64.tar.gz
從上圖中可以看到, 當(dāng)首次執(zhí)行任務(wù)時(shí)會生成.task
目錄, 該目錄包含文件的 hash 值; 當(dāng)重復(fù)執(zhí)行任務(wù)時(shí), 如果 hash 值不改變則真實(shí)任務(wù)不會真正執(zhí)行.Taskfile 默認(rèn)有兩種文件檢測的方式:checksum
、timestamp
,checksum
執(zhí)行文件的 hash 檢測(默認(rèn)), 該模式只需要定義sources
配置;timestamp
執(zhí)行文件的時(shí)間戳檢測, 該模式需要同時(shí)定義sources
和generates
配置.
version:'3'
tasks:
build:
cmds:
-gobuild.
sources:
-./*.go
generates:
-app{{exeExt}}
method:checksum#指定檢測方式
除了內(nèi)置的兩種檢測模式外, 我們還可以通過status
配置來定義自己的檢測命令,如果命令執(zhí)行結(jié)果為 0, 則認(rèn)為文件是最新的, 不需要執(zhí)行任務(wù):
version:'3'
tasks:
generate-files:
cmds:
-mkdirdirectory
-touchdirectory/file1.txt
-touchdirectory/file2.txt
#testexistenceoffiles
status:
-test-ddirectory
-test-fdirectory/file1.txt
-test-fdirectory/file2.txt
輸入檢測
上面的輸出檢測用于檢測任務(wù)生成的文件結(jié)果等, 在某些情況下我們可能期望在運(yùn)行任務(wù)之前來判斷某個(gè)條件, 在完全不執(zhí)行的情況下確定任務(wù)是否需要運(yùn)行; 此時(shí)我們可以使用preconditions
配置指令:
version:'3'
tasks:
generate-files:
cmds:
-mkdirdirectory
-touchdirectory/file1.txt
-touchdirectory/file2.txt
#testexistenceoffiles
preconditions:
-test-f.env
-sh:"[1=0]"
msg:"Onedoesn'tequalZero,Halting"
Go 模版引擎
在上面變量環(huán)節(jié)中已經(jīng)展示了一部分模版引擎的使用, 實(shí)際上 Taskfile 內(nèi)集成了slim-sprig[1]庫, 該庫中提供了一些比較便利的方法, 這些方法都可以在模版引擎內(nèi)使用:
version:'3'
tasks:
print-date:
cmds:
-echo{{now|date"2006-01-02"}}
關(guān)于這些方法和模版引擎的使用具體請參考 Go Template 相關(guān)文檔以及slim-sprig[2]文檔.
交互式終端
有些任務(wù)命令可能需要交互式終端來執(zhí)行, 此時(shí)可以為 task 設(shè)置interactive
選項(xiàng); 當(dāng)interactive
設(shè)置為true
時(shí), task 在運(yùn)行時(shí)可以打開交互式終端:
version:'3'
tasks:
cmds:
-vimmy-file.txt
interactive:true
更多關(guān)于 Taskfile 的細(xì)節(jié)使用請閱讀其官方文檔[3], 本文限于篇幅不在過多闡述。
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
87文章
11319瀏覽量
209828 -
Makefile
+關(guān)注
關(guān)注
1文章
125瀏覽量
19191 -
go語言
+關(guān)注
關(guān)注
1文章
158瀏覽量
9053
原文標(biāo)題:Taskfile VS Makefile,構(gòu)建工具哪家強(qiáng)?Taskfile 敢稱王
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論