From de8e7ff02e52cc5ac60fd5b36c0be71f3069452c Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 17 Oct 2026 20:47:22 +0200 Subject: [PATCH] fix: separate message parts with a colon --- scripts/common.py | 2 +- scripts/generate_pack.py | 12 ++++++------ scripts/verify.py | 12 ++++++------ tests/test_audit_regressions.py | 18 +++++++++++++++++- tests/test_native_mode.py | 2 +- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/scripts/common.py b/scripts/common.py index 3459107e..78a148d9 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -1499,7 +1499,7 @@ def select_emulator_profiles( ) if kind == "launcher": raise ProfileSelectionError( - f"{name} is a launcher -use the emulator it launches" + f"{name} is a launcher: use the emulator it launches" ) if standalone and "standalone" not in kind: raise ProfileSelectionError( diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index e97ea4df..ef0952e9 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -353,7 +353,7 @@ def _data_directory_members( local_path = entry.get("local_cache", "") if not local_path or not os.path.isdir(local_path): print( - f" WARNING: data directory '{ref_key}' not cached at {local_path} -run refresh_data_dirs.py" + f" WARNING: data directory '{ref_key}' not cached at {local_path} (run refresh_data_dirs.py)" ) _MISSING_DATA_DIRS.add(ref_key) continue @@ -1026,7 +1026,7 @@ def generate_pack( validation_owners, ) if disagreement: - core_discrepancies.append(f"{full_dest} -{disagreement}") + core_discrepancies.append(f"{full_dest}: {disagreement}") if status == "hash_mismatch" and not _matches_an_alternative( fe, local_path, emu_profiles or {} ): @@ -1037,7 +1037,7 @@ def generate_pack( # file_status tracks platform declarations only, so the report # goes to its own list and never moves the pack's own count. core_discrepancies.append( - f"{full_dest} -declared hash of " + f"{full_dest}: declared hash of " f"{fe.get('source_profile') or fe.get('source_emulator', 'core profile')}" " does not match the packed copy" ) @@ -1119,7 +1119,7 @@ def generate_pack( label = "MISSING" else: label = "DISCREPANCY" - print(f" {label}: {key} -{reason}") + print(f" {label}: {key}: {reason}") for name in missing_files: print(f" MISSING: {name}") for note in sorted(core_discrepancies): @@ -1500,7 +1500,7 @@ def generate_emulator_pack( ) if disagreement: reason = disagreement.split(" says ", 1)[-1] - refusal = refusal or f"{fe['name']} -{reason}" + refusal = refusal or f"{fe['name']}: {reason}" refused_path = refused_path or local_path continue if better != local_path: @@ -1560,7 +1560,7 @@ def generate_emulator_pack( continue if how == "mismatch": discrepancies.append( - f"{fe['name']} -not the dump the {emu_name} profile declares" + f"{fe['name']}: not the dump the {emu_name} profile declares" ) # SHA1 dedup: skip if same physical file AND same destination diff --git a/scripts/verify.py b/scripts/verify.py index 8351c0c8..fcf25cea 100644 --- a/scripts/verify.py +++ b/scripts/verify.py @@ -139,7 +139,7 @@ def verify_entry_existence( resolve_status: str = "", platform_display: str = "", ) -> dict: - """RetroArch verification: path_is_valid() -file exists = OK.""" + """RetroArch verification: path_is_valid(), a file that exists is OK.""" name = file_entry.get("name", "") required = file_entry.get("required", True) if not local_path: @@ -1254,7 +1254,7 @@ def _print_detail_entries(details: list[dict], seen: set[str], verbose: bool) -> req = "required" if d.get("required", True) else "optional" hle = ", HLE available" if d.get("hle_fallback") else "" reason = d.get("reason", "") - print(f" UNTESTED ({req}{hle}): {key} -{reason}") + print(f" UNTESTED ({req}{hle}): {key}: {reason}") _print_ground_truth(d.get("ground_truth", []), verbose) for d in details: if d["status"] == Status.MISSING: @@ -1273,7 +1273,7 @@ def _print_detail_entries(details: list[dict], seen: set[str], verbose: bool) -> if key in seen: continue seen.add(key) - print(f" DISCREPANCY: {key} -{disc}") + print(f" DISCREPANCY: {key}: {disc}") _print_ground_truth(d.get("ground_truth", []), verbose) if verbose: @@ -1422,7 +1422,7 @@ def print_platform_result( if exclusions and verbose: print(f" No external files ({len(exclusions)}):") for ex in exclusions: - print(f" {ex['emulator']} -{ex['detail']} [{ex['reason']}]") + print(f" {ex['emulator']}: {ex['detail']} [{ex['reason']}]") elif exclusions: print(f" No external files: {len(exclusions)} cores (--verbose lists them)") @@ -1944,7 +1944,7 @@ def print_emulator_result(result: dict, verbose: bool = False) -> None: req = "required" if d.get("required", True) else "optional" hle = ", HLE available" if d.get("hle_fallback") else "" reason = d.get("reason", "") - print(f" UNTESTED ({req}{hle}): {d['name']} -{reason}") + print(f" UNTESTED ({req}{hle}): {d['name']}: {reason}") gt = d.get("ground_truth", []) if gt: if verbose: @@ -1973,7 +1973,7 @@ def print_emulator_result(result: dict, verbose: bool = False) -> None: continue seen.add(d["name"]) why = d.get("unsourceable") or "documented as unobtainable" - print(f" UNSOURCEABLE: {d['name']} -{why}") + print(f" UNSOURCEABLE: {d['name']}: {why}") for d in result["details"]: if d.get("note"): diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index bd602b32..5660f650 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -2084,7 +2084,7 @@ class ACheckThatCannotAnswerDoesNotPass(unittest.TestCase): encoding="utf-8" ) self.assertIn( - 'if report.get("error"):', + 'if report.get("error") or pending(report):', source.split("def main(")[-1], "main() ignores the error the report carries", ) @@ -3426,5 +3426,21 @@ class AutoFetchAsksVerifyWhatIsMissing(unittest.TestCase): self.assertEqual(names, ["gone.bin", "bad.bin", "diabdat.mpq"]) + +class MessagesSeparateWithAColon(unittest.TestCase): + """Em-dashes were replaced by " -" in messages: "bios/BLOOD.RFF -raze + says size mismatch" reads as a flag glued to a file name.""" + + PATTERN = re.compile(r"\} -[{a-z]") + + def test_no_message_uses_a_dash_separator(self): + found = [] + for path in [ROOT / "install.py", *sorted((ROOT / "scripts").rglob("*.py"))]: + for number, line in enumerate(path.read_text().splitlines(), 1): + if self.PATTERN.search(line): + found.append(f"{path.name}:{number}: {line.strip()}") + self.assertEqual(found, []) + + if __name__ == "__main__": unittest.main() diff --git a/tests/test_native_mode.py b/tests/test_native_mode.py index de203348..07c4601b 100644 --- a/tests/test_native_mode.py +++ b/tests/test_native_mode.py @@ -472,7 +472,7 @@ class OneProfileSelector(unittest.TestCase): f"{name} must ask common, not re-derive the refusal", ) self.assertNotIn( - 'is a launcher -use the emulator it launches', text, + 'is a launcher: use the emulator it launches', text, f"{name} still spells the refusal itself", )