自动化任务管理 task

761 阅读3分钟

简介

任务是一个任务运行器/构建工具,旨在比GNU Make更简单,更易于使用。

安装

go install github.com/go-task/task/v3/cmd/task@latest

官方文档 Home | Task (taskfile.dev)

用法

开始

编写配置文件 Taskfile.yml

version: '3'  
  
tasks:  
    build:  
        cmds:  
            - go build -v -i main.go  
    assets:  
        cmds:  
            - minify -o public/style.css src/css

在该文件目录下运行命令

task assets build

其中 task是该软件,assets build是配置文件中的自定义任务名

配置文件基本结构

#版本号
version: '3'  


# 任务定义开始,固定
tasks:  
    #任务名称,自定义
    build:  
        #任务配置项 配置项很多
        cmds:  
            - go build -v -i main.go
            

支持的文件名

配置文件名支持如下:

  • Taskfile.yml
  • Taskfile.yaml
  • Taskfile.dist.yml
  • Taskfile.dist.yaml

文件名大小写均可

dist优先级比较低,会被非dist进行覆盖,一般本地使用Taskfile.yml,并设置到git护理文件中,Taskfile.yml用于生产,进行git提交。

环境变量

任务

配置项 env

使用符号 $

定义任务中的环境变量

version: '3'

tasks:
  greet:
    cmds:
      - echo $GREETING
    env:
      GREETING: Hey, there!

定义全局环境变量

version: '3'

env:
  GREETING: Hey, there!

tasks:
  greet:
    cmds:
      - echo $GREETING

.env文件

文件 .env 类似docker中的.env

KEYNBAME=VALUE

编写 taskfile.yml

version: '3'  
  
env:  
    ENV: testing  
    
dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']  
  
tasks:  
    greet:  
        cmds:  
            - echo "Using $KEYNAME and endpoint $ENDPOINT"

导入其他任务

配置项: includes

使用: 导入名:任务名 包括任务调用和命令调用两部分使用

eg:

version: '3'

includes:
  docs: ./documentation # will look for ./documentation/Taskfile.yml
  docker: ./DockerTasks.yml

其中docs和docker为自定义导入名。

使用特定系统任务文件

version: '3'

includes:
  build: ./Taskfile_{{OS}}.yml

指定任务目录

默认情况下,导入的任务执行时候使用的是顶层配置文件所在的目录,不会使用导入任务的目录,可以通过配置项 dir 进行指定

version: '3'  
  
includes:  
    docs:  
        taskfile: ./docs/Taskfile.yml  
        dir: ./docs

注意此处配置项写法,因为导入任务需要dir参数指定目录,无法直接使用配置文件地址进行配置,所以需要使用 taskfile 配置项进行显示配置。

导入文件可选

默认情况下,导入包要求必须存在,否则会报错,可以通过optional: true进行配置,消除不存在报错。

version: '3'

includes:
  tests:
    taskfile: ./tests/Taskfile.yml
    optional: true

tasks:
  greet:
    cmds:
      - echo "This command can still be successfully executed if ./tests/Taskfile.yml does not exist"

内部任务

内部任务概念是指由任务进行调用,用户不能命令调用,使用task --list-all时候不会进行该任务展示,更不可能用task命令去直接调用。

由关键字internal: true进行设置

导入任务设置后,其导入的所有任务均被置为内部任务

包含任务的变量定义

配置项:vars

注意 vars配置项不仅仅用在 includes下,后边会介绍vars

version: '3'

includes:
  backend:
    taskfile: ./taskfiles/Docker.yml
    vars:
      DOCKER_IMAGE: backend_image

  frontend:
    taskfile: ./taskfiles/Docker.yml
    vars:
      DOCKER_IMAGE: frontend_image

空间别名

导入名过长可以定义别名。

配置项: aliases

version: '3'

includes:
  generate:
    taskfile: ./taskfiles/Generate.yml
    aliases: [gen]

定义别名后在命令中或者任务中都可通过别名:任务名进行调用

内部任务

在导入任务时候简单介绍过,这块介绍在任务中定义内部任务

配置项: internal:true

version: '3'

tasks:
  build-image-1:
    cmds:
      - task: build-image
        vars:
          DOCKER_IMAGE: image-1

  build-image:
    internal: true
    cmds:
      - docker build -t {{.DOCKER_IMAGE}} .

任务目录

配置项: dir

设定任务的运行目录

version: '3'

tasks:
  serve:
    dir: public/www
    cmds:
      # run http server
      - caddy

任务依赖

配置项: deps:[任务1,任务2,...]

特点:

  1. 主任务会在所有以来任务运行完在运行
  2. 以来任务之间是并行运行
version: '3'

tasks:
  build:
    deps: [assets]
    cmds:
      - go build -v -i main.go

  assets:
    cmds:
      - minify -o public/style.css src/css

传递参数给依赖项

version: '3'

tasks:
  default:
    deps:
      - task: echo_sth
        vars: {TEXT: "before 1"}
      - task: echo_sth
        vars: {TEXT: "before 2"}
    cmds:
      - echo "after"

  echo_sth:
    cmds:
      - echo {{.TEXT}}

调用其他任务

调用的任务会按照顺序进行调用

配置项: task

version: '3'

tasks:
  main-task:
    cmds:
      - task: task-to-be-called
      - task: another-task
      - echo "Both done"

  task-to-be-called:
    cmds:
      - echo "Task to be called"

  another-task:
    cmds:
      - echo "Another task"

任务中的变量 默认变量

version: '3'

tasks:
  greet:
    vars:
      RECIPIENT: '{{default "World" .RECIPIENT}}'
    cmds:
      - echo "Hello, {{.RECIPIENT}}!"

  greet-pessimistically:
    cmds:
      - task: greet
        vars: {RECIPIENT: "Cruel World"}

