Skip to content

chore: add clang-format + codespell lint gate - #48

Merged
balbasty merged 1 commit into
mainfrom
claude/18-cpp-lint-format
Aug 1, 2026
Merged

chore: add clang-format + codespell lint gate#48
balbasty merged 1 commit into
mainfrom
claude/18-cpp-lint-format

Conversation

@balbasty

Copy link
Copy Markdown
Collaborator

Part of #18 — item D6, "No C++ lint/format/codespell". The five Python
repos have run ruff + codespell since they were created; none of the six
C++/CUDA repos had a .clang-format, a .clang-tidy or any spell-check.

This is one of six identical PRs, one per C++ repo (fastfields-kernels,
-cpu-impl, -cuda-impl, -cpu-lib, -cuda-lib, -lib). The three files
added are byte-identical across all six.

What this adds

  • .clang-formatderived from the code that is already here, not
    picked off the shelf. I measured the tree before choosing anything:
    4-space is the dominant indent level in every repo (including kernels,
    where a handful of files such as distance/l1.h are 2-space outliers), the
    p90 line length is 68–78 so the column limit is 80, and the code
    consistently spells pointers/references scalar_t * f / DLTensor & out
    (PointerAlignment: Middle). Function braces go on their own line with
    control-flow braces attached (BreakBeforeBraces: Stroustrup), matching the
    existing sources. CUDEV/CUGLOB/CUHOST are declared as AttributeMacros
    so clang-format stops parsing them as a return type and mangling the
    signature that follows, and FF_NAMESPACE_BEGIN/_END as StatementMacros.
  • .codespellrc — the same check the Python repos run, with this
    project's vocabulary allow-listed (nd for N-dimensional, numer/denom,
    mone for the literal −1, the t<name> DLTensor locals in the C++ tests,
    unser for M. Unser of the cited B-spline papers, …) and the vendored
    dlpack.h skipped.
  • .github/workflows/lint.yaml — a thin, self-contained per-repo workflow
    alongside the existing test.yaml, matching the shape of the Python repos'
    lint.yaml: a blocking codespell job pinned to the same 2.4.3 that
    fastfields/.github's reusable python-lint.yml pins, plus a
    clang-format job. Both carry the concurrency group and
    timeout-minutes the other C++ gates already have.

No source file is reformatted in this PR.

Honest note: the clang-format check is diff-scoped, not whole-tree

The task asked for clang-format --dry-run --Werror over the tracked files,
and asked me to confirm it passes before opening the PR. It does not pass,
and no configuration can make it pass.
I measured this rather than assuming
it — with the config in this PR, clang-format would rewrite:

repochanged linesfiles differing
fastfields-kernels24 72747 / 54
fastfields-cpu-impl7 52812 / 12
fastfields-cuda-impl9 94812 / 12
fastfields-cpu-lib11 51732 / 32
fastfields-cuda-lib6 85218 / 18
fastfields-lib3 18120 / 20

Stock LLVM/Google styles are worse (≈89 k changed lines each); the config here
is the best fit I could find (≈63 k). The residual is irreducible: much of the
code is hand column-alignedDLTensor & out , in the parameter
lists, the backslash-aligned dispatch macro blocks — which clang-format cannot
reproduce by design.

So the whole-tree gate had exactly two possible outcomes, and CONTRIBUTING.md
rules out both: a permanently red main, or a mass reformat bundled into a
tooling PR ("never bundle"). The workflow therefore checks only the lines a
pull request actually touches
, via
git clang-format --diff <merge-base> — the incremental-adoption pattern LLVM
itself uses. New and modified code conforms from now on; the one-shot reformat
stays available as its own reviewable change.

Verification

  • codespell exits 0 in this repo with the committed .codespellrc
    (checked with the pinned 2.4.3, the same version CI installs).
  • The CI clang-format command was run locally against this branch's merge base
    and prints no modified files to format — this PR passes its own gate.
  • The gate is not vacuous: appending
    void ff_fmt_probe ( int*x ){if(x){*x=1 ;}} to posdef.cpp and re-running
    the exact CI command produced a failing diff proposing
    void ff_fmt_probe(int * x) with the brace on its own line and int * x
    spacing — i.e. it enforces the project's real style on new lines while
    leaving the untouched legacy lines in the same file alone. (Probe reverted;
    not in the diff.)
  • Config parse checked with clang-format 18; the workflow pins
    clang-format-18 so formatting cannot drift with the runner image.

Workstream: claude-jitfields-to-fastfields

🤖 Generated with Claude Code


Generated by Claude Code

The six C++/CUDA repos had no formatting, lint or spell-check configuration
of any kind, while the five Python repos have run ruff + codespell since they
were created (fastfields-lib#18, item D6).
Adds, identically across all six C++ repos:
* `.clang-format` -- derived from the code that is already here rather than
taken off the shelf: 4-space indent (the dominant indent level in every
repo), an 80-column limit (the p90 line length is 68-78), `T * p` / `T & r`
middle alignment, function braces on their own line with control-flow braces
attached, and `CUDEV`/`CUGLOB`/`CUHOST` declared as attribute macros so
clang-format stops parsing them as return types.
* `.codespellrc` -- the same checks the Python repos run, with the project's
domain vocabulary (`nd`, `numer`, `mone`, the `t<name>` DLTensor locals,
M. Unser) allow-listed and the vendored `dlpack.h` skipped.
* `.github/workflows/lint.yaml` -- codespell (blocking, pinned to the same
2.4.3 the reusable python-lint.yml pins) plus a clang-format check.
The clang-format check is scoped to the lines a pull request touches
(`git clang-format --diff <merge-base>`) rather than the whole tree. The tree
predates the config and is hand-column-aligned in many places, so a whole-tree
`--dry-run --Werror` flags essentially every file; gating on that would mean
either a permanently red main or a mass reformat bundled into an unrelated
change. Diff-scoped checking makes new and modified code conform from now on
and leaves the one-shot reformat as its own reviewable PR.
No source file is reformatted here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016AjQcY78NgbagPSbPJRr6Z
@balbasty
balbastyforce-pushed the claude/18-cpp-lint-format branch from cc6184e to 9515880CompareAugust 1, 2026 20:32
@balbasty
balbasty merged commit 4f6e0ef into mainAug 1, 2026
3 checks passed
@balbasty
balbasty deleted the claude/18-cpp-lint-format branch August 1, 2026 20:47
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@balbasty@claude