golang-spf13-cobra について
Go CLI エンジニア向けの spf13/cobra スキルガイドです。コマンドツリー、フック、引数検証、フラグ、補完、ドキュメント生成とテスト方法を扱います。
主な機能
- 01コマンドとサブコマンドのツリー構築
- 02コマンドフックとエラー処理の設定
- 03位置引数の検証とフラグ定義
- 04シェル補完とコマンドドキュメントの生成
- 05テスト可能なコマンドハンドラーの作成
活用シーン
- 01Go CLI の新規構築
- 02既存 CLI へのサブコマンドやフラグの追加
- 03コマンドのライフサイクルと引数検証のレビュー
- 04テストでの出力と状態の分離
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ samber/ cc-skills-golang --skill golang-spf13-cobraインストール後、Claude Code で/golang-spf13-cobraを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/evals.jsonreferences/commands-and-args.mdcompletions.mdflags.mdgenerators.mdtesting.md詳細
ペルソナ: Unix シェルに自然になじむコマンドツリーを構築する Go CLI エンジニアです。まずユーザー向けのインターフェースを設計し、その後、適切なフックに動作を組み込みます。
モード:
- Build — CLI を新規作成する場合:コマンドツリーのセットアップ、フックの配線、フラグの各セクションを順に進めます。
- Extend — 既存の CLI にサブコマンド、フラグ、または補完機能を追加する場合:まず現在のコマンドツリーを確認し、既存の構造に沿って変更を適用します。
- Review — 既存の CLI を監査する場合:「よくある間違い」の表を確認し、
RunEの使用、OutOrStdout()、フックチェーンの順序、引数の検証を確認します。
Go で CLI コマンドツリーに spf13/cobra を使用する
Cobra は Go CLI アプリケーションの事実上の標準です。コマンド/サブコマンドツリー、フラグの解析(pflag 経由)、引数の検証、シェル補完の生成、ドキュメントの生成を提供します。設定のレイヤリングは扱いません。それは viper の役割です。
公式リソース:
このスキルは網羅的なものではありません。詳しくはライブラリのドキュメントとコード例を参照してください。
- Go パッケージのドキュメント、シンボル、バージョン、インポーター、既知の脆弱性については、Context7 よりも優先して
samber/cc-skills-golang@golang-pkg-go-devスキル(godig)を参照してください。 - 独自コード内でこのライブラリの使い方(定義、呼び出し箇所、診断情報)を調べるには、
samber/cc-skills-golang@golang-goplsスキル(gopls)を参照してください。 - pkg.go.dev にインデックスされていないドキュメントについては、Context7 を引き続き代替手段として利用できます。
go get github.com/spf13/cobra@latest
Cobra と viper の比較
これらのライブラリは根本的に異なる役割を持ち、それぞれ単独で使用できます。
| 懸念事項 | cobra | viper |
|---|---|---|
| 担当するもの | コマンドツリー、フラグ、引数の検証、補完 | 設定値の解決 |
| ユーザー向けか | はい — サブコマンド、フラグ、ヘルプテキスト | いいえ — 純粋なキーと値のリゾルバーです |
| もう一方なしで使えるか | はい — フラグだけを使う CLI に必要なのは cobra だけです | はい — YAML と環境変数を読み込むデーモンに必要なのは viper だけです |
| 統合箇所 | BindPFlag を介して pflag.Flag を viper に渡します | cobra フラグを最も優先度の高いレイヤーとして扱います |
バイナリがフラグと引数を受け取るものの、設定ファイルや環境変数の解決が不要な場合は、cobra のみを使用してください。CLI サブコマンドを持たず、YAML と環境変数から設定を読み込む長時間稼働サービスの場合は、viper のみを使用してください。両方が必要な場合は併用し、ルートコマンドの PersistentPreRunE でバインドしてください。
→ この統合の viper 側については、samber/cc-skills-golang@golang-spf13-viper を参照してください。
コマンドツリー
すべての cobra CLI にはルートコマンドがあり、AddCommand で登録されたサブコマンドが 0 個以上あります。ルートコマンド名はバイナリ名です。
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "One-line summary",
SilenceUsage: true, // ✓ prevents usage wall on every error
SilenceErrors: true, // ✓ lets you control error output format
}
ヘルプ出力でサブコマンドにラベルを付けるには AddGroup を使用します。参照する AddCommand の呼び出しより前にグループを登録してください。cobra は後からグループを割り当てません。
Run* ファミリー
Cobra コマンドには、次の順序で実行される 5 つの実行フックがあります。
PersistentPreRunE → PreRunE → RunE → PostRunE → PersistentPostRunE
常に *E 形式を使用してください。E が付かない形式ではエラーを返せません。主なルールは次のとおりです。
- ルートの
PersistentPreRunEはすべてのサブコマンドの前に実行されます。設定の初期化や認証チェックに使用してください。 - 子の
PersistentPreRunEは親のものを完全に置き換えます。両方が必要な場合は、親を明示的に呼び出してください。 PostRunEはRunEが成功した場合にのみ実行されます。
ライフサイクルと継承ルールの詳細については、commands-and-args.md を参照してください。
引数バリデーター
Cobra は RunE の実行前に位置引数を検証します。RunE 内で len(args) をチェックしないでください。これは Cobra 標準のエラーメッセージと引数数の追跡を回避してしまいます。
組み込みのバリデーター:NoArgs、ExactArgs(n)、MinimumNArgs(n)、MaximumNArgs(n)、RangeArgs(min,max)、OnlyValidArgs、ExactValidArgs(n)。MatchAll(v1, v2) で組み合わせられます。カスタムバリデーター:func(cmd *cobra.Command, args []string) error。
バリデーターの全種類と使用例、MatchAll のパターンについては、commands-and-args.md を参照してください。
フラグ入門
Cobra はフラグの解析を pflag に委譲します。永続フラグ(PersistentFlags())はすべてのサブコマンドに継承され、ローカルフラグ(Flags())は宣言したコマンドにのみ適用されます。
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file path") // inherited by all subcommands
serveCmd.Flags().IntVar(&port, "port", 8080, "listen port") // local to serveCmd only
serveCmd.MarkFlagRequired("port")
serveCmd.MarkFlagsMutuallyExclusive("json", "yaml")
pflag の型、カスタムフラグ値、フラググループ、Viper とのバインディングについては、flags.md を参照してください。
補完入門
Cobra はシェル補完を自動的に生成します。次の方法で拡張できます。
ValidArgs []string— 静的な位置引数の補完です。ValidArgsFunction— 動的な補完です:func(cmd, args, toComplete string) ([]string, ShellCompDirective)。ファイルへのフォールバックを抑制するには、ShellCompDirectiveNoFileCompを返します。RegisterFlagCompletionFunc(name, fn)— フラグ値の補完です。
ShellCompDirective の値、アノテーション、テストについては、completions.md を参照してください。
コマンドのテスト
コマンドはプログラムから実行してテストします。コマンドハンドラー内で os.Stdout / os.Stderr を直接使用しないでください。テストで出力先を変更できるよう、cmd.OutOrStdout() / cmd.ErrOrStderr() を使用します。
func TestServeCmd(t *testing.T) {
buf := new(bytes.Buffer)
rootCmd.SetOut(buf)
rootCmd.SetArgs([]string{"serve", "--port", "9090"})
require.NoError(t, rootCmd.Execute())
assert.Contains(t, buf.String(), "listening on :9090")
}
Cobra は Execute() の呼び出しをまたいでフラグの状態を蓄積します。テストごとに新しいコマンドツリーを作成してください。分離のパターン、ゴールデンファイル、補完のテストについては、testing.md を参照してください。
ベストプラクティス
- 必ず
RunEを使用し、Runは使用しないでください —Runはエラーを返せません。唯一の回避策はos.Exitまたはパニックであり、defer の実行を妨げます。 - 設定の初期化は
PersistentPreRunEに配置してください — すべてのサブコマンドの前に実行されるため、Viper とのバインディングや認証チェックに適しています。 - 位置引数は
RunE内ではなくArgsで検証してください —Argsを使えば Cobra 標準のエラーメッセージが表示されます。バリデーターはMatchAllで組み合わせられます。 - すべての出力に
cmd.OutOrStdout()/cmd.ErrOrStderr()を使用してください —os.Stdoutへの直接書き込みはテストでキャプチャできません。 - テストごとにコマンドツリーを作り直してください — Cobra は同じインスタンスでの
Execute()呼び出しをまたいでフラグの状態を蓄積します。
よくある間違い
| 間違い | 失敗する理由 | 修正方法 |
|---|---|---|
RunE ではなく Run を使用する | エラーを返せません。唯一の回避策は os.Exit またはパニックであり、defer の実行を妨げます | RunE を使用し、エラーを返して Cobra に終了処理を任せます |
RunE 内で len(args) をチェックする | Cobra 標準のエラーメッセージ(「引数を1つ受け取るコマンドですが、2つ受け取りました」)を回避してしまいます | コマンドに Args: cobra.ExactArgs(1) を宣言します |
os.Stdout に直接書き込む | OS レベルのファイルハンドルはリダイレクトできないため、テストで出力をキャプチャできません | cmd.OutOrStdout() / cmd.ErrOrStderr() を使用します |
子の PersistentPreRunE が親のものを黙って置き換える | Cobra はフックを連結しません。子のフックが親のフック全体を置き換えます | 子のフックから parent.PersistentPreRunE(cmd, args) を呼び出します |
| テスト間でルートコマンドを再利用する | Cobra はフラグの状態を蓄積するため、2回目の Execute() では1回目のフラグも認識されます | テストごとに新しいコマンドツリーを作成します |
参考資料
- commands-and-args.md — PreRun*/PostRun* の完全なチェーン、すべての Args バリデーター、PersistentPreRunE の継承ルール
- flags.md — pflag の型、必須/排他/1つ必須のグループ、カスタム値型、viper とのバインド
- completions.md — ShellCompDirective の一覧、アノテーションベースの補完、補完のテスト
- generators.md — man ページ、Markdown、YAML、RST ドキュメントの生成、
cobra-cliスキャフォルダー - testing.md — 分離パターン、ゴールデンファイル、補完のテスト、テーブル駆動のコマンドテスト
相互参照
- → 一般的な CLI アーキテクチャ(プロジェクトの構成、終了コード、シグナル処理、I/O パターン)については、
samber/cc-skills-golang@golang-cliスキルを参照してください - → cobra と併用する設定のレイヤリング(フラグ → 環境変数 → ファイル → デフォルトの優先順位)については、
samber/cc-skills-golang@golang-spf13-viperスキルを参照してください - → 一般的な Go のテストパターンについては、
samber/cc-skills-golang@golang-testingスキルを参照してください
spf13/cobra でバグや予期しない動作が発生した場合は、https://github.com/spf13/cobra/issues で Issue を作成してください。