跳转到主要内容

欢迎Gophers!在本教程中,我将展示如何在 Go 应用程序开发中利用 Taskfiles 来获得名利。

(免责声明):本文是在 CircleCI 中采用 Taskfiles 来帮助他们采用 Go 的。我不能因为发现 Taskfiles 而获得任何功劳,因为这是另一个突出优势的团队。

如果您已经加入 Go 社区一段时间,您可能熟悉在 Go 应用程序中使用 Makefile 或类似的构建工具,您甚至可能选择了某种形式的脚本来捕获一些较长的命令以便更轻松发展。

你们当中的受虐狂甚至可能刚刚将所有常规命令都记入了记忆中。如何记住所有不同的构建参数和设置超出了我的范围,但对你能够记住的严重赞誉。

但毫无疑问,Taskfiles 是我最喜欢的新方法之一,它可以在一个地方捕获一些我必须在日常开发活动中运行的更繁琐的命令。

示例任务文件


让我们快速看一下在 taskfile.dev 主页上演示的示例 Taskfile.yml -

version: '3'

tasks:
  hello:
    cmds:
      - echo 'Hello World from Task!'
    silent: true

乍一看,这看起来与 Makefile 非常相似,但是,我发现该工具具有更好的用户体验,并提供了超越 Makefile 系统所具有的丰富功能层。

安装任务工具


对于 mac 开发人员,使用 homebrew 安装很容易:

$ brew install go-task/tap/go-task


对于 Windows 和 *Nix 用户,您应该能够在此处找到有关您正在运行的任何操作系统风格的说明:任务文件安装

附加上下文


安装任务工具后,您就可以运行 Taskfile.yml 中定义的任务,如下所示:

$ task hello
Hello World from Task!


超级直观对吧?

如果您想为每个定义的任务添加更多上下文,您可以添加一个 desc: 块,然后允许您列出如下命令:

version: '3'

tasks:
  hello:
    desc: "A Hello World Task"
    cmds:
      - echo 'Hello World from Task!'
    silent: true

$ task --list
task: Available tasks for this project:
* hello:        A Hello World Task

对于更大、更复杂的项目,如果您想了解如何在本地启动项目等操作,这将非常方便。

在子目录中运行


过去,我发现自己想在特定的子目录中运行特定的命令。使用 Make 这有点问题。您要么必须将命令链接在一起,例如: (cd terraform && make) 这会增加复杂性,要​​么您必须在 make 命令中使用 -C 标志传递目录。

Taskfiles 采用的方法似乎要简单得多:

version: '3'

tasks:
  hello:
    desc: "A Hello World Task"
    cmds:
      - echo 'Hello World from Task!'
    silent: true
  
  terraform-apply:
    desc: "A task demonstrating a subdir"
    dir: terraform
    cmds:
      - pwd 
    silent: true

现在,每当我们尝试运行 terraform-apply 任务时,它都会在 terraform 子目录中执行该命令,这真的很不错👌

$ task terraform-apply
/path/to/myproject/terraform


任务依赖


假设您有一个任务只能在其他任务执行后才能运行。这在您的任务文件中定义变得微不足道。

在我们的任务定义中使用 deps: [] ,我们可以列出我们运行任务所需的所有依赖项,它们将为我们执行:

version: '3'

tasks:
  hello:
    desc: "A Hello World Task"
    cmds:
      - echo 'Hello World from Task!'
    silent: true
  
  terraform-plan:
    desc: "A mock terraform plan"
    dir: terraform
    cmds:
      - echo "Running terraform plan..."
    silent: true


  terraform-apply:
    desc: "A mock terraform apply"
    dir: terraform
    deps: [terraform-plan]
    cmds:
      - echo "Running terraform apply..."
    silent: true

现在,当我们运行它时,我们应该看到 terraform-plan 在 terraform-apply 之前执行:

$ task terraform-apply
Running terraform plan...
Running terraform apply...


再一次,在我看来,与 Make 相比,编写这些文件的用户体验要好得多。

动态变量


在某些情况下,您需要能够将动态值传递到您的任务中。使用 vars 块,我们可以定义特定的变量和我们需要获取它们的脚本,如下所示:

version: '3'

tasks:
  hello:
    desc: "A Hello World Task"
    cmds:
      - echo 'Hello World from Task!'
    silent: true

  install:
    desc: "An example of dynamic variables"
    cmds:
      - echo 'Installing tool into {{.HOMEDIR}}'
    silent: true
    vars:
      HOMEDIR:
        sh: echo $HOME/.mydir
  
  terraform-plan:
    desc: "A mock terraform plan"
    dir: terraform
    cmds:
      - echo "Running terraform plan..."
    silent: true


  terraform-apply:
    desc: "A mock terraform apply"
    dir: terraform
    deps: [terraform-plan]
    cmds:
      - echo "Running terraform apply..."
    silent: true



在这里,我们定义了具有动态变量 HOMEDIR 的安装任务。对于更复杂的用例,您可能会卷曲 API 以获取一些数据,或者执行一些更高级的 shell 命令。

如果我们要执行这个命令,你会看到正确的 HOMEDIR 值被插入到执行的命令中:

task install
Installing tool into /Users/elliotforbes/.mydir


Go 开发人员的通用任务文件


现在我们已经介绍了任务文件的一些优点,是时候看看在 Go 应用程序中更逼真的 Taskfile.yml 实现会是什么样子了:

 

build:
    desc: "build the compiled binary"
    cmds:
      - go build -o app cmd/server/main.go

  test:
    desc: "run all unit tests"
    cmds:
      - go test -v ./...

  lint:
    desc: "lint the code"
    cmds:
      - golangci-lint run

  run:
    desc: "runs our app and any dependencies defined within the docker-compose.yml"
    cmds:
      - docker-compose up --build

  integration-test:
    desc: "starts our app and then attempts to run our integration tests"
    cmds:
      - docker-compose up -d db
      - go test -tags=integration -v ./...
    env:
      DB_USERNAME: postgres
      DB_PASSWORD: postgres
      DB_TABLE: postgres
      DB_HOST: localhost
      DB_PORT: 5432
      DB_DB: postgres
      SSL_MODE: disable

  acceptance-tests:
    desc: "starts our app and then attempts to run our e2e tests"
    cmds:
      - docker-compose up -d --build
      - go test -tags=e2e -v ./...

这只是我在 Go 应用程序中包含的一些标准命令的一个轻量级示例。随着它的复杂性趋于增长,这个列表变得更长。

这种方法的优点还意味着我在 CI 管道中运行这些相同的任务要容易得多。我只需要确保在我的管道中安装了 Taskfile 工具,然后我可以重用这些命令来构建我的自动化。

结论


好吧,希望这篇文章让你考虑将 Taskfiles 用于你自己的 Go 应用程序开发。它们确实让我在日常工作中的生活变得更简单,我无法强调与更传统的工具相比,我更喜欢 Taskfiles 的用户体验。

如果您对这种方法有任何疑问或意见,我很乐意在下面的评论部分听到他们的意见!

文章链接