mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-04-21 00:02:36 -05:00
feat: add --required-only flag to generate_pack
This commit is contained in:
@@ -231,6 +231,7 @@ def generate_pack(
|
|||||||
data_registry: dict | None = None,
|
data_registry: dict | None = None,
|
||||||
emu_profiles: dict | None = None,
|
emu_profiles: dict | None = None,
|
||||||
target_cores: set[str] | None = None,
|
target_cores: set[str] | None = None,
|
||||||
|
required_only: bool = False,
|
||||||
) -> str | None:
|
) -> str | None:
|
||||||
"""Generate a ZIP pack for a platform.
|
"""Generate a ZIP pack for a platform.
|
||||||
|
|
||||||
@@ -246,7 +247,8 @@ def generate_pack(
|
|||||||
|
|
||||||
version = config.get("version", config.get("dat_version", ""))
|
version = config.get("version", config.get("dat_version", ""))
|
||||||
version_tag = f"_{version.replace(' ', '')}" if version else ""
|
version_tag = f"_{version.replace(' ', '')}" if version else ""
|
||||||
zip_name = f"{platform_display.replace(' ', '_')}{version_tag}_BIOS_Pack.zip"
|
req_tag = "_Required" if required_only else ""
|
||||||
|
zip_name = f"{platform_display.replace(' ', '_')}{version_tag}{req_tag}_BIOS_Pack.zip"
|
||||||
zip_path = os.path.join(output_dir, zip_name)
|
zip_path = os.path.join(output_dir, zip_name)
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
@@ -282,6 +284,8 @@ def generate_pack(
|
|||||||
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf:
|
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||||
for sys_id, system in sorted(pack_systems.items()):
|
for sys_id, system in sorted(pack_systems.items()):
|
||||||
for file_entry in system.get("files", []):
|
for file_entry in system.get("files", []):
|
||||||
|
if required_only and file_entry.get("required") is False:
|
||||||
|
continue
|
||||||
dest = _sanitize_path(file_entry.get("destination", file_entry["name"]))
|
dest = _sanitize_path(file_entry.get("destination", file_entry["name"]))
|
||||||
if not dest:
|
if not dest:
|
||||||
# EmuDeck-style entries (system:md5 whitelist, no filename).
|
# EmuDeck-style entries (system:md5 whitelist, no filename).
|
||||||
@@ -429,6 +433,8 @@ def generate_pack(
|
|||||||
)
|
)
|
||||||
core_count = 0
|
core_count = 0
|
||||||
for fe in core_files:
|
for fe in core_files:
|
||||||
|
if required_only and fe.get("required") is False:
|
||||||
|
continue
|
||||||
dest = _sanitize_path(fe.get("destination", fe["name"]))
|
dest = _sanitize_path(fe.get("destination", fe["name"]))
|
||||||
if not dest:
|
if not dest:
|
||||||
continue
|
continue
|
||||||
@@ -591,6 +597,7 @@ def generate_emulator_pack(
|
|||||||
output_dir: str,
|
output_dir: str,
|
||||||
standalone: bool = False,
|
standalone: bool = False,
|
||||||
zip_contents: dict | None = None,
|
zip_contents: dict | None = None,
|
||||||
|
required_only: bool = False,
|
||||||
) -> str | None:
|
) -> str | None:
|
||||||
"""Generate a ZIP pack for specific emulator profiles."""
|
"""Generate a ZIP pack for specific emulator profiles."""
|
||||||
all_profiles = load_emulator_profiles(emulators_dir, skip_aliases=False)
|
all_profiles = load_emulator_profiles(emulators_dir, skip_aliases=False)
|
||||||
@@ -710,6 +717,8 @@ def generate_emulator_pack(
|
|||||||
|
|
||||||
# Pack individual files (skip archived ones)
|
# Pack individual files (skip archived ones)
|
||||||
for fe in files:
|
for fe in files:
|
||||||
|
if required_only and fe.get("required") is False:
|
||||||
|
continue
|
||||||
if fe.get("archive"):
|
if fe.get("archive"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -801,6 +810,7 @@ def generate_system_pack(
|
|||||||
output_dir: str,
|
output_dir: str,
|
||||||
standalone: bool = False,
|
standalone: bool = False,
|
||||||
zip_contents: dict | None = None,
|
zip_contents: dict | None = None,
|
||||||
|
required_only: bool = False,
|
||||||
) -> str | None:
|
) -> str | None:
|
||||||
"""Generate a ZIP pack for all emulators supporting given system IDs."""
|
"""Generate a ZIP pack for all emulators supporting given system IDs."""
|
||||||
profiles = load_emulator_profiles(emulators_dir)
|
profiles = load_emulator_profiles(emulators_dir)
|
||||||
@@ -835,7 +845,7 @@ def generate_system_pack(
|
|||||||
)
|
)
|
||||||
result = generate_emulator_pack(
|
result = generate_emulator_pack(
|
||||||
matching, emulators_dir, db, bios_dir, output_dir,
|
matching, emulators_dir, db, bios_dir, output_dir,
|
||||||
standalone, zip_contents,
|
standalone, zip_contents, required_only=required_only,
|
||||||
)
|
)
|
||||||
if result:
|
if result:
|
||||||
# Rename to system-based name
|
# Rename to system-based name
|
||||||
@@ -874,6 +884,8 @@ def main():
|
|||||||
parser.add_argument("--refresh-data", action="store_true",
|
parser.add_argument("--refresh-data", action="store_true",
|
||||||
help="Force re-download all data directories")
|
help="Force re-download all data directories")
|
||||||
parser.add_argument("--list", action="store_true", help="List available platforms")
|
parser.add_argument("--list", action="store_true", help="List available platforms")
|
||||||
|
parser.add_argument("--required-only", action="store_true",
|
||||||
|
help="Only include required files, skip optional")
|
||||||
parser.add_argument("--target", "-t", help="Hardware target (e.g., switch, rpi4)")
|
parser.add_argument("--target", "-t", help="Hardware target (e.g., switch, rpi4)")
|
||||||
parser.add_argument("--list-targets", action="store_true", help="List available targets for the platform")
|
parser.add_argument("--list-targets", action="store_true", help="List available targets for the platform")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@@ -923,7 +935,7 @@ def main():
|
|||||||
names = [n.strip() for n in args.emulator.split(",") if n.strip()]
|
names = [n.strip() for n in args.emulator.split(",") if n.strip()]
|
||||||
result = generate_emulator_pack(
|
result = generate_emulator_pack(
|
||||||
names, args.emulators_dir, db, args.bios_dir, args.output_dir,
|
names, args.emulators_dir, db, args.bios_dir, args.output_dir,
|
||||||
args.standalone, zip_contents,
|
args.standalone, zip_contents, required_only=args.required_only,
|
||||||
)
|
)
|
||||||
if not result:
|
if not result:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -934,7 +946,7 @@ def main():
|
|||||||
system_ids = [s.strip() for s in args.system.split(",") if s.strip()]
|
system_ids = [s.strip() for s in args.system.split(",") if s.strip()]
|
||||||
result = generate_system_pack(
|
result = generate_system_pack(
|
||||||
system_ids, args.emulators_dir, db, args.bios_dir, args.output_dir,
|
system_ids, args.emulators_dir, db, args.bios_dir, args.output_dir,
|
||||||
args.standalone, zip_contents,
|
args.standalone, zip_contents, required_only=args.required_only,
|
||||||
)
|
)
|
||||||
if not result:
|
if not result:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -1003,6 +1015,7 @@ def main():
|
|||||||
include_extras=args.include_extras, emulators_dir=args.emulators_dir,
|
include_extras=args.include_extras, emulators_dir=args.emulators_dir,
|
||||||
zip_contents=zip_contents, data_registry=data_registry,
|
zip_contents=zip_contents, data_registry=data_registry,
|
||||||
emu_profiles=emu_profiles, target_cores=tc,
|
emu_profiles=emu_profiles, target_cores=tc,
|
||||||
|
required_only=args.required_only,
|
||||||
)
|
)
|
||||||
if zip_path and variants:
|
if zip_path and variants:
|
||||||
rep_cfg = load_platform_config(representative, args.platforms_dir)
|
rep_cfg = load_platform_config(representative, args.platforms_dir)
|
||||||
|
|||||||
@@ -1539,6 +1539,68 @@ class TestE2E(unittest.TestCase):
|
|||||||
self.assertEqual(gt["total"], result["total_files"])
|
self.assertEqual(gt["total"], result["total_files"])
|
||||||
self.assertGreaterEqual(gt["with_validation"], 1)
|
self.assertGreaterEqual(gt["with_validation"], 1)
|
||||||
|
|
||||||
|
def test_130_required_only_excludes_optional(self):
|
||||||
|
"""--required-only excludes files with required: false from pack."""
|
||||||
|
from generate_pack import generate_pack
|
||||||
|
output_dir = os.path.join(self.root, "pack_reqonly")
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
# Create a platform with one required and one optional file
|
||||||
|
config = {
|
||||||
|
"platform": "ReqOnlyTest",
|
||||||
|
"verification_mode": "existence",
|
||||||
|
"base_destination": "system",
|
||||||
|
"systems": {
|
||||||
|
"test-sys": {
|
||||||
|
"files": [
|
||||||
|
{"name": "present_req.bin", "destination": "present_req.bin", "required": True},
|
||||||
|
{"name": "present_opt.bin", "destination": "present_opt.bin", "required": False},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
with open(os.path.join(self.platforms_dir, "test_reqonly.yml"), "w") as fh:
|
||||||
|
yaml.dump(config, fh)
|
||||||
|
zip_path = generate_pack(
|
||||||
|
"test_reqonly", self.platforms_dir, self.db, self.bios_dir, output_dir,
|
||||||
|
required_only=True,
|
||||||
|
)
|
||||||
|
self.assertIsNotNone(zip_path)
|
||||||
|
with zipfile.ZipFile(zip_path) as zf:
|
||||||
|
names = zf.namelist()
|
||||||
|
self.assertTrue(any("present_req.bin" in n for n in names))
|
||||||
|
self.assertFalse(any("present_opt.bin" in n for n in names))
|
||||||
|
# Verify _Required tag in filename
|
||||||
|
self.assertIn("_Required_", os.path.basename(zip_path))
|
||||||
|
|
||||||
|
def test_131_required_only_keeps_default_required(self):
|
||||||
|
"""--required-only keeps files with no required field (default = required)."""
|
||||||
|
from generate_pack import generate_pack
|
||||||
|
output_dir = os.path.join(self.root, "pack_reqdef")
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
# File with no required field
|
||||||
|
config = {
|
||||||
|
"platform": "ReqDefTest",
|
||||||
|
"verification_mode": "existence",
|
||||||
|
"base_destination": "system",
|
||||||
|
"systems": {
|
||||||
|
"test-sys": {
|
||||||
|
"files": [
|
||||||
|
{"name": "present_req.bin", "destination": "present_req.bin"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
with open(os.path.join(self.platforms_dir, "test_reqdef.yml"), "w") as fh:
|
||||||
|
yaml.dump(config, fh)
|
||||||
|
zip_path = generate_pack(
|
||||||
|
"test_reqdef", self.platforms_dir, self.db, self.bios_dir, output_dir,
|
||||||
|
required_only=True,
|
||||||
|
)
|
||||||
|
self.assertIsNotNone(zip_path)
|
||||||
|
with zipfile.ZipFile(zip_path) as zf:
|
||||||
|
names = zf.namelist()
|
||||||
|
self.assertTrue(any("present_req.bin" in n for n in names))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user