mcpField
G
golang-cli

golang-cli

github.com/samber開発3.7k39.9k 回インストール5 日前に更新
リポジトリ

golang-cli について

Go のコマンドラインツールの構築、拡張、レビューを支援するエンジニアリングスキルです。Cobra と Viper のパターン、設定、シェル向けの入出力、検証、配布を扱います。

主な機能

  1. 01Cobra のコマンドとフラグ構成
  2. 02Viper による設定の優先順位
  3. 03引数とフラグの検証
  4. 04Unix の標準出力・標準エラーの指針
  5. 05補完、テスト、終了コード

活用シーン

  1. 01サブコマンドを備えた Go CLI の作成
  2. 02既存 CLI へのフラグと設定の追加
  3. 03CLI の出力、エラー、終了コードのレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/samber/cc-skills-golang --skill golang-cli

インストール後、Claude Code で/golang-cliを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/examples/
args.go
cli_test.go
completion.go
config.go
exit_codes.go
flags.go
go.mod
main.go
output.go
root.go
serve.go
signal.go
version.go
evals/
evals.json

詳細

ペルソナ: Go CLI エンジニアです。Unix シェルに自然になじむ、組み合わせやすく、スクリプト化でき、自動化のもとでも予測どおりに動作するツールを構築します。

モード:

  • 構築 — CLI をゼロから作成する場合:プロジェクト構成、ルートコマンドの設定、フラグのバインド、バージョンの埋め込みの各セクションを順に確認します。
  • 拡張 — 既存の CLI にサブコマンド、フラグ、または補完機能を追加する場合:まず現在のコマンドツリーを確認し、既存の構成に沿って変更を適用します。
  • レビュー — 既存の CLI の正確性を監査する場合:「よくある間違い」表を確認し、SilenceUsage/SilenceErrors、フラグと Viper のバインド、終了コード、stdout/stderr の使い分けを検証します。

Go CLI のベストプラクティス

Go CLI アプリケーションでは、デフォルトのスタックとして Cobra + Viper を使用します。Cobra はコマンド/サブコマンド/フラグの構造を提供し、Viper はファイル、環境変数、フラグからの設定を自動的に階層化して処理します。この組み合わせは、kubectl、docker、gh、hugo をはじめ、ほとんどの本番環境向け Go CLI で使われています。

Cobra または Viper を使用する際は、最新の API シグネチャについて、各ライブラリの公式ドキュメントとコード例を参照してください。

サブコマンドがなく、フラグも少ない単純な単機能ツールであれば、標準ライブラリの flag で十分です。

クイックリファレンス

項目パッケージ/ツール
コマンドとフラグgithub.com/spf13/cobra
設定github.com/spf13/viper
フラグの解析github.com/spf13/pflag(Cobra 経由)
カラー出力github.com/fatih/color
テーブル出力github.com/olekukonko/tablewriter
対話型プロンプトgithub.com/charmbracelet/bubbletea
バージョンの注入go build -ldflags
配布goreleaser

プロジェクト構成

CLI コマンドは cmd/myapp/ に整理し、コマンドごとにファイルを分けます。main.go は最小限に保ち、Execute() の呼び出しだけを含めます。

myapp/
├── cmd/
│   └── myapp/
│       ├── main.go              # package main, only calls Execute()
│       ├── root.go              # Root command + Viper init
│       ├── serve.go             # "serve" subcommand
│       ├── migrate.go           # "migrate" subcommand
│       └── version.go           # "version" subcommand
├── go.mod
└── go.sum

main.go は最小限に保ちます。詳しくは assets/examples/main.go を参照してください。

ルートコマンドの設定

ルートコマンドでは Viper の設定を初期化し、PersistentPreRunE を使ってグローバルな動作を設定します。assets/examples/root.go を参照してください。

重要なポイント:

  • SilenceUsage: true は必ず設定してください。エラーのたびに使用方法全体が表示されるのを防ぎます。
  • SilenceErrors: true は必ず設定してください。エラー出力の形式を独自に制御できます。
  • PersistentPreRunE はすべてのサブコマンドの前に実行されるため、設定は常に初期化されます。
  • ログは stderr に、出力は stdout に送ります。

サブコマンド

cmd/myapp/ に個別のファイルを作成して init() で登録し、サブコマンドを追加します。コマンドグループを含むサブコマンドの完全な例は、assets/examples/serve.go を参照してください。

フラグ

すべてのフラグのパターンについては、assets/examples/flags.go を参照してください。

永続フラグとローカルフラグ
  • 永続フラグはすべてのサブコマンドに引き継がれます(例:--config)。
  • ローカルフラグは定義されたコマンドにのみ適用されます(例:--port)。
必須フラグ

フラグの制約には、MarkFlagRequired、MarkFlagsMutuallyExclusive、MarkFlagsOneRequired を使用します。

RegisterFlagCompletionFunc によるフラグの検証

フラグ値の補完候補を提供します。

フラグは必ず Viper にバインドする

これにより、viper.GetInt("port") はフラグの値、環境変数 MYAPP_PORT、または設定ファイルの値のうち、優先順位が最も高いものを返します。

引数の検証

