Skip to content

refactor(hooks-post-tool-comment-lint-rust): main.rs を 7 module に分割 (PR-W1、self-host irony 解消) - #220

Merged
aloekun merged 2 commits into
masterfrom
pr-w1-comment-lint-split
Jun 24, 2026
Merged

refactor(hooks-post-tool-comment-lint-rust): main.rs を 7 module に分割 (PR-W1、self-host irony 解消)#220
aloekun merged 2 commits into
masterfrom
pr-w1-comment-lint-split

Conversation

@aloekun

@aloekun aloekun commented Jun 24, 2026

Copy link
Copy Markdown
Owner

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.rs 197 HookInput / HookOutput structs、main、dispatch、emit_feedback / emit_violations_feedback / run_metrics_mode、hook-input parsing tests (3)
violations.rs 38 LintViolation / ViolationLocation / ViolationFix / ViolationExample structs + MAX_VIOLATIONS
comment_lint.rs 429 Bundle Z #B-α コメント検出 (ALLOWED_LINE_PREFIXESis_allowed_commentfind_violations、helpers)、tests (31)
metrics.rs 286 FileMetrics / FunctionMetric + AST walker (compute_metricscollect_functionswalk_for_blocks)、tests (12)
function_length.rs 183 MAX_FUNCTION_LINES = 50 const + find_function_length_violations、tests (10)
file_length.rs 197 MAX_FILE_LINES = 800 const + find_file_length_violations + count_source_lines、tests (12)
line_filter.rs 379 ToolInputcompute_changed_lineslocate_string_line_rangesbyte_offset_to_linespan_overlaps_rangesis_rust_fileextract_file_pathcollect_all_violations、tests (30)
合計 1709 行 (元 1606 行 + 103 行: module header / 重複 helper / find_violations 分割)

全 file ≤ 429 行 (800 行制限の 54% 安全余地)。

behavior 不変性の保証

  • 関数 signature 変更なし、struct field rename なし、default 値変更なし、定数値変更なし
  • 公開 API (cross-module で参照される関数) は pub(crate) 付与のみ、export 経路は同等
  • test count baseline 不変: 100 tests pass (master baseline 100 tests と完全一致)
  • cargo clippy -p hooks-post-tool-comment-lint-rust -- -D warnings: clean
  • cargo fmt --check: clean
  • cargo 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_linesextract_file_path) が line_filter.rs に居るため。main.rsuse line_filter::ToolInput; で import
  • is_allowed_commentcomment_lint.rs に集約: metrics::count_non_doc_comments から pub(crate) で参照 = allow-list semantics の single source of truth
  • test helper の per-module duplicate: make_source_with_lines / make_function_with_lines / tool_input_with 等は memory feedback_test_dry_antipattern.md per、各 test module に独立 copy
  • non-doc コメント削除: 元 main.rs の関数 body 内 // foo 形式の pre-existing コメントを Write 時に削除 (PR-3a で確立した cleanup pattern)

planning doc status 更新

本 PR には commit 2 つが含まれる:

  1. 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)
  2. 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_check block_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: clean
  • cargo fmt --check: clean
  • cargo build --workspace: clean
  • 全 file ≤ 429 行 (800 行制限内、54% 安全余地)
  • Self-host dogfood: release exe が 7 split files に対して 0 violations
  • takt pre-push-review approved (Result: Success、554s)

PR 計画における位置

