fix: prioritize Structure A over Structure B in library structure detection

When a top-level `roms/` folder exists (Structure A), never detect the
library as Structure B, even if individual `<platform>/roms/` directories
also exist. This prevents existing Structure A libraries from being broken
after upgrading to 4.9.0.

- `has_structure_path_b` in `config_manager.py` now returns `False` early
  when `{LIBRARY_BASE_PATH}/{ROMS_FOLDER_NAME}` is an existing directory
- `detect_library_structure()` in `platforms_handler.py` now explicitly
  checks Structure A (`os.path.exists(roms_path)`) before consulting
  `cnfg.has_structure_path_b`
- Updated test to assert Structure A wins when both layouts coexist

Co-authored-by: gantoine <3247106+gantoine@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-06-12 16:35:01 +00:00
committed by GitHub
parent 4ccad8ba17
commit 788d454d98
3 changed files with 24 additions and 10 deletions

View File

@@ -140,6 +140,13 @@ class Config:
@functools.cached_property
def has_structure_path_b(self) -> bool:
# Structure A (roms/{platform}) takes priority: if the top-level roms
# folder exists, never claim Structure B even if some platform dirs
# happen to contain a roms sub-folder.
roms_path = os.path.join(LIBRARY_BASE_PATH, self.ROMS_FOLDER_NAME)
if os.path.isdir(roms_path):
return False
pattern = os.path.join(
LIBRARY_BASE_PATH, "*", glob.escape(self.ROMS_FOLDER_NAME)
)

View File

@@ -33,22 +33,27 @@ class FSPlatformsHandler(FSHandler):
def detect_library_structure(self) -> LibraryStructure | None:
"""Detects the library structure type.
Structure A (roms/{platform}) takes priority over Structure B
({platform}/roms) so that existing libraries are not broken when a
stray {platform}/roms directory happens to exist alongside them.
Returns:
"LibraryStructure.B" for Structure B ({platform}/roms) when any
platform has a roms subfolder.
"LibraryStructure.A" for Structure A (roms/{platform}) when the
top-level roms folder exists.
"LibraryStructure.B" for Structure B ({platform}/roms) when no
top-level roms folder exists but at least one platform has a
roms subfolder.
None if no structure detected.
"""
cnfg = cm.get_config()
if cnfg.has_structure_path_b:
return LibraryStructure.B
roms_path = os.path.join(LIBRARY_BASE_PATH, cnfg.ROMS_FOLDER_NAME)
if os.path.exists(roms_path):
return LibraryStructure.A
if cnfg.has_structure_path_b:
return LibraryStructure.B
return None
def get_platforms_directory(self) -> str:

View File

@@ -337,13 +337,15 @@ class TestFSPlatformsHandler:
with patch(
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
):
result = handler.detect_library_structure()
assert result == LibraryStructure.B
with patch("os.path.exists", return_value=False):
result = handler.detect_library_structure()
assert result == LibraryStructure.B
def test_detect_library_structure_b_takes_priority_over_a(
def test_detect_library_structure_a_takes_priority_over_b(
self, handler: FSPlatformsHandler, config
):
"""Structure B is reported even when the top-level roms folder exists."""
"""Structure A is reported when the top-level roms folder exists, even
when Structure B directories are also present."""
config.has_structure_path_b = True
with patch(
@@ -351,7 +353,7 @@ class TestFSPlatformsHandler:
):
with patch("os.path.exists", return_value=True):
result = handler.detect_library_structure()
assert result == LibraryStructure.B
assert result == LibraryStructure.A
def test_detect_library_structure_none(self, handler: FSPlatformsHandler, config):
"""Test detect_library_structure returns None when no structure detected"""