From d42ec12ae8a67add740bd0e59f2a9730667ee028 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Sat, 1 Mar 2025 16:17:07 +0100 Subject: [PATCH] Fix cloning of add-on store repository (#5701) * Fix cloning of add-on store repository Since #5669, the add-on store reset no longer deletes the root directory. However, if the root directory is not present, the current code no longer invokes cloning, instead tries to load the git repository directly. With this change, the code clones whenever there is no .git directory, which works for both cases. * Fix pytest --- supervisor/store/git.py | 2 +- tests/store/test_repository_git.py | 44 ++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/supervisor/store/git.py b/supervisor/store/git.py index 1cf3b0551..f0bb3a7b0 100644 --- a/supervisor/store/git.py +++ b/supervisor/store/git.py @@ -49,7 +49,7 @@ class GitRepo(CoreSysAttributes): async def load(self) -> None: """Init Git add-on repository.""" - if not self.path.is_dir(): + if not (self.path / ".git").is_dir(): await self.clone() return diff --git a/tests/store/test_repository_git.py b/tests/store/test_repository_git.py index 09c7c1850..3bb444232 100644 --- a/tests/store/test_repository_git.py +++ b/tests/store/test_repository_git.py @@ -67,17 +67,30 @@ async def test_git_clone_error( async def test_git_load(coresys: CoreSys, tmp_path: Path): """Test git load.""" - repo = GitRepo(coresys, tmp_path, REPO_URL) + repo_dir = tmp_path / "repo" + repo = GitRepo(coresys, repo_dir, REPO_URL) + repo.clone = AsyncMock() - with ( - patch("pathlib.Path.is_dir", return_value=True), - patch.object( - GitRepo, "sys_run_in_executor", new_callable=AsyncMock - ) as run_in_executor, - ): + # Test with non-existing git repo root directory + await repo.load() + assert repo.clone.call_count == 1 + + repo.clone.reset_mock() + + # Test with existing git repo root directory, but empty + repo_dir.mkdir() + await repo.load() + assert repo.clone.call_count == 1 + + repo.clone.reset_mock() + + # Pretend we have a repo + (repo_dir / ".git").mkdir() + + with patch("git.Repo") as mock_repo: await repo.load() - - assert run_in_executor.call_count == 2 + assert repo.clone.call_count == 0 + assert mock_repo.call_count == 1 @pytest.mark.parametrize( @@ -87,21 +100,22 @@ async def test_git_load(coresys: CoreSys, tmp_path: Path): NoSuchPathError(), GitCommandError("init"), UnicodeDecodeError("decode", b"", 0, 0, ""), - [AsyncMock(), GitCommandError("fsck")], + GitCommandError("fsck"), ], ) async def test_git_load_error(coresys: CoreSys, tmp_path: Path, git_errors: Exception): """Test git load error.""" + coresys.hardware.disk.get_disk_free_space = lambda x: 5000 repo = GitRepo(coresys, tmp_path, REPO_URL) + # Pretend we have a repo + (tmp_path / ".git").mkdir() + with ( - patch("pathlib.Path.is_dir", return_value=True), - patch.object( - GitRepo, "sys_run_in_executor", new_callable=AsyncMock - ) as run_in_executor, + patch("git.Repo") as mock_repo, pytest.raises(StoreGitError), ): - run_in_executor.side_effect = git_errors + mock_repo.side_effect = git_errors await repo.load() assert len(coresys.resolution.suggestions) == 0