From fa34a9fe18d9d087475a656de35e7b4bdd9c1a5b Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sun, 18 Oct 2026 13:45:48 +0200 Subject: [PATCH] fix: hold docs/ while the site is generated --- scripts/generate_site.py | 12 ++++++++++++ tests/test_artifact_lock.py | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/scripts/generate_site.py b/scripts/generate_site.py index 42f95ad0..d232ce0a 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -46,6 +46,7 @@ from common import ( unique_emulator_profiles, yaml_load, ) +from artifacts import ArtifactLockBusy, artifact_lock from cross_reference import FileConsumers from nativemode import reads_file_contents @@ -4097,6 +4098,17 @@ def main() -> None: parser.add_argument("--emulators-dir", default="emulators") parser.add_argument("--docs-dir", default=DOCS_DIR) args = parser.parse_args() + try: + # Two runs over one docs/ delete each other's pages and scratch + # files in the sweep; the second is refused instead. + with artifact_lock(args.docs_dir): + _generate(args) + except ArtifactLockBusy as exc: + print(f"ERROR: {exc}", file=sys.stderr) + sys.exit(1) + + +def _generate(args: argparse.Namespace) -> None: db = load_database(args.db) docs = Path(args.docs_dir) diff --git a/tests/test_artifact_lock.py b/tests/test_artifact_lock.py index 748b109e..c77c8b2f 100644 --- a/tests/test_artifact_lock.py +++ b/tests/test_artifact_lock.py @@ -221,5 +221,26 @@ class PipelineHoldsTheDataTrees(unittest.TestCase): self.assertLess(hold, verify) + +class SiteGenerationHoldsDocs(unittest.TestCase): + """generate_site swept from docs/ every file its own run had not + written, including the scratch file and new pages of a second run on + the same tree; that run then died on os.replace or lost pages.""" + + def test_a_second_run_is_refused_before_it_writes(self): + docs = _tempdir(self) + marker = Path(docs) / "platforms" / ".retroarch.md.k2j3.tmp" + marker.parent.mkdir() + marker.write_text("scratch of another run") + with artifact_lock(docs): + result = subprocess.run( + [sys.executable, "scripts/generate_site.py", "--docs-dir", docs], + cwd=REPO_ROOT, capture_output=True, text=True, timeout=600, + ) + self.assertEqual(result.returncode, 1, result.stdout + result.stderr) + self.assertIn("in use by another run", result.stderr) + self.assertTrue(marker.exists()) + + if __name__ == "__main__": unittest.main()