タスクランナーしたい(task

$ task タスク名

Taskタスクランナー と呼ばれるコマンド実行を自動化するツールです。 GNU Makeと同じような役割ですが、 YAML形式の設定ファイル(Taskfile.yml)により、 簡潔かつ柔軟にタスクを記述できます。

インストールしたい(go-task

$ brew install go-task

Homebrewでgo-taskフォーミュラをインストールします。

注釈

taskというフォーミュラがありますが、まったく別物です。

$ pip install go-task-bin

taskはGo言語で書かれたツールですが、 go-task-binというPythonパッケージでも提供されています。

初期化したい(task --init

// 初期化
$ task --init
Taskfile created: Taskfile.yml

// デフォルトのタスクを実行
$ task
Hello, World!

task --initで、Taskfile.ymlのひな形を生成します。 タスクランナーを導入したいディレクトリで実行してください。

ひな型はデフォルトで「Hello, World」を表示するようになっているので、 そのままtaskコマンドを実行して動作確認できます。

設定ファイルしたい(Taskfile.yml

# https://taskfile.dev

version: '3'

# グローバルに共有する変数
vars:
  GREETING: Hello, World!

# タスクの定義
tasks:
  default:
    cmds:
      - echo "{{.GREETING}}"
    silent: true

  タスク名:
    desc: タスクの説明
    dir: 実行するパス
    cmds:
      - コマンド1
      - コマンド2

Taskfile.ymlでタスクを設定できます。 Taskfile.ymlプロジェクトルート に配置してください。 前述したようにtask --initでひな形を生成し、編集する方法がオススメです。

varsセクションで変数を定義できます。 tasksセクションに、タスク名とその実行内容を定義します。

タスクしたい(cmds / desc

tasks:
  <タスク名>:
    desc: タスクの説明(オプション)
    cmds:
      - 実行コマンド1
      - 実行コマンド2

tasksセクションでは、1つ以上のタスクを定義できます。 それぞれのタスクには、タスク名cmdsが必須です。 cmdsはリスト形式で複数のコマンドを順番に指定できます。 descで簡単な説明をつけるとよいです。

tasks:
  docs:
    desc: Serve documentation locally
    cmds:
      - uv run mkdocs serve -o

  docs:build:
    desc: Build documentation as static HTML
    cmds:
      - uv run mkdocs build

タスク名はネストできます。 タスクの目的ごとにカテゴリー化すると見通しがよくなります。

注釈

task --list で期待通りの順番に並ばないのは謎です。

ディレクトリを指定したい(dir

tasks:
  html:
    desc: Hot-reload Sphinx docs
    dir: docs
    cmds:
      - poetry run make livehtml

dirオプションを使うと、コマンドを実行するディレクトリを設定できます。 パスはプロジェクトルートからの相対パスで指定できます。 ディレクトリが存在しない場合はエラーになります。

条件分岐したい(status / preconditions

tasks:
  download:
    desc: Download file (skip if already downloaded)
    status:
      - test -f archives/archived.zip
    cmd:
      - wget https://example.com/download.zip
      - mv download.zip archives/archived.zip

statusオプションを使うと、条件を満たしている場合にタスクの実行をスキップできます。 通常はtestコマンドを使って、ファイル(やディレクトリ)の存在を確認します。 上記のサンプルでは、archives/archived.zipが存在する場合、ダウンロードをスキップします。

tasks:
  clean:
    desc: Remove build files
    preconditions:
      - sh: test -d build
        msg: "[Error] Build directory does not exist"
    cmds:
      - rm -rf build

preconditionsを使うと、タスクを実行する前に必要は条件をチェックできます。 条件が満たされない場合は、タスクは中断され、指定したmsgが表示されます。 上記のサンプルではbuildディレクトリが存在しない場合に エラーメッセージが表示されます。

変数したい(vars

vars:
  G4VERSION: "v11.3.2"
  G4HOME: "{{.HOME}}/geant4"
  QT_PATH:
    sh: brew --prefix qt@5

tasks:
  setup:
    cmds:
      - echo "Installing Geant4 {{.G4VERSION}} to {{.G4HOME}}"
      - echo "Qt is located at {{.QT_PATH}}"

varsセクションでタスク全体で利用するグローバル変数を定義できます。 {{.変数名}}の形式で、Goテンプレート構文による変数展開ができます。 shオプションを使うと、シェルコマンドの出力を変数として使用できます。

$ task setup G4VERSION=v11.2.1

varsで定義した変数は、taskコマンドの引数として上書きできます。

サンプルしたい

実際に設定してみて、便利だと思ったタスクを紹介します。

Poetryで更新したい(task update

tasks:
  export:
    desc: Export requirements.txt
    cmds:
      - poetry export --output requirements.txt

  update:
    desc: Update dependencies
    cmds:
      - poetry update
      - task: export

Pythonパッケージを更新する設定です。 最近はpyproject.tomlで依存関係を管理するのが主流ですが、requirements.txtが必要な場合もまだまだあります(例:Read the Docs)。 このタスクを設定すると、パッケージ更新とrequirements.txt生成を一括で実行できるようになります。

VS Codeしたい(task code

tasks:
  code:
    desc: Start VS Code
    cmds:
      - code .

プロジェクトルートでVS Codeを開く設定です。 code .をサブディレクトリで実行すると、親ディレクトリの構造にアクセスできません。 このタスクの設定すると、プロジェクト内のどこからでも、常にプロジェクトルートで開くことができます。 地味な設定ですが、かなり便利だと思っています。

リポジトリを開きたい(task view

vars:
  GITLAB_REPOS: "https://gitlab.com/GROUP/PROJECT/"
  GITLAB_PAGES: "https://GROUP.gitlab.io/PROJECT/"

tasks:
  view:
    desc: Open repository
    cmds:
      - open {{.GITLAB_REPOS}}

  view-issues:
    desc: Open GitLab issues
    cmds:
      - open {{.GITLAB_REPOS}}/-/issues/

  view-mr:
    desc: Open GitLab Merge Requests
    cmds:
      - open {{.GITLAB_REPOS}}/-/merge_requests/

  view-pages:
    desc: Open GitLab Pages
    cmds:
      - open {{.GITLAB_PAGES}}

GitLabリポジトリをブラウザで開く設定です。 リポジトリ本体、イシューやMRの一覧を設定しておくと便利です。