Skip to content

Fix #41: Add function-limits detection - #45

Merged
lefticus merged 9 commits into
cpp-best-practices:mainfrom
leftibot:fix/issue-41-add-function-limits-detection
Nov 4, 2026
Merged

lefticus merged 9 commits into
cpp-best-practices:mainfrom
leftibot:fix/issue-41-add-function-limits-detection

Conversation

@leftibot

Copy link
Copy Markdown
Contributor

Automated fix by @leftibot.

What changed

Fix #41: Add function-limits check that function length is limited
Nothing verified that a project keeps its functions short. The new
function-limits check passes when CI or CMake runs lizard with an explicit
length limit (-L, --length, -T length/nloc), or when .clang-tidy enables
readability-function-size with a positive LineThreshold or StatementThreshold
and clang-tidy is run; it warns if the limit is configured but clang-tidy never
runs, and fails otherwise, explaining a disabled check or missing threshold.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

Files

 project_validator/checks/function_limits.py        | 105 +++++++++++++++++++++
 tests/fixtures/well_configured/.clang-tidy         |   4 +
 .../well_configured/.github/workflows/ci.yml       |   1 +
 tests/test_checks.py                               |  83 ++++++++++++++++
 tests/test_cli.py                                  |   5 +-
 tests/test_plugins.py                              |   1 +
 6 files changed, 197 insertions(+), 2 deletions(-)

Closes #41

Triggered by @lefticus.

…ngth is limited

Nothing verified that a project keeps its functions short. The new
`function-limits` check passes when CI or CMake runs lizard with an explicit
length limit (-L, --length, -T length/nloc), or when .clang-tidy enables
readability-function-size with a positive LineThreshold or StatementThreshold
and clang-tidy is run; it warns if the limit is configured but clang-tidy never
runs, and fails otherwise, explaining a disabled check or missing threshold.

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

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.25%. Comparing base (ed3da4e) to head (023450f).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #45      +/-   ##
==========================================
+ Coverage   97.07%   97.25%   +0.18%     
==========================================
  Files          31       32       +1     
  Lines        1127     1202      +75     
  Branches       92       99       +7     
==========================================
+ Hits         1094     1169      +75     
  Misses         28       28              
  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#45 review.

Kept both sides of the conflicting tests. Since main now scopes checks
to languages, function-limits (clang-tidy readability-function-size or
lizard) is declared for C/C++ only, matching cxx-extensions; the CLI,
structure and color-output tests are updated for the extra check.

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:

5db8b23 Address review: merge origin/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

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot fix merge conflicts and get the tests up to current standards

@leftibot

leftibot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished addressing the review feedback.

