Skip to content

refactor(core): drive metrics from a Metric registry - #40

Merged
ElbertePlinio merged 4 commits into
mainfrom
refactor/metric-registry
Sep 30, 2026
Merged

ElbertePlinio merged 4 commits into
mainfrom
refactor/metric-registry

Conversation

@ElbertePlinio

@ElbertePlinio ElbertePlinio commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Closes #39

The seven metric names were listed by hand in config key validation, limits_for, effective_limits, add_violations, and MetricValues, so a missed entry compiled fine and silently dropped the metric. A Metric enum in crates/core/src/metric.rs now holds the list, the names, and applicability: lines and params skip Svelte template units, and widget_depth covers only Dart build methods. Every accessor matches on Metric without a wildcard, so a new variant fails to compile until each path handles it. ALL is the one list a match cannot check, so a test ties it to the serialized keys of Limits, MetricValues, and FunctionMetrics.

The struct fields and serde attributes are unchanged, so JSON output, config shape, error messages, and exit codes are the same. pickcheck-core gains Metric and get/value accessors as additive public items. The crate is not published and only the CLI in this workspace uses it.

The issue originally said to wait for a second language-specific metric. The maintainer overrode that on 2026-09-30.

Requirement Verified by Scenario Result Evidence
One definition drives config key validation automated test every Metric accepted as a key in limits and languages.rust.limits; unknown limits.bogus and languages.go.limits.widgetdepth still rejected pass every_metric_round_trips_through_config_limits_and_values; QA badkey, badlangkey
One definition drives per-language applicability automated test ordinary, template, and Dart build units against every metric pass applicability_follows_template_and_widget_units
One definition drives violation emission and baseline lookup manual check main vs branch release binaries on every golden fixture, default and custom limits, --base with new/worsened/unchanged statuses, --changed identical bytes, 14 of 14 scenarios QA below
A missed wiring fails instead of dropping silently automated test + manual check removing WidgetDepth from ALL fails all_covers_every_metric_field and names_match_the_default_config_limits pass QA below
Violation emission uses the same applicability as --base limits automated test excluded template unit with over-limit lines, params, widget_depth emits nothing; ordinary unit emits lines and params; test file with default exempt: ["lines"] emits only params. Reverting either path fails the test pass violations_skip_metrics_that_do_not_apply_to_the_unit
Golden fixtures cannot skip a new metric automated (compile-time) Expected::from destructures FunctionMetrics without .. pass crates/core/tests/golden.rs
JSON output, config shape, exit codes unchanged; golden fixtures unmodified automated test + manual check full test suite; no fixture edits in the diff; byte comparison above pass cargo test, QA below
Tests, clippy, fmt, coverage floor, PickCheck automated cargo test --workspace --locked --all-targets, cargo clippy ... -D warnings, cargo fmt --check, cargo llvm-cov --fail-under-lines 94 (94.60%), pickcheck check --base origin/main --fail-on new,worsened,unmatched (35 checked, 0 violations), all on 20bf65f pass CI on this PR

QA: a CLI pass compared pickcheck 0.4.0 built from main at 99a0826 with this branch, over a scratch Git repo holding a copy of tests/fixtures. Scenarios were plain and JSON checks, a .pickcheck.json with global and per-language overrides including null and tests.exempt, three invalid configs, --base text and JSON with default and custom limits (30 new, 8 worsened, 1 unchanged), and --changed. All outputs, stderr, and exit codes matched byte for byte. The comparison was rerun on e14f76d after the review fix, adding a config with params and widget_depth limits of 0, and again matched in 14 of 14 scenarios. 20bf65f changes only a test. The evidence stays local and outside the repo.

Review: independent xhigh reviews by Astra (Lanes) and Fable at 27b6a95 found no regression for the seven current metrics. Both flagged that add_violations bypassed Metric::applies_to and that the golden projection could skip a new metric. Fable also noted that baseline::status re-parsed the metric name. e14f76d fixes all three. Fable's recheck added a nit about direct coverage of the test-file exemption, fixed in 20bf65f. Both reviewers confirmed every finding resolved.

Follow-up found during QA: #41, a pre-existing misleading error path for per-language config keys.

The seven metric names were listed by hand in config validation, limit
resolution, violation emission, and baseline lookup, so a missed entry
compiled fine and silently dropped the metric. A Metric enum now holds the
list, names, and applicability, and exhaustive accessors make a new variant
fail to compile until every path handles it. Output and config are unchanged.
ALL is the one list an exhaustive match cannot check. The test compares it with the serialized keys of Limits, MetricValues, and FunctionMetrics, so a metric field added without an ALL entry fails instead of being skipped.
add_violations read raw language limits and applied only the test-file exemption, so a restricted metric with a nonzero value on an excluded unit would fail while --base reported its limit as null. It now uses effective_limits, the same path as --base. baseline::status takes a Metric, and the golden projection destructures FunctionMetrics so a new metric field cannot go unchecked.
@ElbertePlinio
ElbertePlinio merged commit 4de9c09 into main Sep 30, 2026
8 checks passed
@ElbertePlinio
ElbertePlinio deleted the refactor/metric-registry branch September 30, 2026 17:44
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.

Extract a metric registry when a second language-specific metric lands

1 participant