feat(cadfs): expand selector provenance coverage
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"""Source-derived FeatureScript operation coverage inventory.
|
||||
|
||||
The registry records what the current source corpus actually contains. It is
|
||||
deliberately independent from conversion diagnostics: an old output directory
|
||||
cannot make an operation appear supported, and a planned operation cannot be
|
||||
reported as observed merely because its name is listed in the roadmap.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import Counter, defaultdict
|
||||
from pathlib import Path
|
||||
from typing import Any, Iterable
|
||||
|
||||
from .dataset import Sample
|
||||
from .featurescript_parser import parse_featurescript
|
||||
|
||||
|
||||
REGISTRY_SCHEMA = "cadfs_to_cdsl.operation_registry.v1"
|
||||
|
||||
# These are roadmap work items, not parser aliases or support declarations.
|
||||
P3_OPERATION_WORK_ITEMS = (
|
||||
"draft",
|
||||
"thicken",
|
||||
"split",
|
||||
"moveFace",
|
||||
"deleteFace",
|
||||
"replaceFace",
|
||||
"transform",
|
||||
"derive",
|
||||
"import",
|
||||
"bend_add",
|
||||
)
|
||||
|
||||
|
||||
def build_operation_registry(samples: Iterable[Sample]) -> dict[str, Any]:
|
||||
"""Parse every available FeatureScript source and inventory feature calls.
|
||||
|
||||
Parse failures and missing FeatureScript modalities are recorded separately
|
||||
instead of being treated as a zero-count result. Sample examples remain
|
||||
bounded only for report size; the count is computed from every feature.
|
||||
"""
|
||||
counts: Counter[str] = Counter()
|
||||
sample_ids: dict[str, set[str]] = defaultdict(set)
|
||||
parse_failures: list[dict[str, str]] = []
|
||||
source_sample_count = 0
|
||||
|
||||
for sample in samples:
|
||||
source_path = sample.files.get("featurescript")
|
||||
if not source_path:
|
||||
continue
|
||||
source_sample_count += 1
|
||||
try:
|
||||
model = parse_featurescript(Path(source_path).read_text(encoding="utf-8"), sample.sample_id)
|
||||
except Exception as error:
|
||||
parse_failures.append({"sample_id": sample.sample_id, "error": f"{type(error).__name__}: {error}"})
|
||||
continue
|
||||
for feature in model.features:
|
||||
counts[feature.operation] += 1
|
||||
sample_ids[feature.operation].add(sample.sample_id)
|
||||
|
||||
operations: dict[str, dict[str, Any]] = {}
|
||||
for operation in sorted(counts):
|
||||
operations[operation] = {
|
||||
"state": "observed",
|
||||
"feature_count": counts[operation],
|
||||
"sample_count": len(sample_ids[operation]),
|
||||
"sample_ids": sorted(sample_ids[operation]),
|
||||
}
|
||||
for operation in P3_OPERATION_WORK_ITEMS:
|
||||
if operation in operations:
|
||||
operations[operation]["roadmap_work_item"] = True
|
||||
else:
|
||||
operations[operation] = {
|
||||
"state": "not_observed_in_current_source",
|
||||
"feature_count": 0,
|
||||
"sample_count": 0,
|
||||
"sample_ids": [],
|
||||
"roadmap_work_item": True,
|
||||
}
|
||||
|
||||
return {
|
||||
"schema": REGISTRY_SCHEMA,
|
||||
"source_sample_count": source_sample_count,
|
||||
"parse_failure_count": len(parse_failures),
|
||||
"parse_failures": parse_failures,
|
||||
"operations": operations,
|
||||
}
|
||||
Reference in New Issue
Block a user