use PackageSource enum for Package.load method

When using add function it sill tries to load data with invalid source
This commit is contained in:
Evgenii Alekseev 2021-10-27 02:42:32 +03:00
parent fcb130e226
commit 65ba590ace
8 changed files with 71 additions and 39 deletions

View File

@ -65,11 +65,10 @@ class Packages(Properties):
:param without_dependencies: if set, dependency check will be disabled :param without_dependencies: if set, dependency check will be disabled
""" """
aur_url = self.configuration.get("alpm", "aur_url") aur_url = self.configuration.get("alpm", "aur_url")
package = Package.load(source, self.repository.pacman, aur_url) package = Package.load(source, PackageSource.AUR, self.repository.pacman, aur_url)
Sources.load(self.repository.paths.manual_for(package.base), package.git_url,
self.repository.paths.patches_for(package.base))
local_path = self.repository.paths.manual_for(package.base) local_path = self.repository.paths.manual_for(package.base)
Sources.load(local_path, package.git_url, self.repository.paths.patches_for(package.base))
self._process_dependencies(local_path, known_packages, without_dependencies) self._process_dependencies(local_path, known_packages, without_dependencies)
def _add_directory(self, source: str, *_: Any) -> None: def _add_directory(self, source: str, *_: Any) -> None:
@ -88,11 +87,10 @@ class Packages(Properties):
:param known_packages: list of packages which are known by the service :param known_packages: list of packages which are known by the service
:param without_dependencies: if set, dependency check will be disabled :param without_dependencies: if set, dependency check will be disabled
""" """
local_path = Path(source)
aur_url = self.configuration.get("alpm", "aur_url") aur_url = self.configuration.get("alpm", "aur_url")
package = Package.load(local_path, self.repository.pacman, aur_url) package = Package.load(source, PackageSource.Local, self.repository.pacman, aur_url)
cache_dir = self.repository.paths.cache_for(package.base) cache_dir = self.repository.paths.cache_for(package.base)
shutil.copytree(local_path, cache_dir) # copy package to store in caches shutil.copytree(Path(source), cache_dir) # copy package to store in caches
Sources.init(cache_dir) # we need to run init command in directory where we do have permissions Sources.init(cache_dir) # we need to run init command in directory where we do have permissions
dst = self.repository.paths.manual_for(package.base) dst = self.repository.paths.manual_for(package.base)

View File

@ -26,6 +26,7 @@ from ahriman.application.application.properties import Properties
from ahriman.core.build_tools.sources import Sources from ahriman.core.build_tools.sources import Sources
from ahriman.core.tree import Tree from ahriman.core.tree import Tree
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
class Repository(Properties): class Repository(Properties):
@ -133,7 +134,10 @@ class Repository(Properties):
def process_update(paths: Iterable[Path]) -> None: def process_update(paths: Iterable[Path]) -> None:
if not paths: if not paths:
return # don't need to process if no update supplied return # don't need to process if no update supplied
updated = [Package.load(path, self.repository.pacman, self.repository.aur_url) for path in paths] updated = [
Package.load(str(path), PackageSource.Archive, self.repository.pacman, self.repository.aur_url)
for path in paths
]
self.repository.process_update(paths) self.repository.process_update(paths)
self._finalize(updated) self._finalize(updated)

View File

@ -29,6 +29,7 @@ from ahriman.core.build_tools.sources import Sources
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.models.action import Action from ahriman.models.action import Action
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
class Patch(Handler): class Patch(Handler):
@ -55,23 +56,24 @@ class Patch(Handler):
elif args.action == Action.Remove: elif args.action == Action.Remove:
Patch.patch_set_remove(application, args.package) Patch.patch_set_remove(application, args.package)
elif args.action == Action.Update: elif args.action == Action.Update:
Patch.patch_set_create(application, Path(args.package), args.track) Patch.patch_set_create(application, args.package, args.track)
@staticmethod @staticmethod
def patch_set_create(application: Application, sources_dir: Path, track: List[str]) -> None: def patch_set_create(application: Application, sources_dir: str, track: List[str]) -> None:
""" """
create patch set for the package base create patch set for the package base
:param application: application instance :param application: application instance
:param sources_dir: path to directory with the package sources :param sources_dir: path to directory with the package sources
:param track: track files which match the glob before creating the patch :param track: track files which match the glob before creating the patch
""" """
package = Package.load(sources_dir, application.repository.pacman, application.repository.aur_url) package = Package.load(sources_dir, PackageSource.Local, application.repository.pacman,
application.repository.aur_url)
patch_dir = application.repository.paths.patches_for(package.base) patch_dir = application.repository.paths.patches_for(package.base)
Patch.patch_set_remove(application, package.base) # remove old patches Patch.patch_set_remove(application, package.base) # remove old patches
patch_dir.mkdir(mode=0o755, parents=True) patch_dir.mkdir(mode=0o755, parents=True)
Sources.patch_create(sources_dir, patch_dir / "00-main.patch", *track) Sources.patch_create(Path(sources_dir), patch_dir / "00-main.patch", *track)
@staticmethod @staticmethod
def patch_set_list(application: Application, package_base: str) -> None: def patch_set_list(application: Application, package_base: str) -> None:

