- 開発チームにとって、組織の知識を収集・保存する有用な方法の1つは、役に立つスニペット、スクリプト、ワークフローのコレクションを増やしていくこと
- そのため、多くのリポジトリには Makefile や bash スクリプトのようなものが作られる
- では、組織全体で役立つツールのインストール、ボイラープレートコードの生成、誰も覚えていない複雑な AWS コマンドの実行のようなことは、どう扱えばよいのだろうか?
- Slack や Shopify のような一部の企業には、独自の社内 CLI がある
- モダンなターミナルである Warp には、ワークフローを文書化して共有できる機能がある
- 組織内向けの CLI は簡単に作れる。例として、acme という会社向けの CLI を作ってみる
CLI の設計要件
acme <command> でどこからでもコマンドを実行できる共通のエントリポイントを持つ
- すべての開発者は、特定のリポジトリに先に移動しなくても、どこからでも
acme <command> を実行してコマンドを起動できる
- 開発者が新しいコマンドを簡単に提供できるようにする
acme update で新しいバージョンを簡単に配布できるようにする
- クロスプラットフォーム対応(例:
acme download something を実行すると、Linux では curl、Windows では Invoke-WebRequest を使う)
acme list で利用可能なコマンドの一覧と簡単な説明を見られるようにする
just を使ってプロジェクトを始める
- just は
make に似ているが、コマンド実行に特化したツール
- クロスプラットフォームに対応し、プラットフォーム固有のコマンドも実行できる
- 他の選択肢としては、Slack の
magic-cli(Ruby に慣れているなら始めるのに最適)や make がある
プロジェクトをセットアップする
just をインストールする。こちら の手順に従う
~/acme/cli フォルダを作成し、ルートに次の justfile を追加する:
default:
just --list
# archとos名を表示
os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
just のドキュメントでは、コマンドを "recipes" と呼ぶ
- レシピを指定せずに
just を実行すると、justfile の最初のレシピが実行される。通常、最初のレシピ名を default にするのが一般的なパターン
$ just
just --list
Available recipes:
default
os-info # Show arch and os name
- default レシピは
just list を実行する。すべてのレシピ一覧とコメントを表示する
- default レシピは隠しておくのがよい
- レシピを実行すると、各コマンドは実行前に表示される。
@ 接頭辞でこの出力を消せる。Makefile と同様
[private]
@default:
just --list
# archとos名を表示
@os-info:
echo "Arch: {{arch()}}"
echo "OS: {{os()}}"
acme エイリアスを作る
新しいレシピを書く
シンプルなレシピ
プラットフォーム固有のレシピ
systemd のようなツールを含むスニペットは、開発者が Linux マシンを使っている場合にのみ公開する
[linux] 属性を使って、Linux でのみレシピが公開されるようにする
[linux]
@list-systemd-services:
systemctl list-units --type=service
クロスプラットフォームのレシピ
スクリプトレシピ
- レシピにはスクリプト全体を埋め込める
- Shebang(
#!) で始まるレシピは別ファイルとして保存されて実行される
- 制御フロー(if-else、ループ)の使用、変数の保存や操作など、ワークフローでやや複雑なロジックが必要な場合に便利
# Say hello world in sh
hello-world-sh:
#!/usr/bin/env sh
hello='Yo'
echo "$hello from a shell script!"
- これは、強力なスクリプト機能を持つプログラミング言語を活用できるという意味でもある。作業によっては Bash より Python のほうが簡単に行える
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#!/usr/bin/env python3
import PIL.Image
image = PIL.Image.open("{{path}}")
factor = 0.5
image = image.resize((round(image.width * factor), round(image.height * factor)))
image.save("{{path}}.s50.jpg")
- すべての開発者が自分のコンピュータに Python をインストールしているとは限らず、インストール済みでも pillow が入っていない可能性がある。
nix を使えば、依存関係込みでスクリプトを実行できる:
# scale jpg image by 50%
[no-cd]
scale-jpg path:
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3Packages.pillow
import PIL.Image
...
レシピを配布する
- 独自の配布メカニズムを自作する代わりに
git を使う
- GitHub にリポジトリを作成し、ここまで作ったものを push する
$ git init
$ git commit -m "first commit"
$ git branch -M main
$ git remote add origin git@github.com:acme/cli.git
$ git push -u origin main
- これで、このリポジトリにアクセスできる人なら誰でも PR を作成して変更を提供できる
acme update レシピで git pull を自動化する
# Update the Acme CLI
@update:
git fetch
git checkout main
ドキュメント化
- 社内ツールの成功には導入が非常に重要であり、新しい利用者がツールをインストールして探索できるよう案内する、優れた利用ガイドが不可欠
README にインストール方法と使い方を案内する
# Acme CLI
## Prerequisites
`just`: Install just [here](https://github.com/casey/just/blob/master/README.md#installation)
## Installation
Clone this repo:
...
Set up the `acme` alias:
...
## Usage
List all available recipes:
...
- これで、Acme Corp のすべての開発者が使えるようになった
- 社内で Slack メッセージを投稿して、みんなに試してもらうよう促し、それぞれが自分のスニペットを提供できるようにする
追加機能
- 自動補完(Completion)機能は、TAB キーを押すとサブコマンド、ファイルパス、オプションなどを自動補完できる仕組み
- ほとんどのシェルはこの機能を提供しており、主要な CLI ツールの多くは補完機能をインストールする方法を用意している
- Python の Click、Golang の Cobra、Rust の clap など、主要な CLI フレームワークの多くは自動で補完機能を生成できる
Just は just --completion <shell>. を実行して Completion を生成できる
1件のコメント
以前から、社内向けDX設計はプラットフォームエンジニアリングにとって重要なテーマであるようです。