From 3066083caf77c8f472a2c8b470d6011b0357d74e Mon Sep 17 00:00:00 2001 From: Mirko Brombin Date: Mon, 28 Sep 2026 18:12:15 +0200 Subject: [PATCH] fix: refresh installer catalog on demand --- bottles/backend/managers/installer.py | 7 +++++++ bottles/backend/repos/repo.py | 5 +++++ bottles/frontend/views/bottle_installers.py | 6 +++++- .../tests/backend/manager/test_installer.py | 20 +++++++++++++++++++ bottles/tests/backend/repos/test_repo.py | 18 +++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/bottles/backend/managers/installer.py b/bottles/backend/managers/installer.py index 93b61454..37c1b41a 100644 --- a/bottles/backend/managers/installer.py +++ b/bottles/backend/managers/installer.py @@ -86,6 +86,13 @@ class InstallerManager: catalog = dict(sorted(catalog.items())) return catalog + def refresh_catalog(self) -> dict: + self.__repo.refresh() + self.fetch_catalog.cache_clear() + self.get_installer.cache_clear() + self.get_review.cache_clear() + return self.fetch_catalog() + def get_icon_url(self, installer): """Wrapper for the repo method.""" return self.__repo.get_icon(installer) diff --git a/bottles/backend/repos/repo.py b/bottles/backend/repos/repo.py index 6d0dd24e..fc116e5c 100644 --- a/bottles/backend/repos/repo.py +++ b/bottles/backend/repos/repo.py @@ -46,6 +46,7 @@ class Repo: ): self.url = url self.cache_url = cache_url or url + self.index = index self.offline = offline self.catalog = None @@ -66,6 +67,10 @@ class Repo: offline=offline, ) + def refresh(self) -> dict: + self.catalog = self.__get_catalog(self.index, self.offline) + return self.catalog + def __get_catalog(self, index: str, offline: bool = False): cache_path = self.__get_cache_path("catalog.yml") if index in ["", None] or offline: diff --git a/bottles/frontend/views/bottle_installers.py b/bottles/frontend/views/bottle_installers.py index f8ad17a0..94c719f0 100644 --- a/bottles/frontend/views/bottle_installers.py +++ b/bottles/frontend/views/bottle_installers.py @@ -88,7 +88,6 @@ class InstallersView(Adw.Bin): if config is None: config = BottleConfig() self.config = config - installers = self.manager.supported_installers.items() include_unstable = self.window.settings.get_boolean("release-candidate") self.list_installers.set_sensitive(False) @@ -110,6 +109,11 @@ class InstallersView(Adw.Bin): time.sleep(0.5) # workaround for freezing bug on bottle load GLib.idle_add(self.empty_list) + catalog = self.manager.installer_manager.refresh_catalog() + if catalog: + self.manager.supported_installers = catalog + installers = self.manager.supported_installers.items() + if len(installers) == 0: return Result(False) diff --git a/bottles/tests/backend/manager/test_installer.py b/bottles/tests/backend/manager/test_installer.py index a7821a60..772d488f 100644 --- a/bottles/tests/backend/manager/test_installer.py +++ b/bottles/tests/backend/manager/test_installer.py @@ -43,6 +43,26 @@ def test_installer_respects_compatible_runners(runners, runner, expected): assert InstallerManager.supports_runner(installer, runner) is expected +def test_installer_refreshes_catalog_and_cached_manifests(mocker): + repository = mocker.Mock() + repository.catalog = {"old": {"Name": "Old"}} + + def refresh(): + repository.catalog = {"new": {"Name": "New"}} + + repository.refresh.side_effect = refresh + installer = object.__new__(InstallerManager) + installer._InstallerManager__repo = repository + installer._InstallerManager__utils_conn = mocker.Mock(check_connection=lambda: True) + + assert installer.fetch_catalog() == {"old": {"Name": "Old"}} + repository.get.return_value = {"Version": 1} + assert installer.get_installer("office") == {"Version": 1} + repository.get.return_value = {"Version": 2} + assert installer.refresh_catalog() == {"new": {"Name": "New"}} + assert installer.get_installer("office") == {"Version": 2} + + @pytest.mark.parametrize("current_value", [True, False]) def test_installer_applies_window_decoration_parameter(mocker, current_value): registry = mocker.patch( diff --git a/bottles/tests/backend/repos/test_repo.py b/bottles/tests/backend/repos/test_repo.py index 73ac2a35..51c9ae3b 100644 --- a/bottles/tests/backend/repos/test_repo.py +++ b/bottles/tests/backend/repos/test_repo.py @@ -37,6 +37,24 @@ def test_catalog_callback_mode_is_configurable(monkeypatch, callback_in_main_loo assert callback_modes == [callback_in_main_loop] +def test_repository_refresh_reloads_the_current_index(monkeypatch): + repository = object.__new__(ComponentRepo) + repository.index = "https://repo.example.test/index.yml" + repository.offline = False + repository.catalog = {"old": {}} + calls = [] + + def get_catalog(_repository, index, offline=False): + calls.append((index, offline)) + return {"new": {}} + + monkeypatch.setattr(repo_module.Repo, "_Repo__get_catalog", get_catalog) + + assert repository.refresh() == {"new": {}} + assert repository.catalog == {"new": {}} + assert calls == [(repository.index, False)] + + @pytest.mark.parametrize( ("manager_type", "repository_name"), [