mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 10:03:49 -06:00
fix: report profiles the forge failed to serve
This commit is contained in:
1 parent
a7af0445e3
commit
6b7d93fc9e
2 files changed
+56
-9
No files matched your search
+28
-9
@@ -3427,6 +3427,9 @@ def main() -> None:
|
|||||||
if writes and not args.dry_run and not args.force:
|
if writes and not args.dry_run and not args.force:
|
||||||
_refuse_dirty_tree(args.emulators_dir)
|
_refuse_dirty_tree(args.emulators_dir)
|
||||||
|
|
||||||
|
# A profile that could not be compared or written is not a profile with
|
||||||
|
# nothing to review: it stays in every output and fails the run.
|
||||||
|
failed: set[str] = set()
|
||||||
if args.realign_prose:
|
if args.realign_prose:
|
||||||
for name in selected:
|
for name in selected:
|
||||||
profile_path = Path(args.emulators_dir) / f"{name}.yml"
|
profile_path = Path(args.emulators_dir) / f"{name}.yml"
|
||||||
@@ -3441,8 +3444,12 @@ def main() -> None:
|
|||||||
raise
|
raise
|
||||||
except upstream.UpstreamError as exc:
|
except upstream.UpstreamError as exc:
|
||||||
print(f"{name}: {exc}", file=sys.stderr)
|
print(f"{name}: {exc}", file=sys.stderr)
|
||||||
|
failed.add(name)
|
||||||
except YamlWriteError as exc:
|
except YamlWriteError as exc:
|
||||||
print(f"{name}: write refused: {exc}", file=sys.stderr)
|
print(f"{name}: write refused: {exc}", file=sys.stderr)
|
||||||
|
failed.add(name)
|
||||||
|
if failed:
|
||||||
|
raise SystemExit(1)
|
||||||
return
|
return
|
||||||
|
|
||||||
reports = []
|
reports = []
|
||||||
@@ -3470,6 +3477,7 @@ def main() -> None:
|
|||||||
report = ProfileReport(
|
report = ProfileReport(
|
||||||
name=name, entries=[], counts={}, skipped=f"upstream error: {exc}"
|
name=name, entries=[], counts={}, skipped=f"upstream error: {exc}"
|
||||||
)
|
)
|
||||||
|
failed.add(name)
|
||||||
reports.append(report)
|
reports.append(report)
|
||||||
if writes:
|
if writes:
|
||||||
try:
|
try:
|
||||||
@@ -3477,13 +3485,26 @@ def main() -> None:
|
|||||||
except YamlWriteError as exc:
|
except YamlWriteError as exc:
|
||||||
# The guard already left the file untouched; keep going.
|
# The guard already left the file untouched; keep going.
|
||||||
print(f"{name}: write refused: {exc}", file=sys.stderr)
|
print(f"{name}: write refused: {exc}", file=sys.stderr)
|
||||||
|
failed.add(name)
|
||||||
|
|
||||||
# --changed-only narrows every output, not the text report alone: the
|
# --changed-only narrows every output, not the text report alone: the
|
||||||
# documented `--all --changed-only --json` listed every profile.
|
# documented `--all --changed-only --json` listed every profile.
|
||||||
shown = [
|
shown = [
|
||||||
report for report in reports
|
report for report in reports
|
||||||
if not args.changed_only or report.needs_review()
|
if not args.changed_only or report.needs_review() or report.name in failed
|
||||||
]
|
]
|
||||||
|
_emit(args, selected, reports, shown)
|
||||||
|
if failed:
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def _emit(
|
||||||
|
args: argparse.Namespace,
|
||||||
|
selected: dict,
|
||||||
|
reports: list[ProfileReport],
|
||||||
|
shown: list[ProfileReport],
|
||||||
|
) -> None:
|
||||||
|
"""Write the reports in the form the flags ask for."""
|
||||||
if args.as_json:
|
if args.as_json:
|
||||||
print(json.dumps([report_to_dict(r) for r in shown], indent=2))
|
print(json.dumps([report_to_dict(r) for r in shown], indent=2))
|
||||||
return
|
return
|
||||||
@@ -3501,23 +3522,21 @@ def main() -> None:
|
|||||||
if args.triage:
|
if args.triage:
|
||||||
_print_triage(args, selected, shown)
|
_print_triage(args, selected, shown)
|
||||||
return
|
return
|
||||||
printed = 0
|
for report in shown:
|
||||||
for report in reports:
|
|
||||||
if args.changed_only and not report.needs_review():
|
|
||||||
continue
|
|
||||||
printed += 1
|
|
||||||
print(format_report(report, args.changed_only))
|
print(format_report(report, args.changed_only))
|
||||||
_print_extras(args, selected[report.name], report)
|
_print_extras(args, selected[report.name], report)
|
||||||
print()
|
print()
|
||||||
if args.changed_only:
|
if args.changed_only:
|
||||||
_print_elided(reports, printed)
|
_print_elided(reports, len(shown), frozenset(report.name for report in shown))
|
||||||
|
|
||||||
|
|
||||||
def _print_elided(reports: list[ProfileReport], printed: int) -> None:
|
def _print_elided(
|
||||||
|
reports: list[ProfileReport], printed: int, listed: frozenset[str] = frozenset()
|
||||||
|
) -> None:
|
||||||
"""Account for what --changed-only left out, grouped by reason."""
|
"""Account for what --changed-only left out, grouped by reason."""
|
||||||
reasons: dict[str, int] = {}
|
reasons: dict[str, int] = {}
|
||||||
for report in reports:
|
for report in reports:
|
||||||
if report.needs_review():
|
if report.needs_review() or report.name in listed:
|
||||||
continue
|
continue
|
||||||
key = report.skipped or "nothing to review"
|
key = report.skipped or "nothing to review"
|
||||||
reasons[key] = reasons.get(key, 0) + 1
|
reasons[key] = reasons.get(key, 0) + 1
|
||||||
|
|||||||
@@ -3698,6 +3698,34 @@ class TestOutputModesApplyTheirFlags(unittest.TestCase):
|
|||||||
self.assertEqual(code, 1)
|
self.assertEqual(code, 1)
|
||||||
self.assertIn("--check-version", err)
|
self.assertIn("--check-version", err)
|
||||||
|
|
||||||
|
def test_a_profile_the_forge_failed_is_listed_and_fails_the_run(self):
|
||||||
|
"""Dropped by --changed-only, a 502 read as nothing to review."""
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
def build(name, *args, **kwargs):
|
||||||
|
if name == "drift":
|
||||||
|
raise profile_sync.upstream.UpstreamError("https://x: HTTP 502")
|
||||||
|
return ProfileReport(name=name)
|
||||||
|
|
||||||
|
out = io.StringIO()
|
||||||
|
saved = sys.argv
|
||||||
|
try:
|
||||||
|
sys.argv = ["profile_sync.py", "--all", "--changed-only", "--json"]
|
||||||
|
with mock.patch.object(profile_sync, "load_emulator_profiles", return_value={}), \
|
||||||
|
mock.patch.object(profile_sync, "select_profiles",
|
||||||
|
return_value={"clean": {}, "drift": {}}), \
|
||||||
|
mock.patch.object(profile_sync, "_check_quota"), \
|
||||||
|
mock.patch.object(profile_sync, "build_report", side_effect=build), \
|
||||||
|
contextlib.redirect_stdout(out), contextlib.redirect_stderr(io.StringIO()):
|
||||||
|
with self.assertRaises(SystemExit) as caught:
|
||||||
|
profile_sync.main()
|
||||||
|
finally:
|
||||||
|
sys.argv = saved
|
||||||
|
self.assertEqual(caught.exception.code, 1)
|
||||||
|
(row,) = json.loads(out.getvalue())
|
||||||
|
self.assertEqual(row["name"], "drift")
|
||||||
|
self.assertIn("upstream error", row["skipped"])
|
||||||
|
|
||||||
|
|
||||||
class TestReconcilePerFile(unittest.TestCase):
|
class TestReconcilePerFile(unittest.TestCase):
|
||||||
def test_an_anchored_part_settles_only_its_own_file(self):
|
def test_an_anchored_part_settles_only_its_own_file(self):
|
||||||
|
|||||||
Reference in new issue
Block a user