The first public versions of rustquty shipped with a nice idea: local-first quality gates for Rust projects.
Run one command. Collect metrics. Compare against a baseline or absolute thresholds. Fail if quality regressed.
That model still feels right to me.
But this week I hit the part every tool author eventually hits: the moment where the tool says something so obviously wrong that you stop trusting the entire report.
For rustquty, that happened in two collectors: duplicates and loc.
Version 0.4.3 is a correction release. Not a flashy feature release. A trust repair release.
The Bad Duplicate Detector
The old duplicate collector was too naive.
It walked every .rs file, trimmed every line, skipped blank lines and obvious comments, then counted repeated lines across the entire codebase.
If a line appeared more than once, every occurrence counted as duplication.
That sounds almost reasonable until you remember what Rust code looks like:
| |
Those lines repeat constantly in any real project. A closing brace appearing in two different functions is not duplicated code. It is syntax.
The result was mathematically correct for the algorithm and completely wrong for the product.
I saw reports claiming massive duplicate percentages, not because the codebase had copied 20-line functions everywhere, but because common tokens were repeated thousands of times.
That is worse than useless. It trains you to ignore the gate.
What Changed in 0.4.3
The duplicate collector now works at the token-block level.
Instead of asking “did this single line appear somewhere else?”, rustquty now tokenizes Rust source and searches for repeated windows of tokens. The defaults are intentionally conservative:
- at least 100 tokens
- at least 6 source lines
- exact normalized token matches
- comments and whitespace do not matter
- overlapping windows are merged into duplicate blocks
This means repeated braces, attributes, and punctuation do not trigger duplication anymore.
What triggers it now is actual repeated structure: the kind of copy-paste where a function body, parser branch, mapping block, or setup routine exists twice with the same token stream.
The output also became more useful. metricsSummary.json now includes capped structured duplicate block details:
| |
That is the difference between “you have duplicates, good luck” and “here is the duplicated block, go look at it.”
The LOC Collector Was Also Lying by Omission
The line-of-code collector had a different problem.
Internally, it used a max line length of 120. That part was fine.
But after collection, the aggregation layer forgot to copy several fields into the final metricsSummary.json:
maxLineLengthAllowedfilesWithLongLineslongLineFiles- long-line detail entries
So the raw collector knew the threshold and the files, but the final JSON could show things like:
| |
while still reporting thousands of long lines.
That is exactly the kind of inconsistency that makes a quality gate feel haunted.
There was another subtle mismatch: gate messages could mention the baseline max observed line length instead of the actual threshold used by the collector.
So a message could imply “these lines exceed 284” when the collector actually checked against 120.
Again: not acceptable for a tool whose whole job is to create confidence.
LOC Is Now Configured Where It Matters
In 0.4.3, line length is configured at collection time.
If you put this in rustquty.toml:
| |
the LOC collector uses that value while scanning. The JSON stores it as maxLineLengthAllowed. The gate message reports that same threshold. --verbose uses the same number.
No split-brain between “what was checked” and “what was reported.”
The verbose output now has file:line details too:
| |
The details are capped so huge repositories do not explode the report, but the failure is now explainable.
A Small File-Scanning Fix
While fixing this, I also made the built-in Rust source collectors skip directories that should not be scanned:
target/.git/quality/
This matters more than it looks. After a build, target/ can contain generated .rs files from dependencies. A local quality scanner should scan your project, not generated build output.
Why This Release Matters
The main lesson is simple:
A quality gate is only as useful as the trust you have in its metrics.
False positives are not harmless. They create a habit:
- The tool fails.
- The failure looks wrong.
- You ignore it.
- The next real failure gets ignored too.
That is how a quality tool becomes terminal noise.
I would rather have a smaller, stricter detector that catches fewer things but reports real problems than a noisy detector that reports everything and teaches people to stop reading.
Release Notes
rustquty 0.4.3 and rustquty-core 0.4.3 are published on crates.io.
Install or update:
| |
Main changes:
- replaced repeated-line duplicate detection with token-based duplicate block detection
- preserved LOC aggregation fields in
metricsSummary.json - made
maxLineLengthAllowedreport correctly - made line-length checking use the configured threshold during collection
- fixed LOC gate messages to report the actual collector threshold
- added capped duplicate and long-line details for
--verbose - skipped
target/,.git/, andquality/during built-in Rust source scanning
What Comes Next
The next thing I want from rustquty is not more collectors for the sake of more collectors.
I want better explanations.
When a gate fails, I want the report to answer:
- what failed?
- where?
- compared to what threshold?
- why does this matter?
- what should I inspect first?
The 0.4.3 release moves in that direction. It makes the two noisiest collectors less magical and more inspectable.
That is the kind of boring improvement that makes a tool survive daily use.
Repository: github.com/enrell/rustquty
| |
If it fails now, it should fail for a reason you can actually see.
See you in the Wired.