MarkdownベースのGo製タスクランナー「xc」のススメ
Goにおけるタスクランナーの歴史
npmならnpm run
、denoならdeno task
など言語ツールにタスクランナー機能が付属していることがありますが、Goではそのような機能は提供されていません。
そこでGoのプロジェクトではMakefileがタスクランナーとして用いられることがしばしばありますが、独自の文法、.PHONY
を大量に書く必要がある、Makefile警察が飛んでくる、などの問題があります。
Makefile警察「ぐぬぬぬ…」 #taskfile - Qiita
タスクランナーとしてMakefileを使うことから脱却すべく、巷ではYAMLベースの「Task」やGoベースの「Mage」が用いられている印象です。
どちらも多少試したことはありますが、主に以下の点が気になりました。
- Taskfile.ymlやmagefile.goといったツール独自のファイルを置く必要がある
- これはMakefileも同様
- Go製とはいえプロジェクトメンバー全員がツールのインストールを半強制される
-
make
は大体のLinux環境に入っているためギリ許せる -
go run
で動かせるとはいえコマンドが長い - コマンドを短く実行したくてタスクランナーを使っているのに...
-
- (主にMage) シェルスクリプトに近い形で書きたい
-
os.Exec("docker", "compose", "up", "-d")
のようには書きたくない - 目的はコマンドを短く実行することであってGoでコマンドを実行することではない
- そこまで複雑なエラーハンドリングも必要ない
-
他に良いGo製のタスクランナーがないか探していたところ、「xc」というMarkdownベースのタスクランナーを見つけました。
Markdown内のコマンドを実行するツールはGoogleが作っているTypeScript製の「zx」が有名ですね。
7/24追記:似たツールに「runme」があるそうです。企業が管理しているOSSでxcより開発が盛んなため、runmeの方が安定感があるかもしれません(Goとnpmでインストールできるのも結構嬉しそうです)。本記事ではxcの解説をします。
7/24追記:traP内だとtraPortfolioというレポジトリでxcが使われています。使い方の参考になるかもしれません。
xcの利点
xcはタスクの処理とドキュメントが分離している問題を解決するために作られたそうです。通常のタスクランナータスクを専用のファイル(Makefile、package.jsonなど)に記述した上でさらにそのタスクの使い方をREADMEに書く必要がありますが、xcではその必要はありません。
The problem xc is intended to solve is scripts maintained separately from their documentation. Often a Makefile or a package.json will contain some useful scripts for developing on a project, then the README.md will surface and describe these scripts. In such a case, since the documentation is separate, it may not be updated when scripts are changed or added. xc aims to solve this by defining the scripts inline with the documentation.
VSCode拡張も用意されており、ワンタップで実行することもできます。
また、先ほど挙げたTaskやMageの課題はxcによって解決することができます。
- 独自のファイルを置く必要がある
- README.mdはどのプロジェクトにも基本置かれる
- ツールのインストールを半強制される
- 1回しかタスクを実行しなければREADMEからコマンドをコピペするだけでOK
- 繰り返し実行したくなった時に初めてxcをインストールすれば良い
- (言語にタスクランナーが付属していればこんな問題は...)
- シェルスクリプトに近い形で書きたい
- コードブロック内に直接シェルスクリプトを書くことができる
xcの機能紹介
xcの機能はシンプルで、README.mdに各タスクのコマンドを記述することでそれらがxcを通して実行することができるようになります。
以下のようにTasks
というHeadingを置き、その下に各タスクの処理をコードブロック内に記述します。
説明や設定(Required:
、Inputs
など)も書くことができます。
(... READMEに書くべき諸々のこと)
# Tasks
## test
Test the project.
```bash
go test ./...
```
## tag
Deploys a new tag for the repo.
Specify major/minor/patch with VERSION
Inputs: VERSION
Requires: test
```bash
NEW_TAG=... # Inputsを使って処理を行う
git tag ${NEW_TAG}
git push origin ${NEW_TAG}
```
その後、xcを実行することでREADMEに記述したコマンドをタスクとして実行することができます。
xc tag major
xcの(まだ)イマイチなところ
まだいくつかイマイチなところもありますが、今のところ最低限の機能は使えています。
- カラー対応が貧弱
- Task(10k)やMage(4k)に比べるとスターが少ない(1k)
- 応援してあげてほしい
xcを使おう
xcの紹介でした。
traP (デジタル創作同好会 traP)は、 東京工業大学で最も活発なデジタル創作・プログラミング系サークルです。Zenn 上では主にメンバーによる技術ブログを掲載していますが、普段はホームページ上で投稿しています。こちらもぜひご覧ください。trap.jp
Discussion
zxはJavaScript向けのライブラリー(とそれを自動でimportした状態でスクリプトを実行するコマンド)なのでそうした機能はなかったかと
メインの機能ではないのかもしれませんが、Markdownファイルを対象にコードブロックを実行できる機能があると認識しています
おお、すみません、気づいてませんでした!