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 vartasks: 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.go vars: # 每次任务执行时, 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 # 引用其他 task vars: { # 动态传入变量 image_name: backend, build_context: maven/target } build-frontend: cmds: - task: docker vars: { 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.yaml dir: /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.gz sources: - testfile generates: - 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: - ./*.go generates: - 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 files status: - 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 files preconditions: - 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.txt interactive: true 更多关于 taskfile 的细节使用请阅读其官方文档[3], 本文限于篇幅不在过多阐述。
首个机器人移动营业厅推出
OpenHarmony页面级变量的状态管理
iPhone8什么时候上市?iPhone8最新消息:iPhone8功能,突破很大iPhone8这个新功能让你无法抗拒!
三端稳压管工作原理_如何用万用表判断三端稳压模块的好坏
2023英特尔on技术创新大会:英特尔研究院展示多项技术“魔法”
Taskfile的安装及使用
苏宁快消集团常务总裁卞农:2019年苏宁小店进入精细化运营阶段
北方广微与西工大联合推出非制冷红外偏振焦平面探测器,有何特点
简易超声波雾化器的制作
村田2019年预测“上半年缺乏动力”
四层交换机的特点
笔记本简介
华为开始收取5G专利费 那么到底能收多少呢?
一份不容错过的5G终端热资料
什么样的MCU电路或者场合中用复位芯片
家庭灭火系统中的短消息报警模块设计
一文详解机器学习中的梯度提升机
用于智能家居网关的802.11ac双频WiFi模块SKW93A
汽车电瓶放着不开多长时间才会没电?
浅谈处理220千伏变电站主变重载的三种方法