From d4455c508f7f48048487d361421063ba193c1d56 Mon Sep 17 00:00:00 2001 From: Andrew Quenehen Date: Sat, 1 Aug 2026 05:19:59 -0300 Subject: [PATCH] feat(nx-mods): scan imports/mods for zip candidates Co-authored-by: Cursor --- src/import/RomImporter.lua | 18 ++++++++++++++++ tests/rom_importer_nx_mods_inbox_test.lua | 26 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/import/RomImporter.lua b/src/import/RomImporter.lua index d60df0e7..ecc2a1cb 100644 --- a/src/import/RomImporter.lua +++ b/src/import/RomImporter.lua @@ -398,6 +398,18 @@ local function listRomPaths(dir) return paths end +local function listZipPaths(dir) + local paths = {} + for _, name in ipairs(love.filesystem.getDirectoryItems(dir) or {}) do + local path = (dir == "" or dir == "/") and name or (dir .. "/" .. name) + if name:lower():match("%.zip$") + and love.filesystem.getInfo(path, "file") then + paths[#paths + 1] = path + end + end + return paths +end + function RomImporter:scanInbox(ready) ready = ready or self.ready local paths = {} @@ -411,6 +423,12 @@ function RomImporter:scanInbox(ready) return paths end +-- NX mods inbox: only *.zip under imports/mods/ (never ROM extensions). +function RomImporter:scanModsInbox() + self:ensureModsInboxDir() + return listZipPaths(MODS_INBOX_DIR) +end + function RomImporter:rescanAction(version) if self.workState == "working" then return end version = version or self.tab or "red" diff --git a/tests/rom_importer_nx_mods_inbox_test.lua b/tests/rom_importer_nx_mods_inbox_test.lua index 352dd86e..86d7e63d 100644 --- a/tests/rom_importer_nx_mods_inbox_test.lua +++ b/tests/rom_importer_nx_mods_inbox_test.lua @@ -62,9 +62,12 @@ local function freshImporter() tab = "mods", modNotice = nil, mods = {}, + ready = { red = false, blue = false, yellow = false }, ensureImportsDir = RomImporter.ensureImportsDir, ensureModsInboxDir = RomImporter.ensureModsInboxDir, _setNxModsInboxNotice = RomImporter._setNxModsInboxNotice, + scanModsInbox = RomImporter.scanModsInbox, + scanInbox = RomImporter.scanInbox, }, RomImporter) end @@ -88,8 +91,31 @@ check(ri.modNotice.text:find("DBI MTP", 1, true) ~= nil, check(ri.modNotice.text:find("switch/gen1recomp/pokemon-love2d/imports/mods/", 1, true), "hint uses sdmc-stripped relative imports/mods/ path") +-- NXMOD-02: scanModsInbox returns only *.zip under imports/mods/ +ri = freshImporter() +love.filesystem.write("imports/mods/valid.zip", "ZIPDATA") +love.filesystem.write("imports/mods/readme.txt", "nope") +love.filesystem.write("imports/mods/cart.gb", string.rep("R", 16)) +love.filesystem.write("imports/other.zip", "WRONGDIR") +local zips = ri:scanModsInbox() +eq(#zips, 1, "scanModsInbox returns one zip candidate") +eq(zips[1], "imports/mods/valid.zip", "scanModsInbox path is under imports/mods/") + +-- ROM scanInbox must not treat .zip as ROM +ri = freshImporter() +love.filesystem.write("imports/modpack.zip", "ZIPROM") +love.filesystem.write("imports/mods/also.zip", "ZIPMOD") +local roms = ri:scanInbox(ri.ready) +for _, path in ipairs(roms) do + check(not path:lower():match("%.zip$"), + "ROM scanInbox ignores zip: " .. tostring(path)) +end +eq(#roms, 0, "ROM scanInbox finds no zip-only inbox entries") + -- Cleanup + restore stubs clearModsInbox() +love.filesystem.remove("imports/other.zip") +love.filesystem.remove("imports/modpack.zip") love.system.getOS = saved.getOS love.filesystem.getSaveDirectory = saved.getSaveDirectory love.filesystem.createDirectory = saved.createDirectory