View File

@ -27,6 +27,7 @@ from ahriman.core.report.report import Report
from ahriman.core.repository.cleaner import Cleaner from ahriman.core.repository.cleaner import Cleaner
from ahriman.core.upload.upload import Upload from ahriman.core.upload.upload import Upload
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
class Executor(Cleaner): class Executor(Cleaner):
@ -155,7 +156,7 @@ class Executor(Cleaner):
updates: Dict[str, Package] = {} updates: Dict[str, Package] = {}
for filename in packages: for filename in packages:
try: try:
local = Package.load(filename, self.pacman, self.aur_url) local = Package.load(str(filename), PackageSource.Archive, self.pacman, self.aur_url)
updates.setdefault(local.base, local).packages.update(local.packages) updates.setdefault(local.base, local).packages.update(local.packages)
except Exception: except Exception:
self.logger.exception("could not load package from %s", filename) self.logger.exception("could not load package from %s", filename)

View File

@ -24,6 +24,7 @@ from ahriman.core.repository.executor import Executor
from ahriman.core.repository.update_handler import UpdateHandler from ahriman.core.repository.update_handler import UpdateHandler
from ahriman.core.util import package_like from ahriman.core.util import package_like
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
class Repository(Executor, UpdateHandler): class Repository(Executor, UpdateHandler):
@ -39,7 +40,7 @@ class Repository(Executor, UpdateHandler):
result: Dict[str, Package] = {} result: Dict[str, Package] = {}
for full_path in filter(package_like, self.paths.repository.iterdir()): for full_path in filter(package_like, self.paths.repository.iterdir()):
try: try:
local = Package.load(full_path, self.pacman, self.aur_url) local = Package.load(str(full_path), PackageSource.Archive, self.pacman, self.aur_url)
result.setdefault(local.base, local).packages.update(local.packages) result.setdefault(local.base, local).packages.update(local.packages)
except Exception: except Exception:
self.logger.exception("could not load package from %s", full_path) self.logger.exception("could not load package from %s", full_path)

View File

@ -21,6 +21,7 @@ from typing import Iterable, List
from ahriman.core.repository.cleaner import Cleaner from ahriman.core.repository.cleaner import Cleaner
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
class UpdateHandler(Cleaner): class UpdateHandler(Cleaner):
@ -53,7 +54,7 @@ class UpdateHandler(Cleaner):
continue continue
try: try:
remote = Package.load(local.base, self.pacman, self.aur_url) remote = Package.load(local.base, PackageSource.AUR, self.pacman, self.aur_url)
if local.is_outdated(remote, self.paths): if local.is_outdated(remote, self.paths):
self.reporter.set_pending(local.base) self.reporter.set_pending(local.base)
result.append(remote) result.append(remote)
@ -72,16 +73,16 @@ class UpdateHandler(Cleaner):
result: List[Package] = [] result: List[Package] = []
known_bases = {package.base for package in self.packages()} known_bases = {package.base for package in self.packages()}
for filename in self.paths.manual.iterdir(): for dirname in self.paths.manual.iterdir():
try: try:
local = Package.load(filename, self.pacman, self.aur_url) local = Package.load(str(dirname), PackageSource.Local, self.pacman, self.aur_url)
result.append(local) result.append(local)
if local.base not in known_bases: if local.base not in known_bases:
self.reporter.set_unknown(local) self.reporter.set_unknown(local)
else: else:
self.reporter.set_pending(local.base) self.reporter.set_pending(local.base)
except Exception: except Exception:
self.logger.exception("could not add package from %s", filename) self.logger.exception("could not add package from %s", dirname)
self.clear_manual() self.clear_manual()
return result return result

View File

@ -26,12 +26,13 @@ from dataclasses import asdict, dataclass
from pathlib import Path from pathlib import Path
from pyalpm import vercmp # type: ignore from pyalpm import vercmp # type: ignore
from srcinfo.parse import parse_srcinfo # type: ignore from srcinfo.parse import parse_srcinfo # type: ignore
from typing import Any, Dict, List, Optional, Set, Type, Union from typing import Any, Dict, List, Optional, Set, Type
from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.pacman import Pacman
from ahriman.core.exceptions import InvalidPackageInfo from ahriman.core.exceptions import InvalidPackageInfo
from ahriman.core.util import check_output from ahriman.core.util import check_output
from ahriman.models.package_description import PackageDescription from ahriman.models.package_description import PackageDescription
from ahriman.models.package_source import PackageSource
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
@ -164,21 +165,24 @@ class Package:
packages=packages) packages=packages)
@classmethod @classmethod
def load(cls: Type[Package], path: Union[Path, str], pacman: Pacman, aur_url: str) -> Package: def load(cls: Type[Package], package: str, source: PackageSource, pacman: Pacman, aur_url: str) -> Package:
""" """
package constructor from available sources package constructor from available sources
:param path: one of path to sources directory, path to archive or package name/base :param package: one of path to sources directory, path to archive or package name/base
:param source: source of the package required to define the load method
:param pacman: alpm wrapper instance (required to load from archive) :param pacman: alpm wrapper instance (required to load from archive)
:param aur_url: AUR root url :param aur_url: AUR root url
:return: package properties :return: package properties
""" """
try: try:
maybe_path = Path(path) resolved_source = source.resolve(package)
if maybe_path.is_dir(): if resolved_source == PackageSource.Archive:
return cls.from_build(maybe_path, aur_url) return cls.from_archive(Path(package), pacman, aur_url)
if maybe_path.is_file(): if resolved_source == PackageSource.AUR:
return cls.from_archive(maybe_path, pacman, aur_url) return cls.from_aur(package, aur_url)
return cls.from_aur(str(path), aur_url) if resolved_source == PackageSource.Local:
return cls.from_build(Path(package), aur_url)
raise InvalidPackageInfo(f"Unsupported local package source {resolved_source}")
except InvalidPackageInfo: except InvalidPackageInfo:
raise raise
except Exception as e: except Exception as e:

