タスクに実行時のオプションを渡したい

【mise】mise runでタスクを定義して実行する で紹介したタスクは、runに書いたコマンドをそのまま実行するだけである。デプロイ先の環境名や詳細ログの有無など、実行のたびに変わる値をタスクに渡したい場合がある。

古いmiseには{{arg()}}のようなTeraテンプレート関数でコマンドライン引数を埋め込む方式があったが、この方式はmise run testのように実行すると次の警告が出る。

mise WARN  deprecated [tera_template_task_args]: Task 'test' uses deprecated Tera template functions (arg(), option(), flag()) in run scripts. Use the 'usage' field instead. See https://mise.jdx.dev/tasks/task-arguments.html This will be removed in mise 2027.5.0.

現在のmiseでは、タスクの引数・フラグはusageフィールドで定義するのが推奨される方法である。

usageフィールドで引数を定義する

mise.tomlのタスクにusageを追加し、Usage仕様の文法で引数(arg)とフラグ(flag)を定義する。

[tasks.deploy]
description = "アプリをデプロイする"
usage = '''
arg "<environment>" help="デプロイ先の環境" {
  choices "dev" "staging" "prod"
}
flag "-v --verbose" help="詳細ログを出力する"
flag "--region <region>" help="デプロイ先リージョン" default="ap-northeast-1"
'''
run = '''
echo "Deploying to ${usage_environment} in ${usage_region}"
if [ "${usage_verbose:-false}" = "true" ]; then
  echo "verbose mode"
fi
'''

定義した引数・フラグは、usage_を接頭辞に付けた環境変数としてrun内から参照できる。

$ mise run deploy staging --verbose --region us-west-2
Deploying to staging in us-west-2
verbose mode

必須の引数を検証する

argは既定で必須である。指定せずに実行すると、コマンド本体を実行する前にエラーとなる。

$ mise run deploy
mise ERROR failed to validate task deploy
mise ERROR Missing required arg: <environment>

choicesで許可した値以外を指定した場合もエラーになる。

$ mise run deploy invalidenv
mise ERROR failed to validate task deploy
mise ERROR Invalid choice for arg environment: invalidenv, expected one of dev, staging, prod

コマンド本体を実行する前に引数の妥当性を検証できるため、run側で不正な値を個別にチェックする必要がない。

ヘルプを自動生成する

usageの定義から、--helpオプション付きで実行した際のヘルプが自動的に生成される。

$ mise run deploy --help
アプリをデプロイする

Usage: deploy [-v --verbose] [--region <region>] <environment>

Arguments:
  <environment>  デプロイ先の環境
                 [possible values: dev, staging, prod]

Flags:
  -v, --verbose          詳細ログを出力する
      --region <region>  デプロイ先リージョン
                         (default: ap-northeast-1)
  -h, --help             Print help

ファイルタスクで#USAGEコメントを使う

ファイルタスクではusageフィールドの代わりに、スクリプト先頭のコメントで#USAGEを使って同じ内容を定義できる。タスクの説明は#MISE description="..."で設定する。

#!/usr/bin/env bash
#MISE description="挨拶を表示する"
#USAGE arg "<name>" help="挨拶する相手の名前"
#USAGE flag "--loud" help="大文字で叫ぶ"

NAME="${usage_name}"
if [ "${usage_loud:-false}" = "true" ]; then
  echo "hello, ${NAME}" | tr '[:lower:]' '[:upper:]'
else
  echo "hello, ${NAME}"
fi

【mise】mise tasks lsでタスク一覧を詳しく確認する で確認すると、descriptionがタスク一覧にも表示される。

$ mise tasks ls
deploy  アプリをデプロイする
greet   挨拶を表示する

引数を渡して実行すると、TOMLタスクと同様にusage_接頭辞の環境変数として参照できる。

$ mise run greet suer --loud
HELLO, SUER