🦜

Go製のTaskでクロス環境タスクランナーを書く方法

2024/09/10に公開

えらく、反響があったのでちょっとまとめてみようかなと。
https://x.com/nobonobo/status/1832915385777090832

Taskとは?

ドキュメントホーム:
https://taskfile.dev/

リポジトリ:
https://github.com/go-task/task

特徴

  • タスクランナーやビルドツールとしてのGNU Makeよりもシンプルに記述
  • シンタックスはYAMLによる宣言的でトリッキーな記述方法を含まない
  • インストール手順はほとんどの環境むけに整備済みで最悪GoとGitさえあれば簡単にインストールできる
  • Makefileの代わりにTaskfile.ymlを書く
  • Goのtext/template機能がプリプロセッサの役割を担っている

どういった用途に向いている?

  • 主にMakefileをタスクランナー代わりに使っていた人向けです
  • 複雑な依存を少ない行数で記述するビルドツールとしてはGNU Makeのほうが優れています
  • GoやRustでは依存解決しつつビルドするツールを自前で持っているのでこれらのタスクランナーとして向いています(が、Rustにはcargo-makeというタスクランナーがありますね)
  • つまり処理系依存のビルドツールはそれぞれ処理系向きのツールを使い、タスクランナー部分を提供するのにTaskは向いています

インストール

ここに様々なユースケースのインストール方法があります。
GitHub-Actions上で使うための方法も整備済みです。
https://taskfile.dev/installation/

シンプルな使い方

Taskfile.yml
version: "3"
tasks:
  build:
    env:
      GOOS: js
      GOARCH: wasm
    cmds:
      - go build -o './docs/main.wasm' .
  • tasks配下には「任意のラベル:タスク定義」の配列を定義します
  • cmds配下の配列にシーケンシャルなコマンドリストを記述します
$ task build
task: [build] go build -o './docs/main.wasm' .

タスク依存は?

回答: depsにてタスク名を記述

Taskfile.yml
version: "3"
tasks:
  pre:
    cmds:
      - mkdir -p ./docs
  build:
    deps: [pre]
    env:
      GOOS: js
      GOARCH: wasm
    cmds:
      - go build -o './docs/main.wasm' .
$ task build
task: [pre] mkdir -p ./docs
task: [build] go build -o './docs/main.wasm' .

前述のものはWindowsで動かないのでは!どうすれば?

回答: u-rootツール群を利用すると良いでしょう。

Taskfile.yml
version: "3"
tasks:
  pre:
    cmds:
      - go run github.com/u-root/u-root/cmds/core/mkdir@latest -p ./docs
  build:
    deps: [pre]
    env:
      GOOS: js
      GOARCH: wasm
    cmds:
      - go build -o './docs/main.wasm' .

まとめ

  • Task自体は非常にシンプルでほとんど機能が無い
  • Goと組み合わせることでクロス環境で動作するタスクランナーになる
  • シンプルがゆえにトリッキーな記述が生まれない
  • チームで共有するのに便利(チームメンバーの開発環境が多様でも問題ない)
  • あらゆる環境向けにインストール方法の整備が行き届いているのでCIに組み込むのにも容易
  • シェルコマンドの互換性はTask本体が改善を目指しているので今後に期待しましょう

Discussion