Skip to content

Fix #34: add CI static code quality tests for this project - #43

Merged
lefticus merged 3 commits into
cpp-best-practices:mainfrom
leftibot:fix/issue-34-add-ci-static-code-quality-tests-for-thi
Nov 3, 2026
Merged

lefticus merged 3 commits into
cpp-best-practices:mainfrom
leftibot:fix/issue-34-add-ci-static-code-quality-tests-for-thi

Conversation

@leftibot

Copy link
Copy Markdown
Contributor

Automated fix by @leftibot.

What changed

Fix #34: Add CI static code quality and copy-paste detection
The project had no static quality gate, so lint, formatting and typing
drift went unnoticed. A new single-platform quality CI job runs ruff
lint, ruff format --check, strict mypy and jscpd (threshold 0, see
.jscpd.json), and the issues these tools found are fixed: zip() now uses
strict=True, rich narrowing in pretty.py is type-safe, test helpers are
fully annotated, and make_context takes a typed Options value.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

Files

 .github/workflows/ci.yml               | 29 ++++++++++++++++++++++++
 .jscpd.json                            |  6 +++++
 project_validator/ci/github_actions.py |  4 ++--
 project_validator/ci/gitlab.py         |  2 +-
 project_validator/core.py              |  4 +---
 project_validator/pretty.py            | 17 ++++++++-------
 project_validator/runner.py            |  2 +-
 pyproject.toml                         |  7 ++++++
 tests/support.py                       |  4 ++--
 tests/test_checks.py                   | 22 ++++++++++---------
 tests/test_ci.py                       |  4 ++--
 tests/test_github_actions.py           |  4 ++--
 tests/test_platforms.py                |  4 +---
 tests/test_plugins.py                  | 31 +++++++++++++++++---------
 tests/test_quality.py                  | 40 ++++++++++++++++++++++++++++++++++
 tests/test_runner.py                   | 12 ++++++----
 16 files changed, 144 insertions(+), 48 deletions(-)

Closes #34

Triggered by @lefticus.

…detection

The project had no static quality gate, so lint, formatting and typing
drift went unnoticed. A new single-platform `quality` CI job runs ruff
lint, ruff format --check, strict mypy and jscpd (threshold 0, see
.jscpd.json), and the issues these tools found are fixed: zip() now uses
strict=True, rich narrowing in pretty.py is type-safe, test helpers are
fully annotated, and make_context takes a typed Options value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 46.15385% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.75%. Comparing base (f62b232) to head (7f62bce).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
project_validator/pretty.py 22.22% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #43      +/-   ##
==========================================
- Coverage   96.85%   96.75%   -0.10%     
==========================================
  Files          29       29              
  Lines        1017     1018       +1     
  Branches       80       80              
==========================================
  Hits          985      985              
- Misses         27       28       +1     
  Partials        5        5              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lefticus

lefticus commented Nov 2, 2026

Copy link
Copy Markdown
Member

@leftibot resolve merge conflicts

@leftibot

leftibot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished addressing the review feedback.

Requested by @lefticus in PR cpp-best-practices#43 review.

Resolved conflicts in core.py, tests/support.py, test_checks.py,
test_plugins.py and test_runner.py, keeping main's new behaviour
(project exclusions, layout-parametrised tests, new checks).

make_context, run_in_every_layout and run_as keep this PR's typed
`options: Options | None` parameter instead of main's `**options: object`,
which strict mypy rejects. Code merged from main is also brought up to
the new quality gate: ruff formatting, a ClassVar annotation (RUF012),
Mapping parameters, return annotations and typed JSON access in tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@leftibot

leftibot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review feedback from @lefticus. New commits:

5db41ee Address review: merge main and resolve conflicts
9ce6975 Fix #40: add copy-paste detection detection (#44)
fc47c78 Fix #35: can this project be made more generic? (#46)
afdb7e1 Add LICENSE file for public domain software
0083499 Fix #26: Add `ci-build-types` check: CI builds both Debug and Release (#33)

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot fix merge conflicts and make sure this PR matches current standards for how tests should be organized to reduce merge conflicts

@leftibot

leftibot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished addressing the review feedback.

…files

Merged upstream main, which split tests/test_checks.py into
tests/checks/test_<check>.py (cpp-best-practices#48). The conflicting test_checks.py edits
are now applied to the per-check files instead: _run helpers return
Result, make_context/run_as take a typed Options value instead of
**options, matrix parameters take a covariant Mapping, and an
over-long line is wrapped. ruff, ruff format, strict mypy and jscpd
(threshold 0) all pass on the merged tree.

Requested by @lefticus in PR cpp-best-practices#43 review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@leftibot

leftibot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review feedback from @lefticus. New commits:

7f62bce Address review: merge main and move typing fixes into per-check test files
f62b232 Bump codecov/codecov-action from 5 to 7 (#52)
a0bf37c Fix #15: Add `clang-format` check: formatting is defined and enforced (#39)
589a133 Fix #48: split check tests into one file per check so check PRs stop conflicting (#49)
97a3a90 Fix #29: Add dependency-updates check for Dependabot or Renovate (#47)

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot can you explain the decline in coverage that coveralls is reporting?

@leftibot

leftibot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished looking into this — see reply below.

@leftibot

leftibot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

The drop doesn't mean test coverage got worse. (The report on this PR is from Codecov, not Coveralls; the numbers below are from its comment.) The cause is a gap that already existed in the coverage CI job, and this PR adds one more line to it.

Where the −0.10% comes from

Lines    1017 → 1018   (+1)
Hits      985 →  985
Misses     27 →   28   (+1)

The whole change is one new line in project_validator/pretty.py:

text = _rich.text

To make mypy's strict mode happy, the PR passes the narrowed rich.text module into _report_line and _summary. That line is never executed in the coverage run, so the run gains one line and one miss. The other 6 "missing" patch lines in Codecov's report were already counted as misses before this PR. The PR only edits them, so they show up in the patch.

Why pretty.py is uncovered

rich is optional (pretty = ["rich>=13.0"] in pyproject.toml), and the coverage job in .github/workflows/ci.yml installs only coverage and PyYAML. So pretty._rich is None, every test marked @requires_rich is skipped, and none of the rendering code in print_reports, _report_line or _summary runs. Any PR that touches those functions will report low patch coverage.

I checked this locally on the PR head:

Coverage run Skipped tests pretty.py Total misses
without rich (same as CI) 7 52% (17 missed) 28
with rich installed 0 96% (only the ImportError fallback) 11

Suggested fix

Install rich in the coverage job:

      - name: Install tools
        run: python -m pip install "coverage>=7.10" "PyYAML>=6.0" "rich>=13.0"

This would remove the 7 skips and take overall coverage from about 97% to about 99%. The ImportError fallback (lines 22–23) would then be the only uncovered part, and the tests already exercise that path by patching pretty._rich to None. I'd recommend a separate small PR, since it changes how coverage is measured rather than anything this PR is about. I can also add it here if you'd like.

Also worth noting

The PR branch is now behind main. The Dependabot bumps (#50, #51, #53) moved the workflows to actions/checkout@v7, actions/setup-python@v7 and actions/setup-node@v7. The new quality job still uses @v4/@v5, so it should be updated on the next merge to match.

@lefticus
lefticus merged commit 2b3ab9f into cpp-best-practices:main Nov 3, 2026
11 of 13 checks passed
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.

add CI static code quality tests for this project

2 participants