Skip to content

v2.2.0

Choose a tag to compare

@github-actions github-actions released this 08 Aug 11:42
· 17 commits to main since this release

Lean 4 support

codopsy now analyses Lean 4 (.lean) — 35 languages, 182 lint rules.

  • Cyclomatic and cognitive complexity for def / theorem / abbrev / example / instance, scored against Lean's own control flow: if then else, match arms, induction, by_cases, and the ∧ / ∨ connectives. else if chains stay flat instead of nesting.
  • 8 lint rules aimed at the two things that make a Lean file untrustworthy rather than merely ugly — proofs that are not finished, and declarations that widen what the kernel takes on faith:
Rule Default
no-sorry error
no-axiom warning
no-native-decide warning
no-unsafe warning
no-unlimited-heartbeats warning
no-partial-def info
no-dbg-trace info
no-debug-command info

Lean is macro-extensible, so no tree-sitter grammar reads every file. Measured over lean4 and Mathlib core sources, the grammar codopsy uses leaves ~6% of bytes unparsed; hand-written Lean parses essentially in full. What it cannot read is now reported rather than silently skipped — see the next section.

New rule: syntax-error (all languages, info)

A file the parser could not read produced no functions, no issues, and therefore a perfect score. It now reports how many regions were unreadable and what share of the file they cover, so an unparsed file can no longer pass as a clean one. One issue per file; disable it with "syntax-error": false like any other rule.

Complexity fix: keyword tokens were counted twice

Several tree-sitter grammars name a keyword token exactly like the node it opens — Ruby's if token inside an if node, JavaScript's function inside a function_declaration. Both matched the classification tables, so every such branch was counted twice and phantom (anonymous) functions appeared in reports. Only named nodes are classified now.

This changes reported numbers for Ruby, Crystal, JavaScript and Lua: complexity and function counts go down. A baseline recorded with 2.0.x will register the difference as an improvement.

Other fixes

  • --hotspots silently produced nothing unless the analysed directory was the repository root. Churn keys from git log are repo-root-relative; the comparison was built relative to the analysed directory, so the two never matched in a subdirectory.
  • --help still described codopsy as being "for TypeScript, JavaScript & Rust".
  • --max-complexity / --max-cognitive-complexity CLI defaults were hardcoded instead of reading the centralised defaults, so they could drift from the documented values.
  • score_complexity now honours the configured max-complexity / max-cognitive-complexity thresholds instead of the built-in ones (this landed after v2.0.1 and was never released).

Internal

The language registry is a single table per language, replacing three lists that had to stay in lockstep: a name array indexed by enum declaration order, a grammar match, and an extension map. Adding a language is now one row, and a new test asserts that all 35 grammars actually load and that every extension round-trips.

codopsy's own analysis of src is A (100/100), 0 issues.

Full Changelog: v2.0.1...v2.2.0