go-code-review について
Go の変更、ファイル、パッケージ、コードベース全体を対象とする構造化コードレビューのスキルです。ツールチェーンの確認と手動レビューを組み合わせ、場所を示して重要度別に指摘します。
主な機能
- 01差分・ファイル・全体監査モード
- 02ビルド、vet、lint、レーステストの確認
- 03正確性と安全性のレビュー
- 04API と Go の慣用表現の確認
- 05テストとドキュメントのレビュー
- 06場所付きの重要度別指摘
活用シーン
- 01Go のプルリクエストのレビュー
- 02パッケージとテストの監査
- 03大規模な Go コードベースの体系的な確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ eduardo-sl/ go-agent-skills --skill go-code-reviewインストール後、Claude Code で/go-code-reviewを入力して読み込まれたか確認します。
詳細
Go コードレビュー
Go のための体系的なコードレビュープロセスです。レビューは建設的かつ具体的に行い、各指摘の根拠となる原則を示してください。
運用モード
開始前に、依頼に合ったモードを選択してください。
- 差分レビュー(デフォルト)— 変更された行と、判断に必要な周辺のコンテキストのみをレビューします。PR や作業ツリーの変更に使用します。
- ファイル/パッケージレビュー — 指定されたファイルまたはパッケージを、テストを含めて全体的にレビューします。
- 全体監査 — コードベース全体を調査します。以下の「大規模コードベースの監査」の方針を使用し、すべての結果を1つのレポートにまとめます。
レビュープロセス
次の手順を順番に実行してください。指摘ごとに重大度を分類します。
- 🔴 ブロッカー — マージ前に修正が必須です。正確性、データ損失、セキュリティに関するものです。
- 🟡 警告 — 修正すべきです。保守性、Go の慣用的な書き方、明確さに関するものです。
- 🟢 提案 — 改善を検討してください。スタイル、命名、ドキュメントに関するものです。
0. まずツールチェーンを実行する
コードを手作業で読む前に、ツールで機械的な問題を検出してください(インストールされていないツールはスキップし、レポートに記載してください)。
go build ./... # it must compile
go vet ./... # suspicious constructs
golangci-lint run # if the repo has a config
go test -race ./... # tests pass, no data races
ツールの指摘も手動での指摘と併せて報告してください。go vet の失敗は、自動的に🔴 ブロッカーとなります。ツールによって問題がないと確認された項目は、問題として報告しないでください。
1. 正確性と安全性
エラー処理
- すべてのエラーを確認します。空識別子
_を使ってエラーを黙って破棄してはいけません。 - エラーはコンテキストを付けてラップします。
fmt.Errorf("fetch user %d: %w", id, err)。 - エラー値の比較には
==を使わず、errors.Is()/errors.As()を使います。 init()内、または真に回復不可能な状況以外ではpanicを使いません。- エラーは一度だけ処理します。ログを出力してから返すパターンは避けます。
nil の安全性
- nil が有効な状態であるポインタレシーバーは、デリファレンスする前にチェックします。
- マップの読み取りはガードするか、comma-ok イディオムを使います。
- チャネル操作では、クローズ済みまたは nil のチャネルを考慮します。
- 関連する箇所では、スライス操作の境界をチェックします。
並行処理
- 共有された可変状態は
sync.Mutexまたはチャネルで保護します。 - ゴルーチンリークがないようにします。すべてのゴルーチンに明確な終了経路を設けます。
- コンテキストを伝播します。ブロッキング呼び出しはすべて
context.Contextを受け取り、その内容を尊重します。 - ゴルーチンのライフサイクル管理には
sync.WaitGroupまたはerrgroup.Groupを使います。
2. API 設計
- エクスポートされた関数には、関数名で始まるドキュメントコメントを付けます。
- インターフェースを受け取り、具体的な型を返します。
- オプションのパラメーターには、設定用構造体ではなく関数オプション(
WithTimeout(d))を使います。 - コンテキストは常に最初のパラメーターにします。
func Foo(ctx context.Context, ...)。 errorは最後の戻り値にします。boolパラメーターは避け、名前付き型またはオプションを使います。
3. Go の慣用的な書き方
- ローカル変数には
:=を使い、ゼロ値の意図を示す場合はvarを使います。 - return/continue/break の後に不要な
elseを置きません。 - ガード節と早期リターンでネストを減らします。
- クリーンアップには
deferを使い、リソースを取得した直後に配置します。 - 適切な場合は、手動でインデックスを使った反復より
rangeを使います。 - 構造体リテラルではフィールド名を指定します。
- インターフェースは提供側ではなく、利用側で定義します。
4. パッケージ構成
- パッケージ名は短く、小文字で、単数形の名詞にします。
- パッケージ間に循環依存を作りません。
- 非公開パッケージには
internal/を使います。 cmd/には、バイナリごとに1つずつ、main パッケージを配置します。- 関心事を明確に分離し、何でも詰め込んだパッケージを作りません。
5. テスト
- テスト関数には
TestXxxの命名規則を使います。 - 入出力の組み合わせが複数ある場合は、テーブル駆動テストを使います。
- テストヘルパーでは
t.Helper()を使い、スタックトレースを見やすくします。 init()にテストロジックを置きません。必要な場合はTestMainを使います。- テストでは
testify/assertまたはtestify/requireを一貫して使うか、標準ライブラリのみを使います。 - 空の入力、nil、ゼロ値、最大値などのエッジケースをカバーします。
- 安全な場合は
t.Parallel()を使います。
6. ドキュメント
- エクスポートされた型、関数、定数にはすべてドキュメントコメントを付けます。
- ドキュメントコメントは対象の名前で始めます。
- 複雑なパッケージでは、
doc.goにパッケージレベルのドキュメントコメントを記載します。 - 複雑なアルゴリズムやビジネスロジックには、なぜ そうするのかを説明するインラインコメントを付けます。
7. 依存関係
- コミットされたコードの
go.modに置換ディレクティブがありません(モノレポを除く)。 - 未使用の依存関係がありません。
- 依存関係は、十分に保守されている信頼できるソースから取得されています。
- 間接依存関係が把握されており、許容できるものです。
大規模なコードベースの監査
対象が約20ファイルを超える場合は、すべてを一度に順番に読み進めないでください。監査を独立した複数のパスに分割してください。
- パッケージを列挙し(
go list ./...)、レイヤーごとに分類します (ハンドラー、サービス、ストア、共有ライブラリ)。 - セクション1〜7の各観点(正確性、 API設計、イディオム、構造、テスト、ドキュメント、依存関係)について、 それぞれに絞ったパスを実行します。
- 環境が並列サブエージェントまたはタスクへの作業委任に対応している場合は、 各パスをそれぞれに割り当てます。設計上、各パスは独立しています。 対応していない場合は、観点ごとに一度に1つずつ順番に実行します。
- すべての指摘に
file.go:lineと重大度を明記するよう求めます。これにより、 最終的な集約を機械的に行えます。マージし、重複を排除し、重大度順に並べ替えます。
レビュー出力形式
## Code Review Summary
**Files reviewed:** <list>
**Overall assessment:** APPROVE | REQUEST CHANGES | COMMENT
### Findings
#### 🔴 BLOCKER: <title>
- **File:** `path/to/file.go:42`
- **Issue:** <what is wrong>
- **Why:** <which principle or guideline>
- **Fix:** <concrete suggestion>
#### 🟡 WARNING: <title>
...
#### 🟢 SUGGESTION: <title>
...
### What's Done Well
<genuine positive observations — always include at least one>
コメント
Markdown 対応