refactor(hooks-post-tool-comment-lint-rust): main.rs を 7 module に分割 (PR-W1、self-host irony 解消) - #220
Conversation
docs/file-length-enforcement-plan.md PR-W1 を実装。 lint hook 本体 (1606 行) を coding-style.md § File Organization (800 行 max) 内に収まる module 構成に分割。behavior 不変な mechanical refactor で 関数 signature・公開 API・field 名・default 値はすべて保持。 順位 147 (file_length lint、PR #202 land) を自分自身に適用した self-host の整合性を確立。本 PR が land すれば 7 files 中 1 件 (1606 行) を 800 行 以下に解消、weekly-review file_length watchlist の件数が 7 → 6 に減少。 分割計画は計画書 PR-W1 section + Appendix A Agent prompt template 参照。 PR-3a (#217) の hooks-session-start 分割と同型 procedure を Agent 委譲で 実装、behavior 不変性は test count 不変 + cargo clippy clean で verify。
📝 WalkthroughWalkthrough
ChangesRust lint hook モジュール分割
進捗ドキュメント更新
Sequence Diagram(s)sequenceDiagram
participant stdin
participant main as main.rs
participant lf as line_filter.rs
participant col as collect_all_violations
participant cl as comment_lint.rs
participant fl as function_length.rs
participant fil as file_length.rs
stdin->>main: HookInput JSON (tool_name, tool_input)
main->>lf: extract_file_path(tool_input)
lf-->>main: file_path
main->>lf: is_rust_file(file_path)
lf-->>main: true
main->>lf: compute_changed_lines(tool_name, tool_input, source)
lf-->>main: Option<Vec<(usize, usize)>>
main->>col: collect_all_violations(file_path, source, line_filter)
col->>cl: find_violations(...)
col->>fl: find_function_length_violations(...)
col->>fil: find_file_length_violations(...)
col-->>main: Vec<LintViolation> (MAX_VIOLATIONS で切り詰め済み)
main->>stdin: emit_violations_feedback → HookOutput JSON (stdout)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/file-length-enforcement-plan.md`:
- Line 427: The merged-at timestamp in the docs entry is using UTC with an
explicit timezone qualifier, which is inconsistent with the docs/JST convention.
Update the PR-W0 record in docs/file-length-enforcement-plan.md to record the
merge time in JST local time and omit the timezone suffix, keeping the existing
merged-at field and PR identifier unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d7fe9eb4-e766-4891-9fc6-cf6730067191
📒 Files selected for processing (8)
docs/file-length-enforcement-plan.mdsrc/hooks-post-tool-comment-lint-rust/src/comment_lint.rssrc/hooks-post-tool-comment-lint-rust/src/file_length.rssrc/hooks-post-tool-comment-lint-rust/src/function_length.rssrc/hooks-post-tool-comment-lint-rust/src/line_filter.rssrc/hooks-post-tool-comment-lint-rust/src/main.rssrc/hooks-post-tool-comment-lint-rust/src/metrics.rssrc/hooks-post-tool-comment-lint-rust/src/violations.rs
…#221) * fix(lib-report-formatter): clippy unnecessary_sort_by を sort_by_key に解消 * fix(cli-push-runner): jj git push --all で新規 bookmark の push を修正 bare `jj git push` は tracking 済み bookmark のみ push するため、新規 bookmark (未 tracking) が push されず、jj は exit 0 のまま "Refusing to create new remote bookmark" を出力して何もしない。push-runner はこれを false success と誤報告していた (実 push 未完了を「成功」と誤表示)。jj 0.42 には --allow-new フラグは無いため --all を使う。 - config (push-runner-config.toml / template): command を "jj git push --all" に - stages/push.rs: push_was_refused() で "Refusing to" 出力を検知し失敗扱いに変更 (+ unit tests 4 件) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(file-length-enforcement-plan): PR-W1 (#220) land を status に反映 + 実績節を追加 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ied-files batch mode + [file_length_gate] opt-in (#234) * docs(todo): PR #232 post-merge-feedback 採用 1 件を登録 (順位 246) * feat(hooks): PR-W5 file-length Stop gate — comment-lint --check-modified-files batch mode + [file_length_gate] opt-in Phase 1 (PR-W1〜W4、#220/#224/#230/#231) で 800 行以下に整えた clean state を恒久維持する 強制層。hooks-post-tool-comment-lint-rust に --check-modified-files batch mode を追加し、 Stop hook quality_gate の 1 step として PR 範囲 (base..@) の .rs file 行数を検査。 800 行超が 1 件でもあれば exit 1 で Stop を block する (Option C-2)。 実装: - src/hooks-post-tool-comment-lint-rust/src/modified_files_check.rs (新規、17 tests) - main.rs に --check-modified-files dispatch 追加、Cargo.toml に toml 依存追加 - .claude/hooks-config.toml に file-length step + [file_length_gate] section mechanical refactor、behavior 不変。既存 lint (comment/function/file_length/metrics) は不変。 ## ADR-039 3 点セット (experimental feature 標準パターン) - Config opt-in (default OFF): gate_enabled() が unwrap_or(false)。本 repo のみ dogfood で enabled=true - Kill-switch: 下表 - Bounded lifetime: file-length-enforcement-plan.md 削除条件 3 (override 未使用で 1-2 セッション通過) ## Kill-switch table | 起動経路 | 停止コマンド | 影響範囲 | |---|---|---| | .claude/hooks-config.toml の [file_length_gate] enabled=true + file-length step | enabled=false (恒久) | Stop hook の file-length 判定のみ (他 step 不変) | | Stop hook 発火時に file-length step 実行 | env FILE_LENGTH_CHECK_OVERRIDE=1 (緊急、truthy 値) | 当該 Stop の判定を skip | ## 設計判断 - jj 変更検出は base branch を config 引数化 (default master、ADR-021 § Revset Composability) - cmd path は cmd.exe の forward-slash 非対応のため backslash TOML literal string - jj 失敗時は fail-closed で block (ADR-043、stop_hook_active retry-skip が永続 lock を防止) - templates (TS/Python) は Rust 非対象のため未追加 ## 検証 - cargo test -p hooks-post-tool-comment-lint-rust: 116 pass / clippy clean / fmt clean - cargo test --workspace: regression なし / cargo clippy --workspace clean - dogfood (deploy 済 exe): clean=exit0 / 850行file=block / OVERRIDE(=1,=true)=bypass / enabled=false=no-op / self-host=exit0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(review): CodeRabbit #234-1 fail-closed 対応 + 削除 file skip 補正 CodeRabbit Major #234-1 (読み取り不能な既存 .rs は fail-closed に) を適用: collect_oversize_files を Result 化し、存在するのに読めない .rs は Err → exit 1 (block)。 さらに削除 file 誤検知を補正: jj diff --name-only は削除 file も列挙する (実測確認) ため、 Path::exists() で存在確認し削除 file (非存在) は skip する。これがないと file split refactor (元 file 削除を伴う、本 plan が促進する作業そのもの) を gate が誤 block する。 CodeRabbit の指摘文言も「*既存* .rs」であり削除 file は対象外。 - collect_oversize_files: filter(Path::exists) + Result<Vec, String> - fail-closed 診断を run_check_modified_files で block 表示 (ADR-043 § 原則1) - tests: skips_deleted_file (skip) + errors_on_present_but_unreadable (Err) で両分岐を assert Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
docs/file-length-enforcement-plan.md(PR #218 で land 済) の PR-W1 を実装。hooks-post-tool-comment-lint-rust/src/main.rs(1606 行) を module 分割し、coding-style.md § File Organization (800 行 max) 内に収まる構成にする。self-host irony の解消: 本 crate は順位 147 file_length lint (PR #202) を enforce する lint hook の本体だが、自分自身が 1606 行で違反状態だった。本 PR で 7 module に分割し、最大 file が 429 行 (
comment_lint.rs) になることで lint hook 自身が self-consistent state に到達する。PR-3a (#217) で実証した「Agent 委譲 + behavior 不変 mechanical refactor + PR_SIZE_CHECK_OVERRIDE」テンプレート (計画書 Appendix A) をそのまま適用。
分割結果
main.rsHookInput/HookOutputstructs、main、dispatch、emit_feedback/emit_violations_feedback/run_metrics_mode、hook-input parsing tests (3)violations.rsLintViolation/ViolationLocation/ViolationFix/ViolationExamplestructs +MAX_VIOLATIONScomment_lint.rsALLOWED_LINE_PREFIXES、is_allowed_comment、find_violations、helpers)、tests (31)metrics.rsFileMetrics/FunctionMetric+ AST walker (compute_metrics、collect_functions、walk_for_blocks)、tests (12)function_length.rsMAX_FUNCTION_LINES = 50const +find_function_length_violations、tests (10)file_length.rsMAX_FILE_LINES = 800const +find_file_length_violations+count_source_lines、tests (12)line_filter.rsToolInput、compute_changed_lines、locate_string_line_ranges、byte_offset_to_line、span_overlaps_ranges、is_rust_file、extract_file_path、collect_all_violations、tests (30)find_violations分割)全 file ≤ 429 行 (800 行制限の 54% 安全余地)。
behavior 不変性の保証
pub(crate)付与のみ、export 経路は同等cargo clippy -p hooks-post-tool-comment-lint-rust -- -D warnings: cleancargo fmt --check: cleancargo build --workspace: downstream regression なしself-host dogfood
split 後に release exe を 7 split files に対して実行 → 0 violations を確認。lint hook 本体が自分自身のルール全部 (function-body コメント禁止 / 関数長 50 行 / ファイル長 800 行) を pass する self-consistent state に到達。
注目すべき設計詳細
find_violations(元 64 行) を 3 helper に分割:find_violations/collect_comment_violations/build_violation_for_node。50 行/関数 制限に収まるための分割で、本 PR を Write する過程で 本 crate 自身の hook が catch して指示 した = 期待通りの dogfood 動作ToolInputの配置をmain.rsではなくline_filter.rsに: 主消費者 (compute_changed_lines、extract_file_path) がline_filter.rsに居るため。main.rsはuse line_filter::ToolInput;で importis_allowed_commentをcomment_lint.rsに集約:metrics::count_non_doc_commentsからpub(crate)で参照 = allow-list semantics の single source of truthmake_source_with_lines/make_function_with_lines/tool_input_with等は memoryfeedback_test_dry_antipattern.mdper、各 test module に独立 copy// foo形式の pre-existing コメントを Write 時に削除 (PR-3a で確立した cleanup pattern)planning doc status 更新
本 PR には commit 2 つが含まれる:
docs(plan): PR-W0 を [x] #219 (merged at 2026-06-24T16:07:42Z) に更新— PR-W0 の land 状況を docs/file-length-enforcement-plan.md の進捗追跡 table に反映 (PR feat(weekly-review): file_length scan を pre-LLM step として追加 (PR-W0) + 順位 222 採用 #219 merge 後の docs maintenance、bundle で land)refactor(hooks-post-tool-comment-lint-rust): main.rs を module 分割 (PR-W1)— 本 PR の主目的merge 後に PR-W1 status も
[x] #<本 PR>への更新が必要 (PR-W2 commit と bundle 想定)。pr_size_check override の理由
本 PR の jj diff は ~3300 行 (= 削除 1606 + 追加 1709) で
pr_size_checkblock_threshold 1500 を超過したが、これは「mechanical refactor で同じ code を別 file に移動」した結果で、PR-3a (#217) と同じ override 想定 use case。PR_SIZE_CHECK_OVERRIDE=1で override。Test plan
cargo test -p hooks-post-tool-comment-lint-rust: 100 passed / 0 failed (baseline 100 不変)cargo clippy -p hooks-post-tool-comment-lint-rust -- -D warnings: cleancargo fmt --check: cleancargo build --workspace: cleanPR 計画における位置
本 PR 後 weekly-review file_length watchlist の件数: 7 → 6 件 に減少。
Summary by CodeRabbit
新機能
--metricsで、コメント数や関数の長さ・入れ子の深さをJSONで取得できます。改善