diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index e303b322..da96a087 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -1974,6 +1974,26 @@ def _validate_args(args, parser): parser.error("--manifest is incompatible with --split") if getattr(args, "region", None) and has_from_md5: parser.error("--region and --from-md5 are mutually exclusive") + # A mode either applies a narrowing flag or refuses it. Swallowing one + # answers about an artifact the caller did not ask for, and the name on + # disk then asserts a narrowing the contents do not carry. + source_given = getattr(args, "source", "full") != "full" + if source_given and (has_emulator or (has_system and not has_platform)): + parser.error("--source requires --platform or --all") + if has_from_md5: + for flag, given in ( + ("--target", args.target), + ("--required-only", args.required_only), + ("--source", source_given), + ): + if given: + parser.error(f"{flag} is incompatible with --from-md5") + if has_system and has_platform: + if args.manifest: + parser.error("--system is incompatible with --manifest") + if args.split: + parser.error("--system is incompatible with --split") + if getattr(args, "one_per_slot", False): if has_from_md5: parser.error("--one-per-slot and --from-md5 are mutually exclusive") @@ -2445,6 +2465,16 @@ def main(): _run_verify_packs(args) return if args.manifest_targets: + # This mode writes one manifest per hardware target from the target + # files themselves; it reads none of the narrowing flags. --region and + # --one-per-slot are refused above, and these three the same way. + for flag, given in ( + ("--target", args.target), + ("--required-only", args.required_only), + ("--source", args.source != "full"), + ): + if given: + parser.error(f"{flag} is incompatible with --manifest-targets") with _pack_output_lock(args.output_dir): generate_target_manifests( os.path.join(args.platforms_dir, "targets"), args.output_dir diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 9bc83fa2..cc0412ca 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -5824,6 +5824,23 @@ struct BurnDriver BurnDrvneogeo = { "refuse"), (["--platform", "retroarch", "--verify-packs"], ["--source", "truth"], "refuse"), + # Modes that read none of these: the flag reached the filename or + # nothing at all, never the selection. + (["--emulator", "duckstation"], ["--source", "truth"], "refuse"), + (["--system", "sony-playstation"], ["--source", "truth"], "refuse"), + (["--manifest-targets"], ["--target", "switch"], "refuse"), + (["--manifest-targets"], ["--required-only"], "refuse"), + (["--manifest-targets"], ["--source", "truth"], "refuse"), + (["--platform", "retroarch", "--from-md5", "d8f1"], + ["--target", "switch"], "refuse"), + (["--platform", "retroarch", "--from-md5", "d8f1"], + ["--required-only"], "refuse"), + (["--platform", "retroarch", "--from-md5", "d8f1"], + ["--source", "truth"], "refuse"), + (["--platform", "retroarch", "--manifest"], + ["--system", "sony-playstation"], "refuse"), + (["--platform", "retroarch", "--split"], + ["--system", "sony-playstation"], "refuse"), ] for mode, flag, expected in matrix: with self.subTest(mode=mode, flag=flag):