Taskfile - 比 Makefile 更好用的构建工具
点击上方“程序猿技术大咖”,关注并选择“设为星标”
回复“加群”获取入群讨论资格!
作者丨bleem
译者丨https://mritd.com/about/
1. Taskfile 是什么
Taskfile 通过 yaml 来描述各种执行任务, 其核心采用 go 编写; 相较于 Makefile 的 tab 分割和 bash 结合语法 Taskfile 显得更加现代化和易于使用(虽然会变成 yaml 工程师). Taskfile 内置了动态变量、操作系统等环境变量识别等高级功能都更贴合现代化的 Coding 方式。
总体来说如果你是一个对 Makefile 不太熟悉的人, 又期望通过类似 Makefile 的工具完成一些批量任务, 那么相对于 Makefile 来说 Taskfile 会更加便于入门, 学习曲线更低且速度也足够快。
2. 安装及使用
安装 go-task
对于 mac 用户来说官方提供了 brew 安装方式:
$ brew install go-task/tap/go-task
对于 Linux 用户, 官方提供了部分 Linux 发行版的安装包, 但由于其只有一个二进制文件, 所以官方也提供了快速安装脚本:
# For Default Installation to ./bin with debug logging
$ sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d# For Installation To /usr/local/bin for userwide access with debug logging
# May require sudo sh
$ sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
如果本地已经有了 Go 语言开发环境也可以直接通过 go 命令安装:
$ go install github.com/go-task/task/v3/cmd/task@latest
快速开始
安装完成后, 只需要编写一个 Taskfile.yml
的 yaml 文件, 然后就可以通过 task
命令运行相应的任务:
version: '3'tasks:build:cmds:- echo "执行 build 任务"docker:cmds:- echo "打包 docker 镜像"
如果需要设置默认执行任务, 只需要创建一个名字为 default
的任务即可:
version: '3'tasks:default:cmds:- echo "这是默认任务"build:cmds:- echo "执行 build 任务"docker:cmds:- echo "打包 docker 镜像"
3. 进阶使用
环境变量
Taskfile 支持引用三种环境变量:
Shell 环境变量
Taskfile 内定义的环境变量
变量文件内定义的环境变量
如果需要引用 Shell 内的环境变量只需要使用 $ 变量名
方式直接引用即可:
version: '3'tasks:default:cmds:- echo "$ABCD"
同样在 Taskfile 内也可以定义环境变量:
version: '3'env:TENV2: "t2" # 全局环境变量tasks:default:cmds:- echo "$TENV1"- echo "$TENV2"env:TENV1: "t1" # 单个 task 环境变量
除了这种直接引用变量的方式, Taskfile 也支持类似 docker-compose 一样读取 env 文件来加载环境变量; Taskfile 会默认加载同级目录下的 .env
文件, 也可以在 Taskfile 内通过 dotenv
命令来配置特定文件:
version: '3'dotenv: [".env", ".testenv"]tasks:default:cmds:- echo "$ABCD"- echo "$TESTENV"
增强变量
除了标准的环境变量以外, 在 Taskfile 中还内置了一种使用更加广泛的增强变量 vars
; 该变量模式可以通过 go 的模版引擎进行读取(插值引用), 且具有环境变量不具备的特殊特性. 以下为 vars 变量的示例:
version: '3'# 全局 var 变量
vars:GLOBAL_VAR: "global var"tasks:testvar:# task var 变量vars:TASK_VAR: "task var"cmds:- "echo {{.GLOBAL_VAR}}"- "echo {{.TASK_VAR}}"
除了上面与环境变量类似的使用以外, vars 增强变量还支持动态定义; 常见的场景, 比如我们想每次 task 执行时都获取当前的 git commit id, 此时可以使用 vars 的动态定义特性:
version: '3'tasks:build:cmds:- go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.govars:# 每次任务执行时, GIT_COMMIT 都会调用 shell 命令来生成这个变量GIT_COMMIT:sh: git log -n 1 --format=%h
vars 变量还内置了一些特殊的预定义变量, 例如 {{.TASK}}
变量永远表示当前的任务名称、{{.CLI_ARGS}}
可以引用命令行输入等.
version: '3'tasks:yarn:cmds:- yarn {{.CLI_ARGS}}
此时如果执行 task yarn -- install
, 那么 {{.CLI_ARGS}}
值将会变成 install
从而执行 yarn install
命令.
除此之外, vars 变量还具备一些其他特性, 比如跨任务引用时可进行覆盖传递等, 这些特性将会在后面介绍.
执行目录
Taskfile 内定义的 task 默认在当前目录下执行, 如果期望在其他目录执行, 无需手动编写 cd
等命令, 可以直接通过配置 dir
参数来设置执行目录:
version: '3'tasks:test1:dir: /tmp # 在指定目录执行cmds:- "ls"
任务依赖
在 CI 等环境的使用中, 我们常常需要定义任务的执行顺序和依赖关系; Taskfile 中通过 deps
配置来提供任务依赖关系的支持:
version: '3'tasks:build-jar:cmds:- echo "编译 jar 包..."build-static:cmds:- echo "编译前端 UI..."build-docker:deps: [build-jar, build-static]cmds:- echo "打包 docker 镜像..."
任务调用
当我们在 Taskfile 中定义了多个任务时, 很可能一些任务具有一定的相似性, 此时我们可以通过任务互相调用和 vars 变量动态覆盖的方式来定义模版 Task:
version: '3'tasks:docker:cmds:#- docker build -t {{.IMAGE_NAME}} {{.BUILD_CONTEXT}}- echo {{.IMAGE_NAME}} {{.BUILD_CONTEXT}}build-backend:cmds:- task: docker # 引用其他 taskvars: { # 动态传入变量IMAGE_NAME: "backend",BUILD_CONTEXT: "maven/target"}build-frontend:cmds:- task: dockervars: {IMAGE_NAME: "frontend",BUILD_CONTEXT: "public"}default: # default 用于在命令行不显示输入任何 task 名称时调用cmds:- task: build-backend- task: build-frontend
引入其他文件
Taskfile 支持通过 includes
关键字来引入其他 Taskfile, 从而方便 Taskfile 的结构化处理.
需要注意的是, 由于引入的文件中可能会包含多特 task, 所以在使用时需要对引入的文件进行命名, 且通过命名引用目标 task:
version: '3'includes:file1: ./file1.yaml # 直接引用 yaml 文件dir2: ./dir2 # 引用目录时默认引用该目录下的 Taskfile.yaml
在引入其他 Taskfile 时, 默认情况下会在当前主 Taskfile 目录下执行命令, 我们同样可以通过 dir
参数来控制引入的 Taskfile 内的 task 在特定目录下执行:
version: '3'includes:dir1: ./dirtest.yaml # 直接在当前目录执行dir2:taskfile: ./dirtest.yamldir: /tmp # 在指定目录执行
defer 处理
熟悉 go 语言的同学应该知道, go 里面有个很方便的关键字 defer
; 该指令用于定义在最终代码收尾时要执行的动作, 常见的比如资源清理等. Taskfile 中同样支持了该指令, 可以方便我们在任务执行期间完成一些清理操作:
version: '3'tasks:default: # default 用于在命令行不显示输入任何 task 名称时调用cmds:- wget -q https://github.com/containerd/nerdctl/releases/download/v0.19.0/nerdctl-full-0.19.0-linux-amd64.tar.gz# 定义清理动作- defer: rm -f nerdctl-full-0.19.0-linux-amd64.tar.gz- tar -zxf nerdctl-full-0.19.0-linux-amd64.tar.gz
当然, defer 指令除了直接写命令以外, 还可以引用其他 task 完成清理:
version: '3'tasks:cleanup:cmds:- rm -f {{.FILE}}default: # default 用于在命令行不显示输入任何 task 名称时调用cmds:- wget -q https://github.com/containerd/nerdctl/releases/download/v0.19.0/nerdctl-full-0.19.0-linux-amd64.tar.gz# 引用其他 task 进行清理, 同时也可以传递动态变量- defer: {task: cleanup, vars: {FILE: nerdctl-full-0.19.0-linux-amd64.tar.gz}}- tar -zxf nerdctl-full-0.19.0-linux-amd64.tar.gz
4. 高级应用
动态检测
输出检测
在某些时候, 一些任务我们可能期望进行缓存处理, 比如说已经下载好了文件就不要重复运行下载; 针对于这种需求, Taskfile 允许我们定义源文件和生成的文件, 通过这组文件的 hash 值来确定是否需要执行该任务:
version: '3'tasks:default:cmds:- wget -q https://github.com/containerd/nerdctl/releases/download/v0.19.0/nerdctl-full-0.19.0-linux-amd64.tar.gzsources:- testfilegenerates:- nerdctl-full-0.19.0-linux-amd64.tar.gz
从上图中可以看到, 当首次执行任务时会生成 .task
目录, 该目录包含文件的 hash 值; 当重复执行任务时, 如果 hash 值不改变则真实任务不会真正执行. Taskfile 默认有两种文件检测的方式: checksum
、timestamp
, checksum
执行文件的 hash 检测(默认), 该模式只需要定义 sources
配置; timestamp
执行文件的时间戳检测, 该模式需要同时定义 sources
和 generates
配置.
version: '3'tasks:build:cmds:- go build .sources:- ./*.gogenerates:- app{{exeExt}}method: checksum # 指定检测方式
除了内置的两种检测模式外, 我们还可以通过 status
配置来定义自己的检测命令, 如果命令执行结果为 0, 则认为文件是最新的, 不需要执行任务:
version: '3'tasks:generate-files:cmds:- mkdir directory- touch directory/file1.txt- touch directory/file2.txt# test existence of filesstatus:- test -d directory- test -f directory/file1.txt- test -f directory/file2.txt
输入检测
上面的输出检测用于检测任务生成的文件结果等, 在某些情况下我们可能期望在运行任务之前来判断某个条件, 在完全不执行的情况下确定任务是否需要运行; 此时我们可以使用 preconditions
配置指令:
version: '3'tasks:generate-files:cmds:- mkdir directory- touch directory/file1.txt- touch directory/file2.txt# test existence of filespreconditions:- test -f .env- sh: "[ 1 = 0 ]"msg: "One doesn't equal Zero, Halting"
Go 模版引擎
在上面变量环节中已经展示了一部分模版引擎的使用, 实际上 Taskfile 内集成了 slim-sprig[1] 库, 该库中提供了一些比较便利的方法, 这些方法都可以在模版引擎内使用:
version: '3'tasks:print-date:cmds:- echo {{now | date "2006-01-02"}}
关于这些方法和模版引擎的使用具体请参考 Go Template 相关文档以及 slim-sprig[2] 文档.
交互式终端
有些任务命令可能需要交互式终端来执行, 此时可以为 task 设置 interactive
选项; 当 interactive
设置为 true
时, task 在运行时可以打开交互式终端:
version: '3'tasks:cmds:- vim my-file.txtinteractive: true
更多关于 Taskfile 的细节使用请阅读其官方文档[3], 本文限于篇幅不在过多阐述。
感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!
SpringCloud 优雅下线+灰度发布
云原生钻石课程 | 第3课:Kubernetes高级调度器原理详解
谈阿里云云效 DevOps | DevOps 不再只是 Jenkins
MySQL性能优化(七):MySQL执行计划,真的很重要,来一起学习吧
微服务架构下的核心话题 (三):微服务架构的技术选型
喜欢就点个"在看"呗,留言、转发朋友圈
Taskfile - 比 Makefile 更好用的构建工具相关推荐
- 更快的Maven构建工具mvnd和Gradle哪个性能更好?
作者 | 磊哥 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) Maven 作为经典的项目构建工具相信很多人已经用很久了,但如果体验过 Gradl ...
- Vue3 更高效的构建工具——Vite
文章目录 前言 一.Vite简介 1. Vite组成 2.为什么选 Vite? 二.Vite的优缺点 vite优点 vite缺点 三.使用Vite创建Vue3项目 1. 创建 vite 的项目 2.项 ...
- 前端三大构建工具 Webpack、Vite、Rollup 优劣势及原理分析
在刚刚结束的 VueConf2021 中,除了 Vue 3.0 以外,另外一个亮点就是下一代构建工具 Vite 了. 在尤雨溪分享的[ Vue 3 生态进展和计划]的演讲中,尤大神还特意提到 Vite ...
- 【Linux】三、Linux 环境基础及开发工具使用(上篇)|开发工具|编辑器-vim使用|sudo提升权限问题|编译器 - gcc/g++使用|项目自动化构建工构建工具-make/Makefile
目录 一.开发工具 二.Linux编辑器 - vim使用 2.1 vim 的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2. ...
- 【LINUX修行之路】——工具篇gcc/g++的使用和自动化构建工具make/makefile
学习范围:✔️LINUX ✔️ gcc/g++✔️make/makefile 本文作者:蓝色学者 文章目录 一.前言 二.概念 什么是gcc/g++? 什么是make/makefile? 三.教程 3 ...
- Maven官宣:干掉Maven和Gradle!推出更强更快更牛逼的新一代构建工具,炸裂!
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:网络 相信作为Java开发者的你早已经受够了maven的编译缓慢,但是又由于历史包袱.使用习惯等问题暂时切换不了其他更快的构建 ...
- 即将取代Maven和Gradle的新一代更强更快的构建工具(至尊典藏版)
目录 前言 1.介绍 2.安装 3.使用 3.1. 从GitHub下载压缩包 3.2. 解压并配置环境变量 3.3.测试 4.总结 前言 大家好,我是程序缘--幻羽,我又来了!! Maven和Grad ...
- Gulp.js—比Grunt更易用的前端构建工具-前端自动化
Gulp.js-比Grunt更易用的前端构建工具 Grunt是目前最流行的前端构建工具,对前端的效率帮助非常大,但Grunt并非完美无缺,json描述任务的方式,显得过于繁琐和不够简单,对于新手来说, ...
- 【githubshare】开源的可视化数据管道构建工具,以更简便的方式,快速构建数据
推荐 GitHub 上一款开源的可视化数据管道构建工具:Orchest.以更简便的方式,快速构建数据管道,无需框架和 YAML 配置,可直接通过 Python.R.Julia 来编写代码,处理数据.一 ...
最新文章
- 大数据学习——:wq不能退出vi编辑器
- 操作符offset 和 jmp指令
- ES6入门之Symbol
- 【OSG】OSG软件模块结构
- 廖雪峰Java1-2程序基础-7布尔运算符
- Zen Garden驾到:首批Metal游戏已登录iTunes应用商店
- python中复制n次字符串_Python正则表达式,如何将字符串匹配n次 - python
- navigationItem和navigationBar相关性
- 模型房推荐_【自带水乐园】“巴洛克堡城”酒店,人均200+入住家庭房,乐享下午茶+自行车+游船+萌宠乐园!...
- linux添加pacman命令,pacman 命令详解
- express 文件服务器,Express搭建一个简单后台服务器
- iphone mac地址是否随机_iPad 的 Mac 地址是否会随机更换,如何关闭呢
- 前端学习笔记 - promise是什么?能解决什么问题?
- 学习...笔记05:时间,空间,时空傅里叶变换的基本技巧、获取自旋波的频谱图和色散图
- markdown语法手册完整版
- Android实现一键开启自由窗口、分屏、画中画模式——画中画模式
- 设置安卓app页面强制横屏或者竖屏,不随手机姿势变化
- 《冲动的惩罚》歌词分析
- 安徽大学教育部计算机,2014安徽大学计算机教学部试题及答案
- 激活函数Sigmoid