Skip to content

ENG-4687 pre-commit hook: cargo fmt --check + hygiene#8

Draft
jimbofreedman wants to merge 26 commits into
mainfrom
worktree-ENG-4687
Draft

ENG-4687 pre-commit hook: cargo fmt --check + hygiene#8
jimbofreedman wants to merge 26 commits into
mainfrom
worktree-ENG-4687

Conversation

@jimbofreedman

@jimbofreedman jimbofreedman commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a pre-commit configuration that runs cargo fmt --check plus standard hygiene hooks on every commit, and exposes cargo clippy on the manual stage. Includes contributor docs and machine-verified invariant + e2e tests so the hook contract cannot drift silently.

  • New .pre-commit-config.yaml — two cargo fmt --check hooks (root crate via cargo-fmt-check, nested tests/downstream_consumer sub-package via cargo-fmt-check-downstream, both on the default stage), a manual-stage cargo-clippy hook, and the pre-commit-hooks v5.0.0 hygiene baseline. Both cargo fmt invocations are direct entries (no shell), so the config works on Windows runners.
  • CONTRIBUTING.md updated with pipx install pre-commit && pre-commit install instructions (plus pip/brew alternatives) and a "before opening a PR" reminder.
  • New CI job pre-commit installs pre-commit==4.6.0 and runs cargo test --test pre_commit_e2e — AC2 inside that test invokes pre-commit run --all-files on the repo root and asserts the tree stays drift-free, so the standalone pre-commit run step was unnecessary.
  • Invariant tests (tests/pre_commit_config.rs, 11 cases) lock the YAML shape including the no-shell requirement, the dual-hook structure, and per-hook attribute presence; e2e tests (tests/pre_commit_e2e.rs, 4 cases) exercise the hooks against ephemeral git repos and skip cleanly when pre-commit, cargo fmt, or cargo clippy is absent.

Acceptance criteria

  • AC1pre-commit install succeeds on a fresh clone. Verified by the pre-commit CI job, which performs pip install pre-commit==4.6.0 followed by cargo test --test pre_commit_e2e (whose AC2 case shells out to pre-commit against the repo root).
  • AC2pre-commit run --all-files passes on the current tree. Verified by tests/pre_commit_e2e.rs::ac2_pre_commit_run_all_files_passes_on_current_tree, which also fails if any hook silently rewrites files (auto-fixer with a zero exit), and skips cleanly when the worktree has uncommitted local changes.
  • AC3 — committing misformatted Rust fails the hook with rustfmt's diff. Verified by tests/pre_commit_e2e.rs::ac3_cargo_fmt_check_fails_on_misformatted_rust, which requires rustfmt's Diff in signature in the output (no broad fallback) and skips with a rustup component add rustfmt hint if the toolchain component is absent.
  • AC4pre-commit run --hook-stage manual runs clippy (and clippy does NOT run on default stage). Verified by tests/pre_commit_e2e.rs::ac4_manual_stage_invokes_clippy (anchored on cargo's own Checking ... banner — not pre-commit's hook-name banner, which would fire even if clippy never ran) and ac4_clippy_does_not_run_on_default_stage (requires pre-commit's explicit No hook with id diagnostic plus a non-zero exit, and asserts Checking e2e_root is absent).
  • AC5 — invariants locked against silent drift. Verified by cargo test --test pre_commit_config (11/11 passing). The fmt-hook contract is now asserted per-hook (locate each - id: cargo-fmt-check* block, then check each attribute inside it) so a silently dropped attribute on either fmt hook trips the invariant.

Test plan

  • cargo fmt --check — clean
  • cargo clippy --no-deps -- -D warnings — clean
  • cargo test --test pre_commit_config — 11/11 pass
  • pipx install pre-commit (or pip install pre-commit) then cargo test --test pre_commit_e2e — 4/4 pass
  • pre-commit run --all-files — all hooks green
  • CI: all jobs green (fmt, clippy, test-matrix, features-matrix, coverage, docs, pre-commit)

ClickUp

ENG-4687: https://app.clickup.com/t/86c9umm8t

Copilot AI review requested due to automatic review settings May 20, 2026 18:46
Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
…ene)

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
…consumer

The tests/downstream_consumer/ sub-package is its own [package] (not a
workspace member), so `cargo fmt --check` from the root does not
traverse into it. Without an explicit --manifest-path invocation the
pre-commit gate would silently miss fmt drift in that crate — failing
AC3 ("committing a file with bad formatting fails the hook") for any
edit under tests/downstream_consumer/.

Extend the cargo-fmt-check hook entry to run both invocations:

  cargo fmt --check && \
  cargo fmt --manifest-path tests/downstream_consumer/Cargo.toml --check

Lock the new invariant in tests/pre_commit_config.rs and one-time-format
the existing drift in tests/downstream_consumer/src/lib.rs.

Found by peer review (Codex) on the initial implementation.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Shells out to the real `pre-commit` binary and asserts the runtime
acceptance criteria that the dev-phase string-assertion test in
`tests/pre_commit_config.rs` cannot cover:

- AC2 `pre-commit run --all-files` exits 0 on the worktree
- AC3 staging a fmt-bad `.rs` file fails `cargo-fmt-check` with a
  rustfmt diff
- AC4 `pre-commit run --hook-stage manual cargo-clippy` invokes clippy
- AC4 corollary: clippy is filtered out on the default stage (proves
  `stages: [manual]` is doing real work)

Tests are skip-clean when pre-commit/git are absent (Rust-only
contributors), so `cargo test` stays runnable without `pip install
pre-commit`. CI exercises the suite for real because pre-commit is
installed in the workflow.

AC3/AC4 isolate against a throwaway git repo built in
`tempfile::TempDir` with the real `.pre-commit-config.yaml` copied in;
AC2 runs against the actual tree and restores any auto-fixer
modifications it triggers.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
end-of-file-fixer requires a single trailing LF; the file shipped
with two from the initial repo skeleton, causing
`pre-commit run --all-files` to fail (ac2 e2e test).

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
…rgo fmt`

The AC3 fallback assertion in `tests/pre_commit_e2e.rs` accepted either
`Diff in` (the rustfmt --check signature) OR `cargo fmt` in pre-commit
output. The second alternative was too broad: pre-commit's own hook
banner prints "cargo fmt --check", so the assertion would pass even if
rustfmt stopped emitting diff output and the hook failed for some other
reason — degrading the contributor signal to "the hook failed but I
don't see why".

Narrow the fallback to `rustfmt` so the assertion only succeeds when
the output genuinely looks like rustfmt diagnostics, not just the hook
chrome.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
The "Before opening a pull request, run:" sentence used to lead directly
into the `cargo fmt --check / cargo check / ...` block. After the
pre-commit stanza was inserted above that block, the sentence read as a
lead-in to an install instruction, not a command list — disjointed UX.

Drop the stranded sentence from the section opener and move it down to
immediately precede the actual command block. No content changes, just
reordering so the sentence introduces the commands it's describing.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
The e2e tests in `tests/pre_commit_e2e.rs` shell out to the system
`pre-commit` binary and silently skip when it is not on PATH. The
existing CI workflow did not install pre-commit anywhere, so every CI
run was returning success without exercising a single hook — AC2
("pre-commit run --all-files passes"), AC3 (fmt-bad commit fails the
hook), and AC4 (manual-stage clippy) were effectively self-attested.

Add a dedicated `pre-commit` job that:
  - installs the stable Rust toolchain with rustfmt + clippy components
  - sets up Python 3.x and `pip install pre-commit`
  - runs `pre-commit run --all-files --show-diff-on-failure` (AC2 direct)
  - runs `cargo test --test pre_commit_e2e` (AC2/AC3/AC4 via harness)

Also update the module doc-comment in `tests/pre_commit_e2e.rs` to
match reality — the previous wording falsely claimed CI exercised the
tests; it now points at the new pre-commit job and is explicit that
other CI jobs intentionally skip.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Drop the bare `output.contains("clippy")` alternative from the
ac4_manual_stage_invokes_clippy probe. That substring matches
pre-commit's hook-name banner, which is printed regardless of whether
the hook entry actually executed — making the probe firable on the
banner alone. Keep `Checking ` (cargo's compile banner) and the
literal entry `cargo clippy --no-deps` as the two valid evidence
substrings.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Replace the substring `cargo clippy --no-deps` in the
ac4_clippy_does_not_run_on_default_stage filter with `Checking
e2e_root`. The previous substring overlaps the hook NAME in
.pre-commit-config.yaml, which can appear in pre-commit's output
regardless of whether clippy actually launched. `Checking e2e_root`
is cargo's compile banner for the seeded test crate and only appears
when clippy genuinely runs against it, making the negative assertion
robust against pre-commit upgrades.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Lowercase the .pre-commit-config.yaml contents before substring
matching in python_specific_backend_hooks_are_absent. The previous
test forbade the exact substring `djLint` (upstream repo casing),
which a future contributor using the lowercase hook id `djlint`
would silently bypass. Lowercasing the haystack and forbidding
`djlint` catches both casings with no enumeration.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Pre-existing drift introduced when tightening the AC3 fallback assertion;
cargo fmt --check (the form pre-commit runs) flagged it. Without this fix,
the new AC2 e2e test fails against the worktree itself.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>

Copilot AI 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.

Pull request overview

This PR introduces a repository-wide pre-commit gate to enforce cargo fmt --check plus hygiene hooks on every commit, with cargo clippy exposed as an opt-in manual-stage hook. It also adds invariant + end-to-end tests and a CI job to ensure the hook contract can’t drift unnoticed.

Changes:

  • Add .pre-commit-config.yaml with hygiene hooks, cargo fmt --check (default stage), and cargo clippy (manual stage).
  • Add invariant tests (tests/pre_commit_config.rs) and e2e tests (tests/pre_commit_e2e.rs) to lock configuration and behavior.
  • Update contributor documentation and CI to install/run pre-commit and execute the e2e suite.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/pre_commit_e2e.rs Adds end-to-end tests that shell out to pre-commit to validate AC2/AC3/AC4.
tests/pre_commit_config.rs Adds invariant tests that lock the .pre-commit-config.yaml shape via string assertions.
tests/downstream_consumer/src/lib.rs Applies formatting changes so cargo fmt --check passes.
CONTRIBUTING.md Documents pre-commit usage in the local validation workflow.
CODE_OF_CONDUCT.md Removes trailing blank line at EOF (hygiene).
.pre-commit-config.yaml Introduces the pre-commit hook configuration (hygiene + fmt + manual clippy).
.github/workflows/ci.yaml Adds a dedicated CI job to install/run pre-commit and execute e2e hook tests.
Comments suppressed due to low confidence (2)

tests/pre_commit_e2e.rs:342

  • augmented_path is built with a hard-coded : separator here as well, which is not portable to Windows PATH semantics. Use std::env::join_paths to construct the PATH value in an OS-appropriate way.
    let cargo = cargo_bin();
    let path = std::env::var("PATH").unwrap_or_default();
    let cargo_dir = Path::new(&cargo)
        .parent()
        .map(|p| p.to_string_lossy().into_owned())
        .unwrap_or_default();
    let augmented_path = if cargo_dir.is_empty() {
        path.clone()
    } else {
        format!("{cargo_dir}:{path}")
    };

tests/pre_commit_e2e.rs:412

  • Same PATH concatenation issue here: using format!("{cargo_dir}:{path}") is not portable on Windows. Prefer std::env::join_paths/split_paths so this test behaves consistently across platforms.
    let cargo = cargo_bin();
    let path = std::env::var("PATH").unwrap_or_default();
    let cargo_dir = Path::new(&cargo)
        .parent()
        .map(|p| p.to_string_lossy().into_owned())
        .unwrap_or_default();
    let augmented_path = if cargo_dir.is_empty() {
        path.clone()
    } else {
        format!("{cargo_dir}:{path}")
    };

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread .pre-commit-config.yaml Outdated
Comment thread CONTRIBUTING.md Outdated
…pport

The chained `bash -c '... && ...'` entry required bash on PATH, breaking the
Windows runners in the CI test matrix. Splitting into two separate local
hooks (`cargo-fmt-check` for the root crate, `cargo-fmt-check-downstream`
for the nested sub-package) keeps coverage identical without needing a
shell. Invariant test updated to assert both hooks exist and neither uses
a shell entry.

Reported by Copilot on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
- AC2: assert the worktree stays hook-clean after `pre-commit run` even
  if pre-commit exited 0. A silent auto-fixer rewriting files violates
  the "main-equivalent tree is hook-clean" guarantee just as much as a
  non-zero exit would. Capture the post-run diff for the error message
  before restoring the tree.
- AC3: drop the `output.contains("rustfmt")` fallback in the diff-visible
  assertion. The bare "rustfmt" substring would match unrelated error
  messages (e.g. "rustfmt component not installed"), letting AC3 pass
  for the wrong reason. Require `Diff in` only.
- AC4 corollary: tighten the negative check to require pre-commit's
  explicit "No hook with id" diagnostic and a non-zero exit. The prior
  absence-of-banner fallback could be true if clippy errored before
  printing — false positive risk.
- Extract `cargo_augmented_path()` helper using `std::env::join_paths`
  so PATH manipulation uses the platform separator (Windows uses `;`,
  Unix `:`). The old `format!("{cargo_dir}:{path}")` only worked on
  Unix. Removes ~30 lines of duplication across 3 call sites.

Reported by Copilot on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
The previous stanza jumped straight to `pre-commit install` without
explaining how to obtain the `pre-commit` tool itself. Add pipx/pip/brew
install options before the install line so the setup steps stand alone.

Reported by Copilot on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread .github/workflows/ci.yaml Outdated
Comment thread CONTRIBUTING.md Outdated
- ci: pin `pre-commit==4.6.0` in the CI job. The e2e tests assert on
  specific pre-commit diagnostic wording ("No hook with id …"); an
  unpinned upstream release could change that wording and cause
  nondeterministic CI failures.
- docs: extend the CONTRIBUTING.md manual-stage comment to include
  `-- -D warnings` so the example matches the actual hook entry.
- test(infra): tighten AC2's worktree-clean check to use
  `git status --porcelain` (empty == truly clean: no unstaged, no
  staged, no untracked) instead of `git diff --quiet`. The previous
  check only saw unstaged drift, so a contributor with staged work or
  untracked files could trigger the drift-recovery `git checkout -- .`
  and lose their in-progress changes.
- test(infra): collapse the duplicate `pre_commit_on_path` /
  `git_on_path` helpers into a single `bin_on_path(&str)`.

Reported by Copilot on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment thread tests/pre_commit_e2e.rs
Comment thread .pre-commit-config.yaml Outdated
Comment thread tests/pre_commit_config.rs Outdated
Comment thread tests/pre_commit_e2e.rs Outdated
- security(infra): drop `args: ['--unsafe']` from check-yaml. Verified
  via `yaml.safe_load(...)` that every YAML in the repo (workflows,
  config, .pre-commit-config.yaml itself) loads safely — there's no
  custom-tag YAML that needs the unsafe loader, so the flag was pure
  attack surface against running pre-commit on untrusted PR branches.
- test(infra): AC2 drift-recovery now also runs `git clean -fd` after
  `git checkout -- .` so an untracked artifact written by a hook
  doesn't leave the worktree dirty. Safe because the recovery path
  only fires when the pre-check confirmed the tree was truly clean.
- test(infra): tighten the cargo-fmt-check invariant test to match
  the full `entry:` line (post-trim) instead of a substring. The
  prior `cfg.contains("entry: cargo fmt --check")` would have happily
  passed `entry: cargo fmt --check --all` and silently expanded
  coverage. Now compares against the exact expected line for both
  hooks.
- docs(test): update the e2e module-level doc-comment from
  `std::env::temp_dir()` to `tempfile::tempdir()` (auto-cleans on
  drop) to match the implementation.

Reported by Copilot on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
@jimbofreedman
jimbofreedman requested a review from Copilot May 20, 2026 19:16

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread tests/pre_commit_e2e.rs Outdated
Comment thread tests/pre_commit_config.rs Outdated
Three nits flagged on commit fd46d11:

- AC4 `invoked` probe: drop the `cargo clippy --no-deps` substring
  alternative. It also matches pre-commit's `name:` banner, which is
  printed regardless of whether the entry actually executed (e.g. when
  the clippy toolchain component is missing). Anchor solely on cargo's
  own `Checking ...` output.
- Skip-semantics module doc: the wording "returns Ok(())" was wrong;
  these are `#[test] fn ... ()` tests that `return;` early. Updated
  the doc-comment to describe the actual mechanism.
- `cargo_fmt_check_hook_contract`: previously asserted that the four
  contract attributes appeared *somewhere* in the file. That would
  let the downstream fmt hook silently lose `pass_filenames: false`
  or `types: [rust]` without detection. Switched to a count-based
  assertion (`>= 2 occurrences` per attribute), so dropping one from
  either hook now trips the invariant.

Tests: 11/11 (config) + 4/4 (e2e) pass.

Reported by Copilot on PR #8.
- test(infra): AC4 manual-stage check now uses `pre-commit run
  --verbose` and asserts only on cargo's own `Checking <crate>`
  banner. Pre-commit swallows command stdout by default when a hook
  exits 0, so the prior version had to fall back to matching `cargo
  clippy --no-deps` — which is also the hook's `name:` in
  `.pre-commit-config.yaml` and would have appeared even if clippy
  never ran (missing toolchain component, etc.). With --verbose,
  cargo's banner is reliably visible whenever clippy actually
  executes; the substring fallback is removed.
- test(infra): tighten `cargo_fmt_check_hook_contract` to require
  `language: system`, `pass_filenames: false`, and `types: [rust]`
  appear AT LEAST twice (once per fmt hook). A bare `contains` would
  silently accept a downstream hook that lost one of those keys,
  which would break that hook in ways the existing e2e (which only
  exercises `cargo-fmt-check`) wouldn't catch.
- docs(test): clarify the skip-semantics doc-comment — the tests are
  plain `#[test] fn ... -> ()` that `return;` early when pre-commit
  is missing, not Result-returning functions. Cargo treats no-panic
  as pass, so the skip is invisible to the suite count.

Reported by Copilot on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread tests/pre_commit_e2e.rs
Comment thread tests/pre_commit_e2e.rs Outdated
The CI run of `cargo test --test pre_commit_e2e` on Linux failed AC4
because cargo's `Checking` banner came back with ANSI escape codes
glued to it (`Checking\x1b[0m e2e_root`), so the substring assertion
`output.contains("Checking ")` (with a trailing space) did not match.

`pre-commit run --color never` only controls pre-commit's own
colors, not what the underlying cargo subprocess emits. Set
`CARGO_TERM_COLOR=never` on the pre-commit env so cargo strips its
ANSI output, and tighten the substring to `Checking e2e_root` (the
seeded crate name) so the assertion fails clearly if anything other
than that specific compile happened.

Local cargo test --test pre_commit_e2e: 4/4 PASS.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.com>
Two AC2 nits flagged on commit 8d19074:

- AC2 dirty-tree behaviour: previously, the test ran
  `pre-commit run --all-files` even when `pre_clean` was false,
  and intentionally disabled the drift-recovery path in that case
  so a contributor's in-progress work wouldn't be `git checkout`-ed
  over. The side effect was that auto-fixer hooks (end-of-file-fixer,
  trailing-whitespace, mixed-line-ending) could still silently
  rewrite those in-progress changes — worse than failing. Skip
  with a clear stderr message instead; AC2 is about a
  main-equivalent CLEAN tree, not whatever transient state is in
  someone's worktree mid-edit. The post-run drift logic is now
  unconditional (no `if pre_clean { ... } else { None }`) since
  we early-return on dirty trees.
- AC2 module doc-comment: said the test snapshots `git diff --quiet`
  before/after, but the implementation uses `git status --porcelain`
  + `git diff`. Update the wording to match the actual mechanism so
  future readers don't chase the wrong command when debugging drift.

Tests: 11/11 (config) + 4/4 (e2e) pass; rustfmt clean.

Reported by Copilot on PR #8.

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread tests/pre_commit_config.rs Outdated
Comment thread .github/workflows/ci.yaml Outdated
Two nits flagged on commit bfb40f6:

- `cargo_fmt_check_hook_contract` previously used global occurrence
  counts (`>= 2`) for `language: system` / `pass_filenames: false` /
  `types: [rust]`. That could be satisfied by the cargo-clippy hook
  (which also has `language: system` and `pass_filenames: false`),
  masking a silently dropped attribute on cargo-fmt-check-downstream.
  Now scopes the check per-hook: locate each `- id: cargo-fmt-check*`
  header, read up to the next `- id:`, assert each attribute appears
  inside the block. Drops the cargo-clippy false positive entirely.
- CI workflow was running `pre-commit run --all-files
  --show-diff-on-failure` and then `cargo test --test pre_commit_e2e`
  immediately after — AC2 in that test calls `pre-commit run
  --all-files` on the same root, so the hook suite ran twice. AC2
  also asserts the tree stays drift-free, which the standalone step
  did not, so AC2 strictly supersedes it. Removed the standalone
  step; updated the comment to explain the dedup.

Tests: 11/11 (config) + 4/4 (e2e) pass; rustfmt clean.

Reported by Copilot on PR #8.

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread tests/pre_commit_e2e.rs
Comment thread tests/pre_commit_e2e.rs
Comment thread tests/pre_commit_config.rs Outdated
Two of three nits flagged on commit 5a4e172:

- AC3/AC4 toolchain-component probes: `prereqs_available()` only
  checked for `pre-commit` and `git`, but AC3 needs rustfmt (via
  `cargo fmt`) and AC4 needs clippy-driver (via `cargo clippy`).
  A contributor with `pre-commit` installed but missing rustfmt or
  clippy would hit a misleading hook failure. Added a
  `cargo_subcommand_available(name)` helper that probes `cargo <name>
  --version` with the cargo-augmented PATH, and gates AC3 / AC4 on
  it so they skip cleanly with a `rustup component add ...` hint.
- `pre_commit_config.rs` module-doc invariant list: said `cargo fmt
  --check` had four contract attributes, but the test now checks
  three per-block (`language: system`, `pass_filenames: false`,
  `types: [rust]`) — `entry:` is the fourth attribute, asserted
  separately as an exact match. Reworded the bullet to call out
  both fmt hooks and to distinguish the per-block attributes from
  the separately-asserted entry line.

The third nit (Copilot suggested making the e2e tests opt-in via
`#[ignore]` or an env var to avoid pre-commit auto-downloading hook
envs on first cargo-test run) is a design call. The reply on PR #8
explains why current skip-on-PATH-missing semantics is the right
tradeoff for this project.

Tests: 11/11 (config) + 4/4 (e2e) pass; rustfmt clean.

Reported by Copilot on PR #8.
Clippy 1.93 added the `manual_contains` lint, which fires on the
`entries.iter().any(|line| *line == "...")` pattern in
`cargo_fmt_check_hook_contract`. Both `entries.contains(&"...")` and
the `iter().any(|line| *line == ...)` form compile to the same loop,
but `contains` is more idiomatic. No behaviour change; cargo test
--test pre_commit_config still 11/11 green.

Reported by clippy CI on PR #8.

Signed-off-by: Jimbo Freedman <jimbo@spot-ship.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.

2 participants