はじめに
こんにちは、AWSインフラエンジニアのかふぃです。
最近Goを学んでいて、担当している案件の業務効率化のためにCLIアプリを作ろうと思い、CLIコマンドの設計哲学について勉強を始めました。
学んだことをまとめたので、ご参考になれば幸いです。
目次
参考資料
以下の資料を参照しました。特に、Building an Awesome CLI App in Goは端的でわかりやすかったのでおすすめです。
Building an Awesome CLI App in Go
導入文訳:ユーザーフレンドリーなコマンドラインインターフェイスとコマンドスイートを作成するために必要なテクニック、原則、ライブラリの概要を説明してから、独自のアプリの構築手順を説明します。その過程で、コマンドの設計と構築方法から、フラグ、構成ファイル、リモート構成システムの操作と解析、環境変数と 12 ファクター アプリの操作方法まで、あらゆることをカバーします。ワークショップの最後には、Go の実用的な知識と、機能する独自の CLI アプリを習得できます。
CLI Style Guide, Heroku
導入文訳:Heroku CLI プラグインは、人間にとって読みやすく使いやすいことを主な目的として、ユーザーに満足してもらえる明確なユーザー エクスペリエンスを提供すると同時に、上級ユーザーや出力形式をサポートする必要があります。この記事では、快適な CLI プラグインを設計するための明確な方向性を示します。
UNIX哲学
2003年に出版されたThe Art of UNIX ProgrammingというEric S. Raymondさんの書籍で、KISS(Keep it Simple, Stupid)の原則としてまとめられました。以下はBuilding an Awesome CLI App in Goで抜粋して紹介されていたものです。
- Simple(シンプル)
- Clear(明確)
- Composable(組み合わせ可能)
- Extensible(拡張可能)
- Modular(モジュール性)
- Small(小さく)
CLIコマンドの基本
コマンド名の決め方
コマンド(省略形) | 意味(原形) |
---|---|
ls |
list(一覧) |
cp |
copy(コピー) |
rm |
remove(削除) |
短く、しかし意味がわかるようにします。
コマンドは動詞、引数は名詞
ls /home
# → List the home directory
# 動詞 名詞
ls
が動詞、/home
が名詞。
cp file.txt backup.txt
# → Copy this file to here
# 動詞 名詞 名詞
動詞 cp
に対して、file.txt
(元ファイル)と backup.txt
(新しいファイル名)は名詞。
オプションは副詞
フラグともいう。動詞の振る舞いを変える/調整する働きを持つ。動詞に対する副詞の働き。
rm -f file.txt
rm --force file.txt
# → Remove Forcefully file.txt
# 動詞 副詞 名詞
-f
と --force
は同じ意味で、動詞 rm
の振る舞いを変える“副詞”的な存在。
※英語としてはForcefully remove file.txtですが、便宜上コマンドの順番通りにしています。
ls --color /home/user
# → List colorfully the home directory
# 動詞 副詞 名詞
副詞が影響を与えるもの
- manner:方法
- place:場所
- time:時間
- frequency:頻度
- degree:程度
- level of certainty:確実性
- etc.
簡単にいうと、
- How?:どのくらい?
- In what way?:どうやって?
- When?:いつ?
- Where?:どこで?
- To what extent?:どのくらいまで?
これらを意識して、動詞単位で分けるのか、動詞は固定で副詞で調整するのかを考えて設計する。
--width=40
のような指定は前置詞+目的語で副詞の役割
ls --width=40
# → List this directory with a width of 40 columns
「前置詞+その目的語」で構成され、副詞として振る舞う。
CLIアプリケーション
ls
や cp
などのOSの組み込みコマンドに対するCLIアプリケーション。
例:
httpd
vi
emacs
git
CLIアプリの特徴
- アプリケーションを起動する。
- 1つ以上のことができる(lsなどのような1つのちょっとしたことしかしないのではなく、より多くのことをする)。
- コマンド(サブコマンドと呼ばれる)の集合体である。
- サブコマンドにもこれまでのルールが同様に適用される。
CLIアプリにはサブコマンドというのがある。これは、さっきのlsとかcpと同じ立ち位置。
svn add
brew install
npm search
apt upgrade
git clone
# アプリ名 動詞(コマンド)
先ほどまでのlsとかcpはosの組み込みコマンドで、これをCLIアプリと同様に扱うなら下記のようなものだったと考えてもいいかもです。
oscli ls
oscli cp [file] [newfile]
# アプリ名 動詞(コマンド)
CLIアプリは「呼びかけ+動詞+名詞」の形
brew install hugo
# → Brew, install hugo.
# 呼びかけ 動詞 名詞
「Brew、hugoをインストールしてください」という感じ。
オプションのルールも変わらない
brew fetch -v hugo
# → Brew, fetch verbosely hugo
# 呼びかけ 動詞 副詞 名詞
サブコマンドやオプションの使い方にも、これまでの設計ルールがそのまま適用される。
まとめ
CLIは、動詞(コマンド)+副詞(フラグ)+名詞(引数) という構造で成り立っており、この設計思想に従うことで、一貫性を持ったCLIコマンドを設計することができそうです。
簡単にCLIコマンドの構成要素をまとめました。
- 小さくても意味のある動詞(コマンド)
- 必要に応じて動作を変える副詞(フラグ)
- 操作対象となる名詞(引数)
GoでCLIアプリ作ったらまたブログにしようと思います。
読んでいただきありがとうございました!