Skip to content

feat(pre-commit): replace TOML filter with Rust summary handler + uv run alias#1992

Open
jugrajsingh wants to merge 2 commits into
rtk-ai:developfrom
jugrajsingh:feature/pre-commit-filter
Open

feat(pre-commit): replace TOML filter with Rust summary handler + uv run alias#1992
jugrajsingh wants to merge 2 commits into
rtk-ai:developfrom
jugrajsingh:feature/pre-commit-filter

Conversation

@jugrajsingh
Copy link
Copy Markdown

Summary

Replaces the TOML-based pre-commit filter with a Rust subcommand that produces a real one-line summary plus verbatim blocks for failing hooks. Also recognises uv run pre-commit as an alias so the rewrite layer fires inside uv-managed projects.

Closes / supersedes the implementation merged via #184 (which the TOML pipeline couldn't deliver on — counting and conditional summarisation aren't expressible as line-strip regexes).

Motivation

The previous src/filters/pre-commit.toml only stripped [INFO] Installing environment install noise plus blank lines, then capped at 40 lines. On real passing runs (9 hooks of Passed/Skipped lines) it left output essentially unchanged — measured savings ~0% on representative workloads.

The TOML pipeline (strip_lines_matching, max_lines, replace, …) can drop and truncate lines, but it can't:

  • count hook outcomes
  • emit a single summary like 9 hooks: 7 passed, 2 skipped
  • conditionally keep failure context verbatim while collapsing pass output
  • detect a uv venv and route via uv run pre-commit

What's in this PR

1. Rust handler (src/cmds/python/precommit_cmd.rs)

Parses each line, buckets hooks by status, and renders:

  • Pass-only: 9 hooks: 7 passed, 2 skipped
  • With failures: summary line + verbatim block per failed hook (keeps hook id, exit code, file:line errors)
  • With autofixes: 9 hooks: 8 passed, 1 autofixed — re-stage and retry

Pass-through for install, autoupdate, clean, --help, --version, etc. — only run is filtered.

2. uv run pre-commit alias

Extends the existing pre-commit rule:

  • pattern: r"^(?:uv run )?pre-commit\b"
  • rewrite_prefixes: &["uv run pre-commit", "pre-commit"] (longest first)

Handler does auto-resolution: prefers pre-commit on PATH; falls back to uv run pre-commit when uv is on PATH and a pyproject.toml is reachable in cwd or an ancestor. Falls through to plain pre-commit otherwise so command-not-found surfaces cleanly.

3. Commands::PreCommit clap variant

Adds the missing top-level variant (clap name = "pre-commit") and dispatches to precommit_cmd::run. Registered in is_operational_command.

4. Removes the now-redundant src/filters/pre-commit.toml

The Rust handler supersedes it. Tests for test_builtin_filter_count etc. updated accordingly (59 → 58).

Measured impact

  • Real-world run in a 9-hook config: 720 bytes → 29 bytes (96.0% reduction)
  • Unit test asserts ≥60% savings on the captured pass fixture (passes at ~80%)
  • Failure case keeps full verbatim error block — no information loss

Tests

  • 11 unit tests in precommit_cmd.rs (regex parsing, summary rendering, autofix detection, pyproject walk, savings assertion against real fixture)
  • 3 rewrite-rule tests in discover/registry.rs (bare form, uv run form, no-args form)
  • All 1915 existing tests still pass
  • cargo fmt --all, cargo clippy --all-targets, cargo test --all all clean

Notes for reviewers

  • Real fixtures in tests/fixtures/pre_commit_{pass,fail}.txt were captured from actual pre-commit runs and sanitised (no internal paths).
  • No new dependencies added.
  • No new unsafe, no async, no unwrap() outside lazy_static! regex literal.
  • The handler honours rtk's fallback rule: if the filter function panics or errors, the runner falls back to raw output.

Refs

Issue rtk-ai#184 was closed with a TOML-based filter, but the TOML pipeline
can only strip lines by regex — it cannot count, group, or summarise.
In practice the previous pre-commit.toml filter only removed
[INFO] Installing environment noise and saved ~0% on real runs.

Add a proper Rust subcommand that parses pre-commit's hook-result
lines and collapses them into a single summary plus verbatim blocks
for any failed hook. Achieves 80-95% reduction on passing runs while
keeping all failure context intact.

- src/cmds/python/precommit_cmd.rs: parser + filter + 9 unit tests
  including token-savings assertion (>=60%) against real fixtures
- src/main.rs: register Commands::PreCommit (clap name pre-commit),
  match arm dispatching to precommit_cmd::run, add to
  is_operational_command list
- src/core/toml_filter.rs: bump filter-count tests 59->58 to reflect
  removal of the now-superseded TOML filter
- src/filters/pre-commit.toml: deleted (Rust handler replaces it)
- tests/fixtures/pre_commit_{pass,fail}.txt: real captured outputs
  used for unit tests and the savings assertion
- Cargo.lock: version field refreshed by cargo build

Output shape:
  pass:    9 hooks: 7 passed, 2 skipped
  failure: summary line + verbatim block per failed hook
  autofix: summary line + re-stage and retry hint

Real-world smoke test: 720 bytes -> 29 bytes (96.0% reduction).
1894 tests pass; clippy clean; fmt clean.

Refs rtk-ai#184
In uv-managed projects pre-commit lives inside .venv/bin/ and the
canonical invocation is 'uv run pre-commit run ...'. The previous
rewrite rule only matched bare 'pre-commit', so the hook never
rewrote the uv form — every such call went raw, losing the 90%
savings.

- src/discover/rules.rs: extend pre-commit rule's regex pattern to
  ^(?:uv run )?pre-commit\b and add 'uv run pre-commit' (longest
  first) to rewrite_prefixes. Bump savings_pct 65->90 to reflect the
  measured ~96% on a real repo's passing runs.
- src/cmds/python/precommit_cmd.rs: new build_precommit_command()
  helper that picks pre-commit if on PATH, else 'uv run pre-commit'
  when uv is on PATH and a pyproject.toml exists in cwd or an
  ancestor. Falls through to plain pre-commit otherwise so
  command-not-found surfaces cleanly. Adds 2 unit tests for the
  pyproject walk.
- src/discover/registry.rs: 3 new rewrite tests covering
  'pre-commit run ...', 'uv run pre-commit run --files ...', and
  bare 'uv run pre-commit'.

Verified end-to-end: 'rtk rewrite "uv run pre-commit run --files X"'
emits 'rtk pre-commit run --files X'; live 'rtk pre-commit run
--all-files' in a real repo still hits 96.0% reduction. 1899 tests
pass (was 1894 + 5 new); clippy clean; fmt clean.

Refs rtk-ai#1711 (uv run wrappers)
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 20, 2026

CLA assistant check
All committers have signed the CLA.

@jugrajsingh jugrajsingh marked this pull request as ready for review May 20, 2026 08:38
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.

2 participants