leftibot and others added 2 commits November 2, 2026 22:48
Merges cpp-best-practices/project_validator main, which split check tests into
one file per check (cpp-best-practices#49) and derives check lists from discover(). test_cli.py,
test_plugins.py and test_structure.py take main's generic versions, so they no
longer hard-code function-limits; the well_configured CI fixture keeps both the
clang-tidy step and main's clang-format job. The FunctionLimitsTests removed
along with tests/test_checks.py move to tests/checks/test_function_limits.py in
the next commit.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the tests into tests/checks/test_function_limits.py, as main now requires
one test file per check. They run in every C/C++ project layout via
run_in_every_layout, assert the check's declared languages, try lizard limits in
every CI provider, and compare whole Results so messages and details are pinned.

Requested by @lefticus in PR cpp-best-practices#45 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:

4452316 Address review: bring function-limits tests up to current standards
c7251a8 Address review: merge upstream main and resolve conflicts
7ee859e Bump actions/setup-node from 4 to 7 (#51)
193835f Bump actions/setup-python from 5 to 7 (#50)
a35f4f4 Bump actions/checkout from 4 to 7 (#53)

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot function limits can apply to python as well. Look for applicable tools to check for an apply in this code base. Lizard?

@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

Yes, lizard is the right tool to use for every language. It works on C/C++, Python and Rust (plus about 20 other languages), and the -L/-T length= detection in this PR already handles all of them. The problem is that the check is limited to languages=C_FAMILY (project_validator/checks/function_limits.py). Running it on this repo shows that:

[SKIP] function-limits: not applicable to Python (applies to C, C++)

Tools worth detecting, by ecosystem

Ecosystem Tool What counts as "limited"
any lizard lizard … -L N / -T length=N / -T nloc=N (already detected)
C/C++ clang-tidy readability-function-size with LineThreshold/StatementThreshold (already detected)
Python ruff PLR0915 (too-many-statements) is selected, through PLR0915, PLR, PL or ALL in [tool.ruff.lint] select/extend-select (pyproject.toml or ruff.toml), and CI runs ruff check. max-statements defaults to 50. Ruff doesn't select it by default.
Python pylint R0915 too-many-statements is on by default (max 50), so pylint running in CI is enough unless R0915/too-many-statements is disabled in .pylintrc/[tool.pylint]
Python flake8-functions CFQ001 (max function length) when flake8 runs in CI
Rust clippy clippy::too_many_lines is in pedantic, so it's off by default. It counts when -W clippy::too_many_lines/-W clippy::pedantic is passed or it's enabled in [lints.clippy], with an optional too-many-lines-threshold in clippy.toml

Ruff and pylint count statements, not lines. That's the same thing clang-tidy's StatementThreshold measures, which this check already accepts. I'd ignore complexity-only tools (mccabe/C901, radon, xenon) because they don't measure length.

Suggested shape

Restructure the check like code_formatting.py: put the rules for each ecosystem in a Mapping[Ecosystem, …] and use check_each_ecosystem.

  • C/C++: lizard or clang-tidy (current logic).
  • Python: lizard, ruff PLR0915 plus ruff check in CI, or pylint in CI without R0915 disabled.
  • Rust: lizard or clippy too_many_lines. This could be left for a follow-up.

The lizard match should stay valid for every ecosystem. One small catch: if the command has -l <lang> (for example lizard -l python), it shouldn't count for the other ecosystems.

Applying it to this repo

Here's where the repo stands today, measured with lizard 1.25 and ruff on project_validator and tests:

  • Source (172 functions): the longest is cli.py:main at 32 lines (30 NLOC). Only 3 functions are over 20 NLOC: cli.main, cli._parser and ci/github_actions.expand_matrix.
  • Tests (324 functions): the longest is 22 lines.
  • Statement counts: ruff check --select PLR0915 finds nothing at the default of 50.
  • Complexity: lizard's default complexity limit of 15 flags expand_matrix (complexity 20), so a bare lizard run in CI will report it.
  • Parameter count: ruff's PLR0913 flags ci/__init__.py:_job_with_compilers, which has 6 parameters against a limit of 5.

My proposal is a CI job next to the copy-paste-detection one:

  function-limits:
    name: function limits
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v7
        with:
          python-version: "3.14"
      - name: Install lizard
        run: python -m pip install "lizard>=1.17"
      - name: Limit function length and complexity
        run: lizard --languages python --length 25 --CCN 15 --arguments 5 --warnings_only project_validator tests

These thresholds mean refactoring cli.main, cli._parser, expand_matrix and _job_with_compilers first. I think that's the right call, since all four are already the outliers. The other option is to start at --length 35 --CCN 20 --arguments 6 so CI passes today, then tighten the limits later.

Lizard was my choice over ruff PLR0915 for this repo because it gives a real line limit, and one tool covers length, complexity and parameter count. ruff check is still worth adding for linting in general.

Do you want me to do both in this PR (the ecosystem-aware check and the CI job, with the refactors)? Or should I keep this PR to the check and send the repo changes separately?

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot implement the function limit length with 30loc as the default setting, using lizard for this project and make sure that the validation test allows for lizard as a viable testing scenario

@leftibot

leftibot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished addressing the review feedback.

leftibot and others added 2 commits November 2, 2026 23:06
function-limits now judges each ecosystem the project uses: a lizard
length limit in CI counts for C/C++, Python and Rust, and clang-tidy's
readability-function-size still counts for C/C++. Failures suggest
lizard --length 30 as the default limit. The well-configured Python and
Rust fixtures now run lizard so they keep passing every check.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI gains a function-limits job running lizard --length 30 over
project_validator and tests, so self-validation now judges (and passes)
function-limits for this Python project. cli.main (32 lines) and
expand_matrix (complexity 20, over lizard's default of 15) are split up
so the job passes.

This deliberately edits CI config: @lefticus asked for lizard to be
used for this project.

Requested by @lefticus in PR cpp-best-practices#45 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:

805ebbd Address review: limit this project's functions to 30 lines with lizard
d486ced Address review: judge function limits for Python and Rust with lizard

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot fix issues discovered during code quality analysis

@leftibot

leftibot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished addressing the review feedback.

leftibot and others added 2 commits November 2, 2026 23:27
Requested by @lefticus in PR cpp-best-practices#45 review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ruff RUF012 failed the quality job because RUNS_CLANG_TIDY was a mutable dict
class attribute; it is now a read-only Mapping like the constants in
tests/support.py.

Requested by @lefticus in PR cpp-best-practices#45 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:

fddebec Address review: make the function-limits clang-tidy CI fixture immutable
ad5521b Address review: merge origin/main to pick up the quality checks
2b3ab9f Fix #34: Add CI static code quality and copy-paste detection (#43)

@lefticus

lefticus commented Nov 3, 2026

Copy link
Copy Markdown
Member

@leftibot deal with the merge conflicts and the fact that we don't have pyc files committed now

@leftibot

leftibot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ leftibot finished addressing the review feedback.

Merges cpp-best-practices/main (warnings-as-errors and vcs-ignore checks,
plus the new .gitignore). The only conflicts were modify/delete conflicts on
committed __pycache__/*.pyc files, which main no longer tracks; they are
removed from this branch too, so no bytecode remains in the tree.

Requested by @lefticus in PR cpp-best-practices#45 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:

023450f Address review: merge upstream main and drop committed bytecode
ed3da4e Fix #54: add validation check for .gitignore (#55)
25f278b Fix #12: Add warnings-as-errors check (#37)

@lefticus
lefticus merged commit b7c4318 into cpp-best-practices:main Nov 4, 2026
14 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 function-limits detection

2 participants