任务的触发控制

通过文件变动

version: '3'
vars:
  VER: '3'
tasks:
  build:
    deps: [touchtxt]
    cmds:
      - cat d.txt
  
  touchtxt:
    cmds:
      - echo 1234 > d.txt
    sources:
      - b.txt

b.txt 有变动touchtxt任务才会执行 默认情况下 根据source计算任务hash值,有变动则运行任务。 也可以设置根据文件时间戳进行任务触发

如下配置

generates:  
    - app{{exeExt}}  
method: timestamp

根据时间戳配置时候 generates必须配置

任务状态控制任务执行

配置项: status

特点: 返回错误则执行任务,返回正常不执行任务。正常代表着状态未改变,不需要执行

version: '3'

tasks:
  generate-files:
    cmds:
      - mkdir directory
      - touch directory/file1.txt
      - touch directory/file2.txt
    # test existence of files
    status:
      - test -d directory  //存在则返回exit 0 
      - test -f directory/file1.txt
      - test -f directory/file2.txt
      - grep -q '"dev": false' ./vendor/composer/installed.json

使用编程方式控制任务执行

配置项: preconditions

特点: 返回0 则执行

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 ]"                            //sh 配置项 map写法
        msg: "One doesn't equal Zero, Halting"     //返回异常时候打印

如果任务是由多个其他任务组成或者依赖多个任务,则 source 和 status 不会影响整体任务执行,只会影响当前任务的是否执行,preconditions则会影响整体任务执行,有一个报错则停止继续执行。

运行时间控制

配置项: run 可用配置:

  • always :(默认)始终尝试调用任务,而不管之前的执行次数如何
  • once:无论引用数量多少,仅调用此任务一次
  • when_changed : 仅对传递到任务中的每个唯一变量集调用任务一次

变量

在进行变量插值时,Task 将查找以下内容。它们按重要性顺序(即最重要的第一)列在下面:

静态变量

关键字: var

使用: {{.变量名}}

version: '3'

tasks:
  print-var:
    cmds:
      - echo "{{.VAR}}"
    vars:
      VAR: Hello!

动态变量

version: '3'

tasks:
  build:
    cmds:
      - go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
    vars:
      GIT_COMMIT:
        sh: git log -n 1 --format=%h

将cli参数转发到命令

$ task yarn -- install

version: '3'

tasks:
  yarn:
    cmds:
      - yarn {{.CLI_ARGS}}

任务清理 defer

version: '3'

tasks:
  default:
    cmds:
      - mkdir -p tmpdir/
      - defer: { task: cleanup }
      - echo 'Do work on tmpdir/'

  cleanup: rm -rf tmpdir/

配置项说明

version: '3' //固定

env: 
    GREETING: Hey, there!       //全局环境变量 使用 用$
//env: {GREETING: Hey, there!} //第二种写法

dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']  //定义env导入名

var:
    xxx: yyy //定义变量

includes: //导入任务
    docs: ./documentation                           //docs 导入名 指定导入目录下寻找配置文件 
    docker: ./DockerTasks.yml                       //导入指定配置文件
    docs2: 
        taskfile: ./docs/Taskfile.yml               //taskfile 关键字 指定导入文件 
        dir: ./docs                                 //dir 关键字 指定运行目录
        optional: true                              //optional 导入文件可选
        internal: true                              //internal 关键字 内部任务
        aliases: [gen,...]                          //aliases 关键字 导入别名
      //aliases:         
      //   - gen
      //   -                                         //导入别名第二种写法
     backend: 
         taskfile: ./taskfiles/Docker.yml 
         vars: 
             DOCKER_IMAGE: backend_image           //vars 关键字 导入变量
      // vars: { DOCKER_IMAGE: backend_image }     //第二种写法
          
        
        
tasks: //任务
    build-image-1:                                   //任务名称
        vars: 
            DEMO: demo                               // 任务变量指定
        cmds:                                        //任务
            - task: build-image                      //task 关键字 调用其他任务
              vars:                                  //vars 关键字 指定变量
                  DOCKER_IMAGE: image-1 
    build-image: 
        internal: true                               //internal: true 指定内部任务
        cmds: 
            - docker build -t {{.DOCKER_IMAGE}} .    //{{.DOCKER_IMAGE}} 模板语法
        dir: 
           public/www                                //指定目录
            
        
    build:               
        deps: [assets]                                //任务依赖 依赖项之间并行运行 
      //deps:
      //    - assets                                  //任务依赖第二种写入
        cmds:  
            - go build -v -i main.go                  //等待依赖项运行完在运行 
    assets: 
        cmds: 
            - minify -o public/style.css src/css
            
    main-task: 
        cmds:                                         //调用其他任务
            - task: task-to-be-called                 //任务会按照顺序执行
            - task: another-task 
            - echo "Both done"
           
    touchtxt:
      cmds:
        - echo 1234 > d.txt
      sources:              //sources 关键字 查看源文件或者目录是否变动 变动触发任务
        - b.txt
      generates:            //sources generates method: timestamp 联合使用 按照源文件时间戳是否变动来控制是否执行任务
        - app{{exeExt}}  
      method: timestamp
      status:              //status 关键字 后边参数返回异常及exit 非0 则执行任务
          - test -f a.txt  // shell 返回 非0 执行 否则不执行
      preconditions:       //preconditions 与status相反 返回0 正常则执行
           - test -f .env
           - sh: "[ 1 = 0 ]"                            //sh 配置项 map写法
             msg: "One doesn't equal Zero, Halting"     //返回异常时候打印
       run: always|once|when_changed                   //调用时间控制