diff --git a/scripts/export_native.py b/scripts/export_native.py index 32af276b..105b20d2 100644 --- a/scripts/export_native.py +++ b/scripts/export_native.py @@ -552,6 +552,13 @@ def export_platform( return False, ["the exporter produced no file"] issues = exporter.validate(systems, produced) + if issues: + # Written first, a file its own validator refused replaced the + # published export and only the exit code said so. + invalid = [f"INVALID: {issue}" for issue in issues[:10]] + if len(issues) > 10: + invalid.append(f"and {len(issues) - 10} more validation failures") + return False, invalid platform_dir = output_dir / platform _remove_stale(platform_dir, set(produced)) @@ -628,10 +635,6 @@ def export_platform( if len(cleared) > 5: messages.append(f"and {len(cleared) - 5} more cleared") - messages.extend(f"INVALID: {issue}" for issue in issues[:10]) - if len(issues) > 10: - messages.append(f"and {len(issues) - 10} more validation failures") - write_report(output_dir / f"{platform}.json", { "platform": platform, "originals": wanted_sources(exporter, systems, scraped), @@ -652,7 +655,7 @@ def export_platform( "withheld": list(withheld), "invalid": issues, }) - return not issues, messages + return True, messages def write_report(path: Path, report: dict) -> None: diff --git a/tests/test_exporters.py b/tests/test_exporters.py index 51161d8c..a5c91b69 100644 --- a/tests/test_exporters.py +++ b/tests/test_exporters.py @@ -1092,6 +1092,37 @@ class AnExportWithoutTruthIsRefused(unittest.TestCase): ["batocera", "batocera-systems"]) +class AnInvalidExportIsNotWritten(unittest.TestCase): + """validate() ran after the files were written: an export its own + validator refused still replaced the published one, and only the exit + code said so.""" + + def test_the_published_file_stays(self): + from unittest import mock # noqa: PLC0415 + + import export_native # noqa: PLC0415 + + if not (UPSTREAM_CACHE / "romm").exists(): + self.skipTest("upstream cache not populated") + exporter = discover_exporters()["romm"] + config = native_layer(load_platform_config("romm", str(REPO_ROOT / "platforms"))) + with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp: + output = Path(tmp) / "out" + published = output / "romm" / "known_bios_files.json" + published.parent.mkdir(parents=True) + published.write_text("published", encoding="utf-8") + with mock.patch.object(export_native, "load_inputs", + return_value=({"systems": {}}, config)), \ + mock.patch.object(exporter, "validate", return_value=["bad entry"]): + ok, messages = export_native.export_platform( + "romm", exporter, Path(tmp), output, + str(REPO_ROOT / "platforms"), UPSTREAM_CACHE, False, + ) + self.assertFalse(ok) + self.assertIn("INVALID: bad entry", messages) + self.assertEqual(published.read_text(encoding="utf-8"), "published") + + class RommKeepsItsFixture(unittest.TestCase): """The export rebuilt known_bios_files.json from our model in our order: 3 hash corrections came out as a 3116-line diff, and a key RomM had that