feat: prepare Radixor 3.0.0 with contracted tries and compiled patch commands
Introduce contracted compiled patch tries for faster lookup, make compiled patch commands the primary runtime path, refresh stemmer benchmarks and documentation, and restructure the documentation for 3.0.0 onboarding. BREAKING CHANGE: Radixor 3.0.0 promotes compiled patch-command APIs and new compiled trie artifacts as the primary runtime integration model.
This commit is contained in:
@@ -6,7 +6,6 @@ This script derives compact machine-readable badge payloads from:
|
||||
|
||||
- JaCoCo XML coverage report
|
||||
- PIT mutation testing XML report
|
||||
- JMH CSV benchmark report
|
||||
|
||||
The generated JSON files are intended to be consumed by Shields endpoint badges.
|
||||
"""
|
||||
@@ -14,7 +13,6 @@ The generated JSON files are intended to be consumed by Shields endpoint badges.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
@@ -38,8 +36,8 @@ def parse_args() -> argparse.Namespace:
|
||||
)
|
||||
parser.add_argument(
|
||||
"--jmh-csv",
|
||||
required=True,
|
||||
help="Path to the JMH CSV report."
|
||||
required=False,
|
||||
help="Deprecated compatibility option. JMH speed badges are no longer generated."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--run-metrics-dir",
|
||||
@@ -60,6 +58,12 @@ def write_json(target: Path, payload: dict[str, object]) -> None:
|
||||
target.write_text(json.dumps(payload, indent=2) + os.linesep, encoding="utf-8")
|
||||
|
||||
|
||||
def remove_file_if_present(target: Path) -> None:
|
||||
"""Remove a previously generated file when it is present."""
|
||||
if target.is_file():
|
||||
target.unlink()
|
||||
|
||||
|
||||
def unavailable_payload(label: str) -> dict[str, object]:
|
||||
"""Create a standard payload for unavailable metrics."""
|
||||
return {
|
||||
@@ -83,19 +87,6 @@ def color_for_percentage(value: float) -> str:
|
||||
return "red"
|
||||
|
||||
|
||||
def color_for_speedup(value: float) -> str:
|
||||
"""Select a badge color for a speedup factor."""
|
||||
if value >= 4.0:
|
||||
return "brightgreen"
|
||||
if value >= 3.0:
|
||||
return "green"
|
||||
if value >= 2.0:
|
||||
return "yellow"
|
||||
if value >= 1.0:
|
||||
return "orange"
|
||||
return "red"
|
||||
|
||||
|
||||
def coverage_payload(jacoco_xml: Path) -> dict[str, object]:
|
||||
"""Build a line coverage badge payload from a JaCoCo XML report."""
|
||||
if not jacoco_xml.is_file():
|
||||
@@ -158,94 +149,27 @@ def mutation_payload(pit_xml: Path) -> dict[str, object]:
|
||||
}
|
||||
|
||||
|
||||
def parse_family_count(row: dict[str, str]) -> int:
|
||||
"""Extract the JMH familyCount parameter from a CSV row."""
|
||||
for key, value in row.items():
|
||||
if key.startswith("Param: ") and key.endswith("familyCount"):
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError):
|
||||
return -1
|
||||
return -1
|
||||
|
||||
|
||||
def benchmark_payload(jmh_csv: Path) -> dict[str, object]:
|
||||
"""Build a benchmark speedup badge payload from a JMH CSV report."""
|
||||
if not jmh_csv.is_file():
|
||||
return unavailable_payload("english benchmark")
|
||||
|
||||
with jmh_csv.open("r", encoding="utf-8", newline="") as input_file:
|
||||
rows = list(csv.DictReader(input_file))
|
||||
|
||||
if not rows:
|
||||
return unavailable_payload("english benchmark")
|
||||
|
||||
relevant_rows: list[tuple[int, str, float]] = []
|
||||
for row in rows:
|
||||
benchmark = row.get("Benchmark", "")
|
||||
if not benchmark.endswith(
|
||||
"EnglishStemmerComparisonBenchmark.radixorUsUkProfiPreferredStem"
|
||||
) and not benchmark.endswith(
|
||||
"EnglishStemmerComparisonBenchmark.snowballOriginalPorter"
|
||||
):
|
||||
continue
|
||||
|
||||
try:
|
||||
score = float(row["Score"])
|
||||
except (KeyError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
relevant_rows.append((parse_family_count(row), benchmark, score))
|
||||
|
||||
if not relevant_rows:
|
||||
return unavailable_payload("english benchmark")
|
||||
|
||||
best_family_count = max(family_count for family_count, _, _ in relevant_rows)
|
||||
radixor_score = None
|
||||
porter_score = None
|
||||
|
||||
for family_count, benchmark, score in relevant_rows:
|
||||
if family_count != best_family_count:
|
||||
continue
|
||||
if benchmark.endswith(".radixorUsUkProfiPreferredStem"):
|
||||
radixor_score = score
|
||||
elif benchmark.endswith(".snowballOriginalPorter"):
|
||||
porter_score = score
|
||||
|
||||
if radixor_score is None or porter_score is None or porter_score <= 0.0:
|
||||
return unavailable_payload("english benchmark")
|
||||
|
||||
# score is time for the batch processing, i.e. longer => slower, i.e. speedup is porter/radixor
|
||||
speedup = porter_score / radixor_score
|
||||
family_suffix = "" if best_family_count < 0 else f" ({best_family_count})"
|
||||
return {
|
||||
"schemaVersion": 1,
|
||||
"label": "english benchmark",
|
||||
"message": f"{speedup:.1f}x vs Porter{family_suffix}",
|
||||
"color": color_for_speedup(speedup)
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Generate all requested badge metadata files."""
|
||||
arguments = parse_args()
|
||||
|
||||
jacoco_xml = Path(arguments.jacoco_xml)
|
||||
pit_xml = Path(arguments.pit_xml)
|
||||
jmh_csv = Path(arguments.jmh_csv)
|
||||
run_metrics_dir = Path(arguments.run_metrics_dir)
|
||||
latest_metrics_dir = Path(arguments.latest_metrics_dir)
|
||||
|
||||
payloads = {
|
||||
"coverage-badge.json": coverage_payload(jacoco_xml),
|
||||
"pitest-badge.json": mutation_payload(pit_xml),
|
||||
"jmh-badge.json": benchmark_payload(jmh_csv)
|
||||
"pitest-badge.json": mutation_payload(pit_xml)
|
||||
}
|
||||
|
||||
for file_name, payload in payloads.items():
|
||||
write_json(run_metrics_dir / file_name, payload)
|
||||
write_json(latest_metrics_dir / file_name, payload)
|
||||
|
||||
remove_file_if_present(run_metrics_dir / "jmh-badge.json")
|
||||
remove_file_if_present(latest_metrics_dir / "jmh-badge.json")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user