diff --git a/src/ahriman/core/archive/archive_tree.py b/src/ahriman/core/archive/archive_tree.py index dfa7500e..c145f0af 100644 --- a/src/ahriman/core/archive/archive_tree.py +++ b/src/ahriman/core/archive/archive_tree.py @@ -91,10 +91,11 @@ class ArchiveTree(LazyLogging): has_file = False for file in archive.glob(f"{single.filename}*"): symlink = root / file.name - if symlink.exists(): + try: + symlink.symlink_to(file.relative_to(symlink.parent, walk_up=True)) + has_file = True + except FileExistsError: continue # symlink is already created, skip processing - has_file = True - symlink.symlink_to(file.relative_to(symlink.parent, walk_up=True)) if has_file: repo.add(root / single.filename) diff --git a/tests/ahriman/core/archive/test_archive_tree.py b/tests/ahriman/core/archive/test_archive_tree.py index f3eb6c04..a6d0a542 100644 --- a/tests/ahriman/core/archive/test_archive_tree.py +++ b/tests/ahriman/core/archive/test_archive_tree.py @@ -1,5 +1,6 @@ from pathlib import Path from pytest_mock import MockerFixture +from unittest.mock import call as MockCall from ahriman.core.archive.archive_tree import ArchiveTree from ahriman.core.utils import utcnow @@ -23,29 +24,26 @@ def test_symlinks_create(archive_tree: ArchiveTree, package_ahriman: Package, pa """ _original_exists = Path.exists - def exists_mock(path: Path) -> bool: - if path.name in (package.filename for package in package_python_schedule.packages.values()): - return True - return _original_exists(path) - - symlinks_mock = mocker.patch("pathlib.Path.symlink_to") + symlinks_mock = mocker.patch("pathlib.Path.symlink_to", side_effect=(None, FileExistsError, FileExistsError)) add_mock = mocker.patch("ahriman.core.alpm.repo.Repo.add") mocker.patch("pathlib.Path.glob", autospec=True, side_effect=lambda path, name: [path / name[:-1]]) - mocker.patch("pathlib.Path.exists", autospec=True, side_effect=exists_mock) archive_tree.symlinks_create([package_ahriman, package_python_schedule]) - symlinks_mock.assert_called_once_with( - Path("..") / - ".." / - ".." / - ".." / - ".." / - ".." / - archive_tree.paths.archive_for(package_ahriman.base) - .relative_to(archive_tree.paths.root) - .relative_to("archive") / - package_ahriman.packages[package_ahriman.base].filename - ) + symlinks_mock.assert_has_calls([ + MockCall(Path("..") / + ".." / + ".." / + ".." / + ".." / + ".." / + archive_tree.paths.archive_for(package.base) + .relative_to(archive_tree.paths.root) + .relative_to("archive") / + single.filename + ) + for package in (package_ahriman, package_python_schedule) + for single in package.packages.values() + ]) add_mock.assert_called_once_with( archive_tree.repository_for() / package_ahriman.packages[package_ahriman.base].filename ) diff --git a/tests/ahriman/core/archive/test_archive_trigger.py b/tests/ahriman/core/archive/test_archive_trigger.py index 5f257ddc..bdacc11b 100644 --- a/tests/ahriman/core/archive/test_archive_trigger.py +++ b/tests/ahriman/core/archive/test_archive_trigger.py @@ -25,7 +25,7 @@ def test_on_start(archive_trigger: ArchiveTrigger, mocker: MockerFixture) -> Non def test_on_stop(archive_trigger: ArchiveTrigger, mocker: MockerFixture) -> None: """ - must create repository tree on load + must fix broken symlinks on stop """ symlinks_mock = mocker.patch("ahriman.core.archive.archive_tree.ArchiveTree.symlinks_fix") archive_trigger.on_stop()