From 797fe425b114cf386dca6207e4d35177b297d1af Mon Sep 17 00:00:00 2001 From: ginnoir Date: Fri, 5 Jun 2026 22:37:35 -0500 Subject: [PATCH] feat(roms): add igir per-platform dry-run + rename sweep helpers igir-dryrun.sh: read-only igir report for one platform vs given DAT(s), prints an identified%% summary + sample of unmatched files (the scoring step of the platform sweep). igir-dorename.sh: igir move to canonical names in place for one platform, with before/after manifests for reversibility and --dir-game-subdir never to keep folders flat. Cart-safe; not for disc systems with .m3u. --- scripts/igir-dorename.sh | 36 ++++++++++++++++++++++++++++++++++ scripts/igir-dryrun.sh | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 scripts/igir-dorename.sh create mode 100644 scripts/igir-dryrun.sh diff --git a/scripts/igir-dorename.sh b/scripts/igir-dorename.sh new file mode 100644 index 0000000..73fc226 --- /dev/null +++ b/scripts/igir-dorename.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# scripts/igir-dorename.sh (runs ON valhalla) +# +# igir 'move' to canonical No-Intro/Redump names, in place, for one platform. +# Records a before/after filename manifest under /storage1/igir/manifests for +# reversibility. Unmatched files are left untouched; --dir-game-subdir never +# keeps the folder flat (EmuDeck expects flat per-platform dirs). +# +# Only run on platforms that scored healthy in igir-dryrun.sh (>=~80% identified) +# AND have no co-located saves keyed to ROM basenames (renaming would orphan +# them) AND are NOT disc systems with .m3u multi-disc playlists (renaming the +# images breaks the playlists). Carts are the safe case. +# +# ssh ginnoir@valhalla 'bash -s -- gb "no-intro/Nintendo - Game Boy.dat"' < scripts/igir-dorename.sh +# # or, already deployed on the host: +# ssh ginnoir@valhalla 'bash /storage1/igir/dorename.sh nes "no-intro/Nintendo - Nintendo Entertainment System.dat"' +# +# Undo: the before-manifest lists original names; igir is deterministic, so +# re-running against the same DAT is idempotent. +set -uo pipefail +plat="$1"; shift +dargs=(); for d in "$@"; do dargs+=(-d "/dats/$d"); done +mkdir -p /storage1/igir/manifests +before="/storage1/igir/manifests/${plat}-before.txt" +after="/storage1/igir/manifests/${plat}-after.txt" +ls -1 "/storage1/Emulation/roms/$plat" > "$before" +docker run --rm \ + -v /storage1/Emulation/roms:/input \ + -v /storage1/igir/dats/libretro-database/metadat:/dats:ro \ + -v /storage1/igir/reports:/output \ + node:lts npx -y igir@latest move "${dargs[@]}" \ + --dir-game-subdir never \ + -i "/input/$plat" -o "/input/$plat" 2>&1 \ + | grep -vE "npm notice|npm warn" || true +ls -1 "/storage1/Emulation/roms/$plat" > "$after" +echo "RENAME $plat: before_files=$(wc -l < "$before") after_files=$(wc -l < "$after")" diff --git a/scripts/igir-dryrun.sh b/scripts/igir-dryrun.sh new file mode 100644 index 0000000..8f042f9 --- /dev/null +++ b/scripts/igir-dryrun.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# scripts/igir-dryrun.sh (runs ON valhalla) +# +# Read-only igir REPORT for one platform folder against the given DAT(s), then a +# checksum-status summary + a sample of unmatched files. Used to score a platform +# ("identified%") before deciding whether to canonicalize it with igir-dorename.sh. +# +# DAT paths are relative to libretro-database/metadat (so "no-intro/..." or +# "redump/...") — the cache populated by scripts/igir-report.ps1. +# +# ssh ginnoir@valhalla 'bash -s -- gb "no-intro/Nintendo - Game Boy.dat"' < scripts/igir-dryrun.sh +# # or, already deployed on the host: +# ssh ginnoir@valhalla 'bash /storage1/igir/dryrun.sh nes "no-intro/Nintendo - Nintendo Entertainment System.dat"' +set -uo pipefail +plat="$1"; shift +dargs=(); for d in "$@"; do dargs+=(-d "/dats/$d"); done +out="_dry_${plat}.csv" +docker run --rm \ + -v /storage1/Emulation/roms:/input:ro \ + -v /storage1/igir/dats/libretro-database/metadat:/dats:ro \ + -v /storage1/igir/reports:/output \ + node:lts npx -y igir@latest report "${dargs[@]}" \ + -i "/input/$plat" --report-output "/output/$out" 2>&1 \ + | grep -E "files found|games," || true +python3 - "/storage1/igir/reports/$out" <<'PY' +import csv,sys +name=sys.argv[1].split('/')[-1] +found=unused=dup=missing=0; samp=[] +with open(sys.argv[1],newline='',encoding='utf-8',errors='replace') as fh: + for r in csv.DictReader(fh): + s=r.get('Status','') + if s=='FOUND': found+=1 + elif s=='UNUSED': + unused+=1 + if len(samp)<10: samp.append(r.get('ROM Files') or r.get('Game Name','')) + elif s=='DUPLICATE': dup+=1 + elif s=='MISSING': missing+=1 +den=found+dup+unused +pct=100.0*(found+dup)/den if den else 0 +print(f"SUMMARY {name}: identified={pct:.1f}% matched={found+dup}/{den} FOUND={found} DUP={dup} UNUSED={unused} MISSING={missing}") +for x in samp: print(" UNUSED:",x) +PY