fix: check --target before the output lock

A mistyped target waited on the dist lock and the data directory refresh
before it was refused (finding 62).
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 11:44:22 +01:00
1 parent 8ef4eb47fc
commit 9ae0ede21d
2 files changed
+43 -13

No files matched your search

+16 -13
View File
@@ -3477,6 +3477,22 @@ def _main(held: contextlib.ExitStack) -> None:
parser.error("Specify --platform or --all")
return
# A mistyped target is refused before the output lock and the data
# directory refresh: checked after them, `--target swich` waited on a
# pipeline's caches before saying the target does not exist.
target_cores_cache: dict[str, set[str] | None] = {}
if args.target:
try:
target_cores_cache, platforms = build_target_cores_cache(
platforms,
args.target,
args.platforms_dir,
is_all=args.all,
)
except (FileNotFoundError, ValueError) as e:
print(f"ERROR: {e}", file=sys.stderr)
sys.exit(1)
data_registry = load_data_dir_registry(args.platforms_dir)
# The output directory is claimed before the data directory refresh: a
# refresh waits for every run that holds a cache, so a second build
@@ -3498,19 +3514,6 @@ def _main(held: contextlib.ExitStack) -> None:
emu_profiles = load_emulator_profiles(args.emulators_dir)
target_cores_cache: dict[str, set[str] | None] = {}
if args.target:
try:
target_cores_cache, platforms = build_target_cores_cache(
platforms,
args.target,
args.platforms_dir,
is_all=args.all,
)
except (FileNotFoundError, ValueError) as e:
print(f"ERROR: {e}", file=sys.stderr)
sys.exit(1)
groups = group_identical_platforms(
platforms, args.platforms_dir, target_cores_cache if args.target else None
)
+27
View File
@@ -58,5 +58,32 @@ class ANameClaimsOnlyANarrowingThatHappened(unittest.TestCase):
)
class AMistypedTargetIsRefusedFirst(unittest.TestCase):
"""`--platform retroarch --target swich` took the dist lock and waited on
the data directory refresh, 22 s here and hours behind a pipeline, before
saying the target does not exist."""
def test_no_lock_and_no_refresh_before_the_refusal(self):
from unittest import mock
import generate_pack
def touched(*_a, **_kw):
raise AssertionError("lock or refresh taken before the target check")
argv = ["generate_pack.py", "--platform", "retroarch", "--target", "swich",
"--output-dir", str(REPO_ROOT / "tmp" / "never-written")]
err = io.StringIO()
with mock.patch.object(sys, "argv", argv), \
mock.patch.object(generate_pack, "_pack_output_lock", touched), \
mock.patch.object(generate_pack, "hold_data_dirs", touched), \
contextlib.redirect_stdout(io.StringIO()), \
contextlib.redirect_stderr(err), \
self.assertRaises(SystemExit) as ctx:
generate_pack.main()
self.assertEqual(ctx.exception.code, 1)
self.assertIn("Unknown target 'swich'", err.getvalue())
if __name__ == "__main__":
unittest.main()