diff --git a/src/ahriman/core/database/migrations/m016_archive.py b/src/ahriman/core/database/migrations/m016_archive.py index 376c17ce..056e972b 100644 --- a/src/ahriman/core/database/migrations/m016_archive.py +++ b/src/ahriman/core/database/migrations/m016_archive.py @@ -25,7 +25,8 @@ from sqlite3 import Connection from ahriman.application.handlers.handler import Handler from ahriman.core.alpm.pacman import Pacman from ahriman.core.configuration import Configuration -from ahriman.core.utils import symlink_relative +from ahriman.core.sign.gpg import GPG +from ahriman.core.utils import package_like, symlink_relative from ahriman.models.package import Package from ahriman.models.pacman_synchronization import PacmanSynchronization from ahriman.models.repository_paths import RepositoryPaths @@ -67,19 +68,19 @@ def move_packages(repository_paths: RepositoryPaths, pacman: Pacman) -> None: repository_paths(RepositoryPaths): repository paths instance pacman(Pacman): alpm wrapper instance """ - for source in repository_paths.repository.iterdir(): - if not source.is_file(follow_symlinks=False): + for archive in filter(package_like, repository_paths.repository.iterdir()): + if not archive.is_file(follow_symlinks=False): continue # skip symbolic links if any - filename = source.name - if filename.startswith(".") or ".pkg." not in filename: - # we don't use package_like method here, because it also filters out signatures - continue - package = Package.from_archive(source, pacman) + package = Package.from_archive(archive, pacman) + artifacts = [archive] + # check if there are signatures for this package and append it here too + if (signature := GPG.signature(archive)).exists(): + artifacts.append(signature) - # move package to the archive directory - target = repository_paths.archive_for(package.base) / filename - source.rename(target) - - # create symlink to the archive - symlink_relative(source, target) + for source in artifacts: + # move package to the archive directory + target = repository_paths.archive_for(package.base) / source.name + source.rename(target) + # create symlink to the archive + symlink_relative(source, target) diff --git a/src/ahriman/core/utils.py b/src/ahriman/core/utils.py index e9d53aa8..4efc65e8 100644 --- a/src/ahriman/core/utils.py +++ b/src/ahriman/core/utils.py @@ -282,7 +282,9 @@ def filelock(path: Path) -> Iterator[None]: finally: fcntl.flock(fd, fcntl.LOCK_UN) # unlock file first finally: - lock_path.unlink(missing_ok=True) # remove lock file at the end + # remove lock file at the end + # there might be a race condition here, but we don't care about this case + lock_path.unlink(missing_ok=True) def filter_json(source: dict[str, Any], known_fields: Iterable[str]) -> dict[str, Any]: diff --git a/tests/ahriman/core/database/migrations/test_m016_archive.py b/tests/ahriman/core/database/migrations/test_m016_archive.py index 12f71b30..8bb091b3 100644 --- a/tests/ahriman/core/database/migrations/test_m016_archive.py +++ b/tests/ahriman/core/database/migrations/test_m016_archive.py @@ -47,10 +47,12 @@ def test_move_packages(repository_paths: RepositoryPaths, pacman: Pacman, packag repository_paths.repository / "directory", repository_paths.repository / "file.pkg.tar.xz", repository_paths.repository / "file.pkg.tar.xz.sig", + repository_paths.repository / "file2.pkg.tar.xz", repository_paths.repository / "symlink.pkg.tar.xz", ]) mocker.patch("pathlib.Path.is_dir", return_value=True) mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=is_file) + mocker.patch("pathlib.Path.exists", return_value=True) archive_mock = mocker.patch("ahriman.models.package.Package.from_archive", return_value=package_ahriman) rename_mock = mocker.patch("pathlib.Path.rename") symlink_mock = mocker.patch("pathlib.Path.symlink_to") @@ -58,11 +60,12 @@ def test_move_packages(repository_paths: RepositoryPaths, pacman: Pacman, packag move_packages(repository_paths, pacman) archive_mock.assert_has_calls([ MockCall(repository_paths.repository / "file.pkg.tar.xz", pacman), - MockCall(repository_paths.repository / "file.pkg.tar.xz.sig", pacman), + MockCall(repository_paths.repository / "file2.pkg.tar.xz", pacman), ]) rename_mock.assert_has_calls([ MockCall(repository_paths.archive_for(package_ahriman.base) / "file.pkg.tar.xz"), MockCall(repository_paths.archive_for(package_ahriman.base) / "file.pkg.tar.xz.sig"), + MockCall(repository_paths.archive_for(package_ahriman.base) / "file2.pkg.tar.xz"), ]) symlink_mock.assert_has_calls([ MockCall( @@ -79,4 +82,11 @@ def test_move_packages(repository_paths: RepositoryPaths, pacman: Pacman, packag repository_paths.archive_for(package_ahriman.base).relative_to(repository_paths.root) / "file.pkg.tar.xz.sig" ), + MockCall( + Path("..") / + ".." / + ".." / + repository_paths.archive_for(package_ahriman.base).relative_to(repository_paths.root) / + "file2.pkg.tar.xz" + ), ])