diff --git a/backend/config/config_manager.py b/backend/config/config_manager.py index b8aa92687..16883284a 100644 --- a/backend/config/config_manager.py +++ b/backend/config/config_manager.py @@ -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) ) diff --git a/backend/handler/filesystem/platforms_handler.py b/backend/handler/filesystem/platforms_handler.py index eed0e969a..8d1c4f5f2 100644 --- a/backend/handler/filesystem/platforms_handler.py +++ b/backend/handler/filesystem/platforms_handler.py @@ -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: diff --git a/backend/tests/handler/filesystem/test_platforms_handler.py b/backend/tests/handler/filesystem/test_platforms_handler.py index fdcc12b1f..4743b7c30 100644 --- a/backend/tests/handler/filesystem/test_platforms_handler.py +++ b/backend/tests/handler/filesystem/test_platforms_handler.py @@ -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"""