概要
stdin からファイルパスリストを受け取り、変更影響範囲分析や関連ファイル検索の入力として使用する。
背景・動機
- シナリオ10(リグレッション影響分析):
git diff --name-only | commandindex impact のパイプラインを実現
- Unix哲学に沿った CLI 設計(他コマンドとの組み合わせ)
提案する解決策
# git diff の出力を直接パイプ
git diff main...develop --name-only | commandindex impact --format json
# ファイルリストをパイプ
cat file_list.txt | commandindex search --related-stdin --format json
# grep 結果をパイプ
grep -rl "getDbInstance" src/ | commandindex impact --format json
# 引数でもファイル指定可能(stdinと排他)
commandindex impact src/main.rs src/cli/search.rs --format json
実装方針
impact サブコマンドは stdin またはコマンドライン引数からファイルリストを受け取る
- 引数が指定されている場合: 引数のファイルリストを使用
- 引数がない場合: stdin から読み取る(TTY の場合はエラー)
- 引数あり + stdin パイプの場合: 引数を優先(stdin は無視)
search --related-stdin で stdin からファイルリストを読み取る(1行1ファイルパス)
--related-stdin を採用する理由: 既存の --related <FILE> は値を1つ取る Option で、clap の conflicts_with_all による排他モデルに載っている。--related-stdin は値を取らない bool フラグとして追加し、--related と相互排他にすることで、既存の排他モデルを最小限の変更で拡張できる。main.rs の match 分岐では related_stdin を related の前に if let で先にチェックする。
- stdin が TTY の場合はエラー(パイプ専用)
impact サブコマンドの機能定義
impact サブコマンドは、入力されたファイルパスリストに対して 関連ファイルの集約分析 を行う。
注意: 既存の RelatedSearchEngine::find_related は双方向で関連ファイルを集計する(Markdown link も import dependency も順方向・逆方向の両方を含む)。したがって impact は厳密な「逆依存のみの分析」ではなく、「複数入力ファイルの関連ファイルを集約し、影響度スコアで降順ソートする」機能となる。将来的に逆依存のみのフィルタリングが必要になった場合は、--reverse-only オプション等で拡張する。
context との差分:
context: 複数ファイルの関連コンテキスト生成(ファイル内容のマージ出力、LLM向け)
impact: 複数ファイルの関連ファイル集約分析(影響を受けるファイルの一覧出力、CI/CD向け)
具体的な処理:
- stdin または引数からファイルパスリストを取得
- 各ファイルに対して
RelatedSearchEngine::find_related を呼び出し
- 結果を集約・重複排除し、影響度スコアで降順ソート
- 指定フォーマット(human/json/path)で出力
出力スキーマ(JSON)
{
"input_files": ["src/main.rs", "src/cli/search.rs"],
"impacted_files": [
{
"file_path": "tests/cli_args.rs",
"score": 1.5,
"relation_types": ["import_dependency", "path_similarity"],
"impacted_by": ["src/main.rs"]
}
],
"total_input_files": 2,
"total_impacted_files": 5
}
注: relation_types は既存の snake_case 命名規約に合わせる(import_dependency, path_similarity, markdown_link, tag_match, directory_proximity)
search --related-stdin の出力仕様
複数ファイル入力時の集約ルール:
- 結果は union(全入力ファイルの関連結果を統合)
- 重複ファイルは 最大スコアを採用
relation_types は全入力からのユニーク集合
- 入力ファイル自体は出力から除外
- 出力形式は既存の
--related と同じ(human/json/path の3形式、JSONL形式)
impacted_by は含まない(既存の related 出力互換を維持)
stdin 入力仕様
- 1行1ファイルパス
- 空行はスキップ
- 前後の空白はトリム
- 重複パスはユニーク化(正規化後のパスで比較。例:
a/b.rs と ./a/b.rs は同一扱い)
- 相対パスのみ(絶対パスはエラー)
.. を含むパスは禁止
- バックスラッシュを含むパスは禁止(context.rs と同じ制約)
- 存在しないファイルは warning 出力してスキップ
- 入力ファイル数の上限: 500件
エッジケースの挙動
| ケース |
終了コード |
stderr |
stdout |
| stdin が TTY(パイプなし) |
1 |
Error: stdin is a terminal. Pipe input required. |
なし |
| stdin が空(0行) |
1 |
Error: no input received from stdin |
なし |
| 有効パスが1件も残らない |
1 |
Error: no valid file paths found in input |
なし |
| 関連結果が0件 |
0 |
No impacted files found |
フォーマットに応じた空結果 |
実装上の影響範囲
- CLI層:
src/main.rs: Commands enum に Impact バリアント追加、match 式にハンドラ追加
src/cli/mod.rs: pub mod impact; と pub mod stdin; 追加
src/cli/impact.rs: 新規作成(impact サブコマンドロジック)
src/cli/stdin.rs: 新規作成(stdin 読み取り・バリデーション共通ユーティリティ)
src/main.rs Search: --related-stdin オプション追加、conflicts_with 更新
- エラー型:
src/cli/search.rs SearchError: stdin 関連バリアント追加(StdinNotPiped, StdinReadError, StdinEmptyInput)
- 出力フォーマッタ:
src/output/mod.rs: ImpactResult 型追加
src/output/human.rs, json.rs, path.rs: format_impact_* 関数追加
- 注: relation_types は既存の snake_case 規約に合わせる
- テスト:
tests/cli_args.rs: help テストに impact 追加、排他テスト追加
tests/e2e_impact.rs: 新規(assert_cmd .write_stdin() 使用)
tests/e2e_related_search.rs: --related-stdin テスト追加
- 依存追加不要: TTY検出は
std::io::IsTerminal(Rust 1.70+)を使用
既存ロジックの再利用
src/search/related.rs: RelatedSearchEngine::find_related を複数ファイルに対して呼び出し
src/cli/context.rs: ファイルパスバリデーションロジック再利用
受け入れ基準
実装規模
中
関連シナリオ
関連サブコマンド
context: 複数ファイルの関連コンテキスト生成(順方向、ファイル内容マージ出力)
search --related: 単一ファイルの関連ファイル検索
概要
stdin からファイルパスリストを受け取り、変更影響範囲分析や関連ファイル検索の入力として使用する。
背景・動機
git diff --name-only | commandindex impactのパイプラインを実現提案する解決策
実装方針
impactサブコマンドは stdin またはコマンドライン引数からファイルリストを受け取るsearch --related-stdinで stdin からファイルリストを読み取る(1行1ファイルパス)--related-stdinを採用する理由: 既存の--related <FILE>は値を1つ取る Option で、clap のconflicts_with_allによる排他モデルに載っている。--related-stdinは値を取らないboolフラグとして追加し、--relatedと相互排他にすることで、既存の排他モデルを最小限の変更で拡張できる。main.rs の match 分岐ではrelated_stdinをrelatedの前に if let で先にチェックする。impact サブコマンドの機能定義
impactサブコマンドは、入力されたファイルパスリストに対して 関連ファイルの集約分析 を行う。注意: 既存の
RelatedSearchEngine::find_relatedは双方向で関連ファイルを集計する(Markdown link も import dependency も順方向・逆方向の両方を含む)。したがってimpactは厳密な「逆依存のみの分析」ではなく、「複数入力ファイルの関連ファイルを集約し、影響度スコアで降順ソートする」機能となる。将来的に逆依存のみのフィルタリングが必要になった場合は、--reverse-onlyオプション等で拡張する。context との差分:
context: 複数ファイルの関連コンテキスト生成(ファイル内容のマージ出力、LLM向け)impact: 複数ファイルの関連ファイル集約分析(影響を受けるファイルの一覧出力、CI/CD向け)具体的な処理:
RelatedSearchEngine::find_relatedを呼び出し出力スキーマ(JSON)
{ "input_files": ["src/main.rs", "src/cli/search.rs"], "impacted_files": [ { "file_path": "tests/cli_args.rs", "score": 1.5, "relation_types": ["import_dependency", "path_similarity"], "impacted_by": ["src/main.rs"] } ], "total_input_files": 2, "total_impacted_files": 5 }注:
relation_typesは既存の snake_case 命名規約に合わせる(import_dependency,path_similarity,markdown_link,tag_match,directory_proximity)search --related-stdin の出力仕様
複数ファイル入力時の集約ルール:
relation_typesは全入力からのユニーク集合--relatedと同じ(human/json/path の3形式、JSONL形式)impacted_byは含まない(既存の related 出力互換を維持)stdin 入力仕様
a/b.rsと./a/b.rsは同一扱い)..を含むパスは禁止エッジケースの挙動
Error: stdin is a terminal. Pipe input required.Error: no input received from stdinError: no valid file paths found in inputNo impacted files found実装上の影響範囲
src/main.rs: Commands enum にImpactバリアント追加、match 式にハンドラ追加src/cli/mod.rs:pub mod impact;とpub mod stdin;追加src/cli/impact.rs: 新規作成(impact サブコマンドロジック)src/cli/stdin.rs: 新規作成(stdin 読み取り・バリデーション共通ユーティリティ)src/main.rsSearch:--related-stdinオプション追加、conflicts_with 更新src/cli/search.rsSearchError: stdin 関連バリアント追加(StdinNotPiped, StdinReadError, StdinEmptyInput)src/output/mod.rs: ImpactResult 型追加src/output/human.rs,json.rs,path.rs: format_impact_* 関数追加tests/cli_args.rs: help テストに impact 追加、排他テスト追加tests/e2e_impact.rs: 新規(assert_cmd .write_stdin() 使用)tests/e2e_related_search.rs: --related-stdin テスト追加std::io::IsTerminal(Rust 1.70+)を使用既存ロジックの再利用
src/search/related.rs: RelatedSearchEngine::find_related を複数ファイルに対して呼び出しsrc/cli/context.rs: ファイルパスバリデーションロジック再利用受け入れ基準
impactサブコマンドが stdin からファイルリストを読み取れるimpactサブコマンドがコマンドライン引数からもファイルリストを受け取れるimpactサブコマンドが--format human/json/pathをサポートするsearch --related-stdinが stdin からファイルリストを読み取れるsearch --related-stdinの複数入力時の集約が union + 最大スコア採用--related-stdinと--relatedが相互排他..禁止、バックスラッシュ正規化.write_stdin()を使ったパイプ入力テスト実装規模
中
関連シナリオ
関連サブコマンド
context: 複数ファイルの関連コンテキスト生成(順方向、ファイル内容マージ出力)search --related: 単一ファイルの関連ファイル検索