Files
homelabstack/scripts/igir-report.ps1
T
ginnoir 57aba346f9 feat(roms): add igir report + SNES header-strip ops scripts
igir-report.ps1: read-only igir report over the EmuDeck tree on valhalla,
matching ROMs by checksum against libretro's No-Intro + Redump DAT sets
(sparse-cloned + cached). Scoped (-Platforms) or whole-library (-All);
CSV per run under /storage1/igir/reports. Uses node:lts (alpine breaks
igir on musl) and metadat/no-intro (not the curated dat/ folder).

igir-strip-snes-headers.sh: reversible backup-then-strip of 512-byte SNES
copier headers (size%1024==512) that igir can't auto-detect, renaming to
.sfc so headered ROMs match headerless No-Intro.
2026-06-05 20:54:17 -05:00

96 lines
3.9 KiB
PowerShell

#!/usr/bin/env pwsh
# scripts/igir-report.ps1
#
# Run the igir ROM collection manager in REPORT mode (read-only) against the
# EmuDeck tree at /storage1/Emulation/roms on valhalla, matching ROMs by
# checksum against the full No-Intro + Redump DAT sets. Produces a CSV per run
# under /storage1/igir/reports listing FOUND / MISSING / UNUSED per system.
#
# Nothing is moved, renamed, or deleted — the ROM tree is mounted read-only.
#
# ./scripts/igir-report.ps1 -Platforms gba,snes,n64,psx # scoped run (fast)
# ./scripts/igir-report.ps1 -All # whole library (SLOW: hashes everything)
# ./scripts/igir-report.ps1 -Platforms snes -UpdateDats # refresh the cached DATs first
#
# Gotchas baked in (all learned the hard way — see memory igir-roms):
# * Uses the Debian `node:lts` image, NOT node:lts-alpine (igir silently
# dies on musl).
# * DATs come from libretro-database `metadat/no-intro` + `metadat/redump`
# (full sets with checksums), NOT the tiny curated top-level `dat/` folder.
# * SNES `.smc` copier headers (size%1024==512) are NOT auto-detected by igir
# and won't match headerless No-Intro until physically stripped. The `snes`
# folder was stripped 2026-06-06; if you add more headered SNES ROMs, strip
# them first (see scripts/igir-strip-snes-headers.sh) or they'll show UNUSED.
[CmdletBinding()]
param(
[string[]]$Platforms,
[switch]$All,
[switch]$UpdateDats,
[string]$Hostname = 'valhalla'
)
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
$server = "ginnoir@$Hostname"
if (-not $All -and (-not $Platforms -or $Platforms.Count -eq 0)) {
Write-Error "Specify -Platforms <name,name,...> (e.g. -Platforms gba,snes) or -All for the whole library."
exit 1
}
# Build the igir -i input args. -All scans the entire roms tree (heavy);
# otherwise one -i per named platform folder.
if ($All) {
$inputArgs = '-i /input'
} else {
$inputArgs = ($Platforms | ForEach-Object { "-i /input/$_" }) -join ' '
}
$doPull = if ($UpdateDats) { '1' } else { '0' }
# Remote logic runs on valhalla. Single-quoted here-string so PowerShell leaves
# $vars for bash; INPUT_ARGS / DOPULL are injected below.
$remote = @'
set -uo pipefail
DATS=/storage1/igir/dats/libretro-database
REPORTS=/storage1/igir/reports
mkdir -p "$REPORTS" /storage1/igir/dats
# Sparse, blobless clone of just the No-Intro + Redump DAT dirs (cached & reused).
if [ ! -d "$DATS/.git" ]; then
echo ">> Fetching libretro-database DATs (one-time sparse clone)..."
docker run --rm -v /storage1/igir:/w -w /w node:lts sh -c '
git clone --filter=blob:none --sparse --depth 1 \
https://github.com/libretro/libretro-database dats/libretro-database &&
cd dats/libretro-database &&
git sparse-checkout set metadat/no-intro metadat/redump'
elif [ "__DOPULL__" = "1" ]; then
echo ">> Updating cached DATs..."
docker run --rm -v /storage1/igir:/w -w /w/dats/libretro-database node:lts git pull -q
fi
NI=$(find "$DATS/metadat/no-intro" -name '*.dat' | wc -l)
RD=$(find "$DATS/metadat/redump" -name '*.dat' | wc -l)
echo ">> DATs available: $NI No-Intro, $RD Redump"
STAMP=$(date +%Y-%m-%dT%H-%M-%S)
OUT="igir-report-$STAMP.csv"
echo ">> Running igir report -> $REPORTS/$OUT"
docker run --rm \
-v /storage1/Emulation/roms:/input:ro \
-v "$DATS":/dats:ro \
-v "$REPORTS":/output \
node:lts npx -y igir@latest report \
-d /dats/metadat/no-intro -d /dats/metadat/redump \
__INPUT_ARGS__ \
--report-output "/output/$OUT" 2>&1 | grep -vE 'npm notice|npm warn' || true
echo ">> Done. CSV: /storage1/igir/reports/$OUT"
'@
$remote = $remote.Replace('__INPUT_ARGS__', $inputArgs).Replace('__DOPULL__', $doPull)
# Strip CR so the remote bash never sees stray \r (this file may be CRLF on disk).
$remote = $remote.Replace("`r", '')
Write-Host "igir report on $server :: $(if ($All) {'ALL platforms'} else {$Platforms -join ', '})"
ssh $server $remote