master (PR #218 + #219 land 済、planning doc + weekly audit 確立)
  ↓
本 PR (PR-W1、hooks-post-tool-comment-lint-rust 分割) ← 本 PR
  ↓
PR-W2 (cli-pr-monitor 分割: poll/mod.rs 1404 + fix_commit.rs 972)
  ↓
PR-W3 (cli-merge-pipeline 分割: feedback.rs 1432 + main.rs 890)
  ↓
PR-W4 (cli-push-runner 分割: lint_screen.rs 982 + config.rs 946)
  ↓
PR-W5 (Stop hook gate 追加、Phase 2 完了)
  ↓
[将来] PR-W6 (C → B 移行検討)

本 PR 後 weekly-review file_length watchlist の件数: 7 → 6 件 に減少。

Summary by CodeRabbit

  • 新機能

    • Rustコード向けに、コメントの禁止ルール、関数の長さ、ファイル全体の長さをまとめてチェックできるようになりました。
    • 変更範囲に応じて、対象箇所だけを絞って検査する仕組みが追加されました。
    • --metrics で、コメント数や関数の長さ・入れ子の深さをJSONで取得できます。
  • 改善

    • 違反メッセージの出力形式が整理され、より一貫したフィードバックが返るようになりました。

aloekun added 2 commits June 25, 2026 02:16
PR #219 (PR-W0、weekly-review に file_length scan facet 追加) が
2026-06-24T16:07:42Z に master へ land したことを受けて、
docs/file-length-enforcement-plan.md の進捗追跡 table の PR-W0 status を
`[in progress]` → `[x] #219` に更新する。
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。
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

main.rs に集中していた Rust lint ロジック(コメント禁止・関数長・ファイル長・メトリクス計算・変更行フィルタ・違反データ構造)を violations.rscomment_lint.rsfile_length.rsfunction_length.rsmetrics.rsline_filter.rs の 6 モジュールに分割した。main.rs は入力解析・dispatch・出力のオーケストレーションのみを担うよう再編された。

Changes

Rust lint hook モジュール分割

Layer / File(s) Summary
lint 違反データ構造の定義
src/hooks-post-tool-comment-lint-rust/src/violations.rs
LintViolationViolationLocationViolationFixViolationExampleserde::Serialize 対応構造体群と MAX_VIOLATIONS = 20 定数を新規定義した。
コメント lint の実装とテスト
src/hooks-post-tool-comment-lint-rust/src/comment_lint.rs
tree-sitter で Rust 構文木を解析し、/////!// TODO: 等の許可マーカーに該当しない行/ブロックコメントを LintViolation として収集する。line_filter による範囲絞り込みと MAX_VIOLATIONS 上限、境界条件を含む網羅的なテストを追加した。
ファイル長 lint の実装とテスト
src/hooks-post-tool-comment-lint-rust/src/file_length.rs
MAX_FILE_LINES = 800 超過時に RUST_FILE_TOO_LONG 違反を 1 件返す。line_filter が空(純削除)の場合のみスキップし、末尾改行考慮の count_source_lines と境界/フィルタ挙動テストを追加した。
関数長 lint の実装とテスト
src/hooks-post-tool-comment-lint-rust/src/function_length.rs
MAX_FUNCTION_LINES = 50 超過関数を RUST_FUNCTION_TOO_LONG として検出。line_filter の有無で touch-trigger ratchet / grandfather / スキップを切り替え、上限と JSON フィールド検証テストを含む。
メトリクス計算モジュールの実装とテスト
src/hooks-post-tool-comment-lint-rust/src/metrics.rs
--metrics モード向けに FileMetricsFunctionMetric を定義し、tree-sitter で非ドキュメントコメント数・関数行範囲・最大ネスト深度を計算する compute_metrics を新規追加した。
line_filter dispatch 層の実装とテスト
src/hooks-post-tool-comment-lint-rust/src/line_filter.rs
Edit ツール入力の new_string からバイトオフセット→1-indexed 行範囲を算出するユーティリティ群と、3 つの lint 結果を MAX_VIOLATIONS で切り詰めて返す collect_all_violations を新規実装した。UTF-8 境界・複数出現・各ツール名パターンのテストを含む。
main.rs のオーケストレーション集約
src/hooks-post-tool-comment-lint-rust/src/main.rs
lint 実装を全てモジュールへ移し、HookInput パース→ファイルパス抽出→Rust 判定→フィルタ生成→collect_all_violationsemit_violations_feedback の直列フローに再編した。HookOutput/HookSpecificOutput によるフィードバック出力と --metrics モードも整理した。

進捗ドキュメント更新

Layer / File(s) Summary
PR-W0 進捗状態の更新
docs/file-length-enforcement-plan.md
PR-W0 の状態を [in progress] から [x] #219 (merged at 2026-06-24T16:07:42Z) へ更新した。

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)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • aloekun/claude-code-hook-test#104: line_filter.rsspan_overlaps_rangescomment_lint.rsline_filter 適用ロジックは、このPRで追加された Edit 影響行への lint 絞り込み変更と直接関連している。
  • aloekun/claude-code-hook-test#105: find_function_length_violations / RUST_FUNCTION_TOO_LONG / MAX_FUNCTION_LINES=50 のロジックがこのPRで function_length.rs へ切り出されており、元の関数長 lint 追加と強いコードレベルの連続性がある。
  • aloekun/claude-code-hook-test#151: このPRが新設した byte_offset_to_line / locate_string_line_ranges / 行範囲オーバーラップロジックは、取得PRで追加された同名ユーティリティとテストの直接的な後継となっている。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed main.rs を 7 モジュールに分割する主変更を具体的に表しており、内容も正確です。
Docstring Coverage ✅ Passed Docstring coverage is 98.31% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 33a845d and f5335c3.

📒 Files selected for processing (8)
  • docs/file-length-enforcement-plan.md
  • src/hooks-post-tool-comment-lint-rust/src/comment_lint.rs
  • src/hooks-post-tool-comment-lint-rust/src/file_length.rs
  • src/hooks-post-tool-comment-lint-rust/src/function_length.rs
  • src/hooks-post-tool-comment-lint-rust/src/line_filter.rs
  • src/hooks-post-tool-comment-lint-rust/src/main.rs
  • src/hooks-post-tool-comment-lint-rust/src/metrics.rs
  • src/hooks-post-tool-comment-lint-rust/src/violations.rs

Comment thread docs/file-length-enforcement-plan.md
@aloekun
aloekun merged commit 08f173f into master Jun 24, 2026
1 check passed
@aloekun
aloekun deleted the pr-w1-comment-lint-split branch June 24, 2026 18:04
aloekun added a commit that referenced this pull request Jun 26, 2026
…#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>
aloekun added a commit that referenced this pull request Jul 2, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant