Skip to content

chore: enforce formatting with lint checks and git hooks (#55) - #68

Merged
abienkowski merged 8 commits into
mainfrom
chore/format-and-hooks-55
Oct 10, 2026
Merged

abienkowski merged 8 commits into
mainfrom
chore/format-and-hooks-55

Conversation

@abienkowski

@abienkowski abienkowski commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Part of #55 (comment 3). Formatting is now enforced, both in CI and locally. Before this, make lint-* ran only go vet, cargo check and tsc. On main, gofmt flagged 3 Go files, cargo fmt reported diffs, and prettier (at width 120) flagged 13 TS files.

This PR does not close #55. The remaining items follow in a separate PR.

What changes

  • Formatters, one config per language:
    • Go: gofmt.
    • Rust: cargo fmt, with rs/rustfmt.toml = max_width = 120.
    • TS: prettier 3.9.9, pinned exactly as a devDependency, with ts/.prettierrc = { "printWidth": 120 }.
    • Width 120 is closest to the existing style: compared with the defaults, it cuts the one-time diff from 119 to 72 rustfmt hunks, and from 254 to 197 changed TS lines.
  • One-time reformat: one style: commit per language, containing formatter output only (see Verification).
  • Lint gates:
    • make lint-go fails when gofmt -l lists a file, or when the file doesn't parse, and points to make fmt-go.
    • lint-rs adds cargo fmt --check.
    • lint-ts adds npm run format:check.
    • CI's rust job installs the rustfmt component, and rust-toolchain.toml also requests it, so a minimal local rustup works too.
  • Fix targets: make fmt-go, fmt-rs, fmt-ts and fmt-all. fmt-ts and the hook call ts/node_modules/.bin/prettier directly and refuse to run without it, so they can never format with a different prettier version. Documented in CONTRIBUTING and AGENTS.md.
  • Opt-in git hooks (make hooks sets core.hooksPath=.githooks; documented in CONTRIBUTING):
    • pre-commit checks the formatting of staged Go, Rust and TS files, in about a second.
      • It reports every failing language, with the make fmt-* command to run and --no-verify for skipping once.
      • It never rewrites files.
      • It fails closed on a missing tool, and on file names git still quotes.
      • Go and TS check the staged files; Rust checks the whole crate (cargo fmt --check), because rustfmt follows mod declarations.
    • pre-push runs make lint-all.

Review notes

  • Squash or merge: both are safe. Every commit passes on its own, and no commit has a body or footer.
  • Release: merging cuts v0.3.2, a patch, because the release workflow runs on every push to main. A simulated default squash message gives bump=patch tag=v0.3.2. The release would contain no behaviour change.
  • Partial staging: the pre-commit check reads the working-tree copy of each staged file, so with git add -p it can disagree with what is committed. Pre-push and CI are the backstop. This is documented in the hook and in CONTRIBUTING.

Verification

  • The style: commits are formatter output only. I checked out each commit's parent, re-ran the formatter, and compared the result with the commit's tree. They were identical for 5768631 (gofmt), 694a175 (cargo fmt with the commit's rustfmt.toml) and e17231d (prettier 3.9.9).
  • The CI toolchain agrees with the local one. cargo fmt --check under rust:1.85 (rustfmt 1.8.0) shows no diff. Local rustfmt is 1.9.0.
  • The gates catch bad formatting. One stray space per language makes make lint-<lang> fail (exit 2).
  • The hooks work. I exercised them in a scratch clone with a local bare remote.
    • Refused:
      • misformatted Go, Rust and TS staged together, with all three languages named;
      • misformatted files named a b.go and é.go;
      • commits made from a subdirectory or a git worktree;
      • file names containing " or \;
      • a push of a misformatted commit.
    • Accepted: docs-only commits, formatted commits, merge commits and --no-verify.
    • shellcheck is clean.
  • The suites pass with unchanged counts: make test-all gives Go 108, Rust 145, and TS 162 with 1 skipped. make lint-all passes.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Tooling / maintenance (formatting, lint gates, git hooks)

Implementation(s) changed

  • Go (formatting only)
  • Rust (formatting only)
  • TypeScript (formatting only)
  • Quint specification
  • CI / infrastructure

Testing

  • Unit tests pass (make test-all): Go 108, Rust 145, TS 162 (1 skipped)
  • Integration tests pass: not run locally, because the changes are formatter-only; CI runs all three suites
  • Quint verification: not affected
  • New checks added: make lint-* format gates and the git hooks

Checklist

  • I have read CONTRIBUTING.md
  • My code follows the project's coding style
  • I have updated documentation as needed (CONTRIBUTING: git hooks)

@abienkowski abienkowski added the Type: Maintenance Added to issues and PRs when a change is for repository maintenance , such as CI or linter changes. label Oct 9, 2026
@abienkowski abienkowski self-assigned this Oct 9, 2026
@abienkowski
abienkowski merged commit bc21f81 into main Oct 10, 2026
7 checks passed
@abienkowski
abienkowski deleted the chore/format-and-hooks-55 branch October 10, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Maintenance Added to issues and PRs when a change is for repository maintenance , such as CI or linter changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deferred minor findings from the #43/#47/#50/#51 review cycles

1 participant