View File

@ -6,6 +6,7 @@ from unittest.mock import MagicMock, PropertyMock
from ahriman.core.exceptions import InvalidPackageInfo from ahriman.core.exceptions import InvalidPackageInfo
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.package_source import PackageSource
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
@ -156,14 +157,24 @@ def test_from_json_view_3(package_tpacpi_bat_git: Package) -> None:
assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git
def test_load_resolve(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None:
"""
must resolve source before package loading
"""
resolve_mock = mocker.patch("ahriman.models.package_source.PackageSource.resolve",
return_value=PackageSource.Archive)
mocker.patch("ahriman.models.package.Package.from_archive")
Package.load("path", PackageSource.Archive, pyalpm_handle, package_ahriman.aur_url)
resolve_mock.assert_called_once_with("path")
def test_load_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None: def test_load_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None:
""" """
must load package from package archive must load package from package archive
""" """
mocker.patch("pathlib.Path.is_file", return_value=True)
load_mock = mocker.patch("ahriman.models.package.Package.from_archive") load_mock = mocker.patch("ahriman.models.package.Package.from_archive")
Package.load("path", PackageSource.Archive, pyalpm_handle, package_ahriman.aur_url)
Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url)
load_mock.assert_called_once() load_mock.assert_called_once()
@ -172,8 +183,7 @@ def test_load_from_aur(package_ahriman: Package, pyalpm_handle: MagicMock, mocke
must load package from AUR must load package from AUR
""" """
load_mock = mocker.patch("ahriman.models.package.Package.from_aur") load_mock = mocker.patch("ahriman.models.package.Package.from_aur")
Package.load("path", PackageSource.AUR, pyalpm_handle, package_ahriman.aur_url)
Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url)
load_mock.assert_called_once() load_mock.assert_called_once()
@ -181,10 +191,8 @@ def test_load_from_build(package_ahriman: Package, pyalpm_handle: MagicMock, moc
""" """
must load package from build directory must load package from build directory
""" """
mocker.patch("pathlib.Path.is_dir", return_value=True)
load_mock = mocker.patch("ahriman.models.package.Package.from_build") load_mock = mocker.patch("ahriman.models.package.Package.from_build")
Package.load("path", PackageSource.Local, pyalpm_handle, package_ahriman.aur_url)
Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url)
load_mock.assert_called_once() load_mock.assert_called_once()
@ -192,13 +200,26 @@ def test_load_failure(package_ahriman: Package, pyalpm_handle: MagicMock, mocker
""" """
must raise InvalidPackageInfo on exception must raise InvalidPackageInfo on exception
""" """
mocker.patch("pathlib.Path.is_dir", side_effect=InvalidPackageInfo("exception!")) mocker.patch("ahriman.models.package.Package.from_aur", side_effect=InvalidPackageInfo("exception!"))
with pytest.raises(InvalidPackageInfo): with pytest.raises(InvalidPackageInfo):
Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) Package.load("path", PackageSource.AUR, pyalpm_handle, package_ahriman.aur_url)
mocker.patch("pathlib.Path.is_dir", side_effect=Exception())
def test_load_failure_exception(package_ahriman: Package, pyalpm_handle: MagicMock, mocker: MockerFixture) -> None:
"""
must raise InvalidPackageInfo on random eexception
"""
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception())
with pytest.raises(InvalidPackageInfo): with pytest.raises(InvalidPackageInfo):
Package.load(Path("path"), pyalpm_handle, package_ahriman.aur_url) Package.load("path", PackageSource.AUR, pyalpm_handle, package_ahriman.aur_url)
def test_load_invalid_source(package_ahriman: Package, pyalpm_handle: MagicMock) -> None:
"""
must raise InvalidPackageInfo on unsupported source
"""
with pytest.raises(InvalidPackageInfo):
Package.load("path", PackageSource.Remote, pyalpm_handle, package_ahriman.aur_url)
def test_dependencies_failed(mocker: MockerFixture) -> None: def test_dependencies_failed(mocker: MockerFixture) -> None: