From 62d55eff19b747fcd51124fbd212557f2be499a7 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Fri, 2 Apr 2021 04:20:39 +0300 Subject: [PATCH] add ability to fitler by dependency list --- src/ahriman/application/ahriman.py | 1 + src/ahriman/application/handlers/rebuild.py | 6 ++- src/ahriman/core/report/html.py | 2 + src/ahriman/core/repository/repository.py | 2 +- src/ahriman/models/package.py | 7 ++++ src/ahriman/models/package_description.py | 3 ++ src/ahriman/web/views/index.py | 2 + .../handlers/test_handler_rebuild.py | 40 +++++++++++++++++++ tests/ahriman/conftest.py | 3 ++ tests/ahriman/models/conftest.py | 1 + tests/ahriman/models/test_package.py | 10 +++++ 11 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index 980ab96a..0ce4b26f 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -136,6 +136,7 @@ def _set_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser: """ parser = root.add_parser("rebuild", help="rebuild repository", description="rebuild whole repository", formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument("--depends-on", help="only rebuild packages that depend on specified package") parser.set_defaults(handler=handlers.Rebuild) return parser diff --git a/src/ahriman/application/handlers/rebuild.py b/src/ahriman/application/handlers/rebuild.py index 6ec4558e..9d181e4a 100644 --- a/src/ahriman/application/handlers/rebuild.py +++ b/src/ahriman/application/handlers/rebuild.py @@ -40,5 +40,9 @@ class Rebuild(Handler): :param configuration: configuration instance """ application = Application(architecture, configuration) - packages = application.repository.packages() + packages = [ + package + for package in application.repository.packages() + if args.depends_on is None or args.depends_on in package.depends + ] # we have to use explicit list here for testing purpose application.update(packages) diff --git a/src/ahriman/core/report/html.py b/src/ahriman/core/report/html.py index c6d9992b..10b5e718 100644 --- a/src/ahriman/core/report/html.py +++ b/src/ahriman/core/report/html.py @@ -43,6 +43,7 @@ class HTML(Report): * architecture, string * archive_size, pretty printed size, string * build_date, pretty printed datetime, string + * depends, sorted list of strings * description, string * filename, string, * groups, sorted list of strings @@ -95,6 +96,7 @@ class HTML(Report): "architecture": properties.architecture or "", "archive_size": pretty_size(properties.archive_size), "build_date": pretty_datetime(properties.build_date), + "depends": properties.depends, "description": properties.description or "", "filename": properties.filename, "groups": properties.groups, diff --git a/src/ahriman/core/repository/repository.py b/src/ahriman/core/repository/repository.py index e6c876b0..f849a4f6 100644 --- a/src/ahriman/core/repository/repository.py +++ b/src/ahriman/core/repository/repository.py @@ -53,4 +53,4 @@ class Repository(Executor, UpdateHandler): get list of files in built packages directory :return: list of filenames from the directory """ - return list(self.paths.packages.iterdir()) + return list(filter(package_like, self.paths.packages.iterdir())) diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index 17616284..cce86329 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -52,6 +52,13 @@ class Package: _check_output = check_output + @property + def depends(self) -> List[str]: + """ + :return: sum of dependencies per arch package + """ + return sorted(set(sum([package.depends for package in self.packages.values()], start=[]))) + @property def git_url(self) -> str: """ diff --git a/src/ahriman/models/package_description.py b/src/ahriman/models/package_description.py index 1a5f70d8..0944a112 100644 --- a/src/ahriman/models/package_description.py +++ b/src/ahriman/models/package_description.py @@ -32,6 +32,7 @@ class PackageDescription: :ivar architecture: package architecture :ivar archive_size: package archive size :ivar build_date: package build date + :ivar depends: package dependencies list :ivar description: package description :ivar filename: package archive name :ivar groups: package groups @@ -43,6 +44,7 @@ class PackageDescription: architecture: Optional[str] = None archive_size: Optional[int] = None build_date: Optional[int] = None + depends: List[str] = field(default_factory=list) description: Optional[str] = None filename: Optional[str] = None groups: List[str] = field(default_factory=list) @@ -69,6 +71,7 @@ class PackageDescription: architecture=package.arch, archive_size=package.size, build_date=package.builddate, + depends=package.depends, description=package.desc, filename=path.name, groups=package.groups, diff --git a/src/ahriman/web/views/index.py b/src/ahriman/web/views/index.py index e0ebac3d..2a1c07ab 100644 --- a/src/ahriman/web/views/index.py +++ b/src/ahriman/web/views/index.py @@ -36,6 +36,7 @@ class IndexView(BaseView): architecture - repository architecture, string, required packages - sorted list of packages properties, required * base, string + * depends, sorted list of strings * groups, sorted list of strings * licenses, sorted list of strings * packages, sorted list of strings @@ -61,6 +62,7 @@ class IndexView(BaseView): packages = [ { "base": package.base, + "depends": package.depends, "groups": package.groups, "licenses": package.licenses, "packages": list(sorted(package.packages)), diff --git a/tests/ahriman/application/handlers/test_handler_rebuild.py b/tests/ahriman/application/handlers/test_handler_rebuild.py index 173e09b6..45853567 100644 --- a/tests/ahriman/application/handlers/test_handler_rebuild.py +++ b/tests/ahriman/application/handlers/test_handler_rebuild.py @@ -4,12 +4,19 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Rebuild from ahriman.core.configuration import Configuration +from ahriman.models.package import Package + + +def _default_args(args: argparse.Namespace) -> argparse.Namespace: + args.depends_on = None + return args def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: """ must run command """ + args = _default_args(args) mocker.patch("pathlib.Path.mkdir") application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages") application_mock = mocker.patch("ahriman.application.application.Application.update") @@ -17,3 +24,36 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc Rebuild.run(args, "x86_64", configuration) application_packages_mock.assert_called_once() application_mock.assert_called_once() + + +def test_run_filter(args: argparse.Namespace, configuration: Configuration, + package_ahriman: Package, package_python_schedule: Package, + mocker: MockerFixture) -> None: + """ + must run command with depends filter + """ + args = _default_args(args) + args.depends_on = "python-aur" + mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.core.repository.repository.Repository.packages", + return_value=[package_ahriman, package_python_schedule]) + application_mock = mocker.patch("ahriman.application.application.Application.update") + + Rebuild.run(args, "x86_64", configuration) + application_mock.assert_called_with([package_ahriman]) + + +def test_run_without_filter(args: argparse.Namespace, configuration: Configuration, + package_ahriman: Package, package_python_schedule: Package, + mocker: MockerFixture) -> None: + """ + must run command for all packages if no filter supplied + """ + args = _default_args(args) + mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.core.repository.repository.Repository.packages", + return_value=[package_ahriman, package_python_schedule]) + application_mock = mocker.patch("ahriman.application.application.Application.update") + + Rebuild.run(args, "x86_64", configuration) + application_mock.assert_called_with([package_ahriman, package_python_schedule]) diff --git a/tests/ahriman/conftest.py b/tests/ahriman/conftest.py index d1a6da87..bed81b50 100644 --- a/tests/ahriman/conftest.py +++ b/tests/ahriman/conftest.py @@ -61,6 +61,7 @@ def package_description_ahriman() -> PackageDescription: architecture="x86_64", archive_size=4200, build_date=42, + depends=["devtools", "git", "pyalpm", "python-aur", "python-srcinfo"], description="ArcHlinux ReposItory MANager", filename="ahriman-0.12.1-1-any.pkg.tar.zst", groups=[], @@ -75,6 +76,7 @@ def package_description_python_schedule() -> PackageDescription: architecture="x86_64", archive_size=4201, build_date=421, + depends=["python"], description="Python job scheduling for humans.", filename="python-schedule-1.0.0-2-any.pkg.tar.zst", groups=[], @@ -89,6 +91,7 @@ def package_description_python2_schedule() -> PackageDescription: architecture="x86_64", archive_size=4202, build_date=422, + depends=["python2"], description="Python job scheduling for humans.", filename="python2-schedule-1.0.0-2-any.pkg.tar.zst", groups=[], diff --git a/tests/ahriman/models/conftest.py b/tests/ahriman/models/conftest.py index 504e095b..191e2505 100644 --- a/tests/ahriman/models/conftest.py +++ b/tests/ahriman/models/conftest.py @@ -42,6 +42,7 @@ def pyalpm_package_description_ahriman(package_description_ahriman: PackageDescr mock = MagicMock() type(mock).arch = PropertyMock(return_value=package_description_ahriman.architecture) type(mock).builddate = PropertyMock(return_value=package_description_ahriman.build_date) + type(mock).depends = PropertyMock(return_value=package_description_ahriman.depends) type(mock).desc = PropertyMock(return_value=package_description_ahriman.description) type(mock).groups = PropertyMock(return_value=package_description_ahriman.groups) type(mock).isize = PropertyMock(return_value=package_description_ahriman.installed_size) diff --git a/tests/ahriman/models/test_package.py b/tests/ahriman/models/test_package.py index a547a8bf..bb5276c0 100644 --- a/tests/ahriman/models/test_package.py +++ b/tests/ahriman/models/test_package.py @@ -9,6 +9,16 @@ from ahriman.models.package import Package from ahriman.models.repository_paths import RepositoryPaths +def test_depends(package_python_schedule: Package) -> None: + """ + must return combined list of dependencies + """ + assert all( + set(package_python_schedule.depends).intersection(package.depends) + for package in package_python_schedule.packages.values() + ) + + def test_git_url(package_ahriman: Package) -> None: """ must generate valid git url