50 ポイント 投稿者 xguru 2024-09-03 | 1件のコメント | WhatsAppで共有
  • 開発チームにとって、組織の知識を収集・保存する有用な方法の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 を使ってプロジェクトを始める

  • justmake に似ているが、コマンド実行に特化したツール
  • クロスプラットフォームに対応し、プラットフォーム固有のコマンドも実行できる
  • 他の選択肢としては、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 エイリアスを作る

  • acme <command> の形で実行するため、.bashrc にエイリアスを追加する
    alias acme='just --justfile ~/acme/cli/justfile'  
    
  • source ~/.bashrc または exec bash で新しいエイリアスを読み込む

新しいレシピを書く

シンプルなレシピ

  • AWS IAM ユーザー/ロール情報を取得する
    @aws-id:  
      aws sts get-caller-identity  
    
    • 誰も覚えていないコマンドを単純化することが、おそらく社内 CLI の主なユースケース
    • awscli はクロスプラットフォームだと仮定しているため、このレシピは呼び出し元の場所に関係なく動作する

プラットフォーム固有のレシピ

  • systemd のようなツールを含むスニペットは、開発者が Linux マシンを使っている場合にのみ公開する
  • [linux] 属性を使って、Linux でのみレシピが公開されるようにする
[linux]  
@list-systemd-services:  
  systemctl list-units --type=service  

クロスプラットフォームのレシピ

  • フォルダサイズの取得を Windows と Linux でそれぞれ実装する
    [windows]  
    [no-cd]  
    get-folder-size path:  
      (Get-ChildItem "{{path}}" -Recurse -Force | Measure-Object -Property Length -Sum).Sum / 1MB  
    
    [linux]  
    [no-cd]  
    get-folder-size path:  
      du -sh {{path}}  
    

スクリプトレシピ

  • レシピにはスクリプト全体を埋め込める
  • 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 フレームワークの多くは自動で補完機能を生成できる
  • Justjust --completion <shell>. を実行して Completion を生成できる

1件のコメント

 
bus710 2024-09-03

以前から、社内向けDX設計はプラットフォームエンジニアリングにとって重要なテーマであるようです。