Cobra には、位置引数用の組み込みバリデーターが用意されています。組み込みの検証例とカスタム検証例については、assets/examples/args.go を参照してください。

バリデーター説明
cobra.NoArgs引数が指定されている場合に失敗します
cobra.ExactArgs(n)引数をちょうど n 個要求します
cobra.MinimumNArgs(n)引数を少なくとも n 個要求します
cobra.MaximumNArgs(n)引数を最大 n 個まで許可します
cobra.RangeArgs(min, max)min 個から max 個までの引数を要求します
cobra.ExactValidArgs(n)有効な引数リストに含まれる引数をちょうど n 個要求します

Viper による設定

Viper は次の順序(優先度の高いものから低いもの)で設定値を解決します。

  1. CLI フラグ(明示的なユーザー入力)
  2. 環境変数(デプロイ時の設定)
  3. 設定ファイル(永続的な設定)
  4. デフォルト値(コード内で設定)

構造体へのアンマーシャリングや設定ファイルの監視を含む Viper の完全な統合例については、assets/examples/config.go を参照してください。

設定ファイルの例(.myapp.yaml)
port: 8080
host: localhost
log-level: info
database:
  dsn: postgres://localhost:5432/myapp
  max-conn: 25

上記の設定では、次の指定はすべて同じ意味になります。

  • フラグ:--port 9090
  • 環境変数:MYAPP_PORT=9090
  • 設定ファイル:port: 9090

バージョンとビルド情報

バージョンは、コンパイル時に ldflags を使って埋め込むべきです。バージョンコマンドとビルド手順については、assets/examples/version.go を参照してください。

終了コード

終了コードは Unix の規約に従う必要があります。

コード意味使用する場面
0成功操作が正常に完了した場合
1一般エラー実行時エラー
2使用方法エラーフラグまたは引数が無効な場合
64-78BSD sysexits特定のエラーカテゴリ
126実行不可権限が拒否された場合
127コマンドが見つからない依存関係が不足している場合
128+Nシグナル Nシグナルによって終了した場合(例:130 = SIGINT)

エラーを終了コードに対応付ける方法については、assets/examples/exit_codes.go を参照してください。

入出力パターン

すべての入出力パターンについては、assets/examples/output.go を参照してください。

  • stdout と stderr:診断出力を stdout に書き込んではいけません。stdout はプログラム出力用(パイプで利用可能)であり、stderr はログ、エラー、診断情報用です。
  • パイプと端末の判別:stdout の os.ModeCharDevice を確認します。
  • 機械可読な出力:テーブル、JSON、プレーン形式に対応する --output フラグをサポートします。
  • 色:出力先が端末でない場合に自動で無効になる fatih/color を使用します。

シグナル処理

シグナル処理では signal.NotifyContext を使用して、コンテキストを通じてキャンセルを伝播させる必要があります。HTTP サーバーをグレースフルにシャットダウンする例については、assets/examples/signal.go を参照してください。

シェル補完

Cobra は bash、zsh、fish、PowerShell 用の補完を自動生成します。補完コマンドとカスタムのフラグ/引数補完の両方については、assets/examples/completion.go を参照してください。

CLI コマンドのテスト

コマンドをプログラムから実行し、出力を取得してテストします。assets/examples/cli_test.go を参照してください。

テストで出力を取得できるように、コマンドでは os.Stdout / os.Stderr の代わりに cmd.OutOrStdout() と cmd.ErrOrStderr() を使用してください。

よくある間違い

間違い修正方法
os.Stdout に直接書き込むテストでは出力をキャプチャできません。テストでバッファーにリダイレクトできる cmd.OutOrStdout() を使用します
RunE 内で os.Exit() を呼び出すCobra のエラー処理、遅延実行関数、クリーンアップコードが実行されません。エラーを返し、main() に判断させます
フラグを Viper にバインドしないフラグを環境変数や設定で構成できません。構成可能な各フラグに対して viper.BindPFlag を呼び出します
viper.SetEnvPrefix がないPORT はほかのツールと衝突します。接頭辞(MYAPP_PORT)を使用して環境変数を名前空間に分けます
stdout にログを出力するUnix パイプでは stdout が連結されるため、ログが次のプログラムのデータストリームを破損させます。ログは stderr に出力します
エラーのたびに使用方法を表示するエラーのたびにヘルプ全体を表示するとノイズになります。SilenceUsage: true を設定し、完全な使用方法は --help 用に残します
設定ファイルを必須にする設定ファイルがないユーザーはクラッシュします。viper.ConfigFileNotFoundError を無視し、設定ファイルは任意にします
PersistentPreRunE を使用しないすべてのサブコマンドの前に設定を初期化する必要があります。ルートの PersistentPreRunE を使用します
バージョン文字列をハードコードするバージョンがタグと一致しなくなります。ビルド時に git タグから ldflags を介して設定します
--output の形式をサポートしないスクリプトで人間向けの出力を解析できません。機械処理用に JSON/テーブル/プレーン形式を追加します

関連するスキル

samber/cc-skills-golang@golang-project-layout、samber/cc-skills-golang@golang-dependency-injection、samber/cc-skills-golang@golang-testing、samber/cc-skills-golang@golang-design-patterns のスキルを参照してください。

コメント