最近 config が YAML になっているアプリケーションが多い。ただ、自分は YAML の読み書きが苦手である。
設定を書くには機能が多すぎるのと、(config なので)ネストしやすいのにインデントが関わってくるのが苦手なのだと思う。
何度かハマった結果、これからは JSON に変換して読むことにした。JSON を読むのには慣れているし、jq
など色付・抽出するツールも持っているので最高 *1 。
YAML を JSON に変換するツールは世の中に多くあるが、そんなに大変じゃないので自分で作ることにした*2。
何で作るか
案1 Ruby で書く
Ruby は標準ライブラリに YAML パーサーが入っているので、適当な ruby のスクリプトを書けば目的は達成される。
ただ、そのためだけに Ruby 入れるのも嫌だな…って思ってやめた。
案2 Go で書く
Go のようなコンパイラ言語であれば、標準ライブラリに入ってなくともコンパイルすれば良いので楽である。
また、Go は goreleaser や go get などインストールしやすい環境が整っており最高。
というわけで初めは Go で書いていたのだけど、YAML と JSON で型が微妙に違う(YAML は map[int]interface{}
のこともあるが、JSON は map[string]interface{}
)のが面倒でやめた。
案3 Nim で書く(採用)
Nim は先日 1.0.0 が出たイケイケの言語で、Python っぽく書けて便利という評判が自分の中である。Go が無理なら Nim チャンス!ということで Nim で書くことにした。
Nim の YAML ライブラリ は最高で、loadToJson
関数があるので一瞬で終わった。
バイナリを作る
リリース周りは CI でやりたい。今回は GitHub Actions を使ってみることにした。GitHub Actions では、Action を組み合わせたり、自分でコマンドを記述したりして CI の動作を記述する。
Action は 公式がいくつか配布している 他、サードパーティのもある。今回はサードパーティ Action は使わない方向でやってみた。
Nim with GitHub Actions
公式では Golang など様々な言語をインストールする Action があるが、残念ながら Nim はない。なので自分で環境構築を行った。
macOS
brew が入っているので、 brew install nim
する。
Ubuntu
Ubuntu では Docker を使った(apt で Nim が配布されているものの、バージョンが古くて依存ライブラリがコンパイルできない)。
amd64 だと 公式 Nim Docker Image を使えばよかったが、クロスコンパイルはできなかったので、 arm 用には クロスコンパイルできる Image を Docker Hub に作った *3。
ちなみに、GitHub Workflow には Docker 上で動かしたり Volume を作ってくれたりする機能があるが、それを使うにはパブリックイメージを使う必要がある。そうでない場合は自前で docker build
して docker run ...
することになると思う。
その他
良かった
- 何でもできる
- Cron っぽいこともできる のはすごい
- Public repository だと無料
- 20並列までいけるし、ビルド開始も素早い。 MS 様〜〜
- macOS や Windows がある
- Nim では OS をまたいだクロスコンパイルは難しいので非常にありがたい
- macOS では brew が入ってたりする ので何でもできる
- GitHub のトークンを渡すのが楽
- 勝手に生成してくれる
悪かった
まだ出たばかりというのもあって、使いづらい点も多かった。
公式の Actions が機能不足
artifact は一つずつしか Upload できない等、「一応できるけど不便」みたいな例が多い。 特にリリース周りは不便で、本当はもっとうまくできるのにな…と言いながら長い Workflow になってしまった。
job 間で値の受け渡しがしずらい
値を直接受け渡しすることはできず、 artifact 経由になってしまう。「一回リリースつくって、そこに並列で artifact を追加する」といったケースでは upload_url を渡すことができずに困った。
情報が多くない
ドキュメントはちゃんとしているが、ユースケースがまだ少ないため情報が探しにくい。
YAML エディタが使いにくい
エラーや補完を出てくれるのは嬉しいが、改行時は普通に改行してほしいな…。
多くの問題は時が経てば解決するだろう。