diff --git a/aurweb/packages/util.py b/aurweb/packages/util.py index 4fb6cbe4..b6739c98 100644 --- a/aurweb/packages/util.py +++ b/aurweb/packages/util.py @@ -9,30 +9,35 @@ from sqlalchemy import and_, orm from aurweb import db, l10n, models, util from aurweb.models.official_provider import OFFICIAL_BASE +from aurweb.models.package import Package +from aurweb.models.package_dependency import PackageDependency from aurweb.models.relation_type import PROVIDES_ID from aurweb.redis import redis_connection from aurweb.scripts import notify from aurweb.templates import register_filter +def dep_extra_with_arch(dep: models.PackageDependency, annotation: str) -> str: + output = [annotation] + if dep.DepArch: + output.append(dep.DepArch) + return f"({', '.join(output)})" + + def dep_depends_extra(dep: models.PackageDependency) -> str: - """ A function used to produce extra text for dependency display. """ return str() def dep_makedepends_extra(dep: models.PackageDependency) -> str: - """ A function used to produce extra text for dependency display. """ - return "(make)" + return dep_extra_with_arch(dep, "make") def dep_checkdepends_extra(dep: models.PackageDependency) -> str: - """ A function used to produce extra text for dependency display. """ - return "(check)" + return dep_extra_with_arch(dep, "check") def dep_optdepends_extra(dep: models.PackageDependency) -> str: - """ A function used to produce extra text for dependency display. """ - return "(optional)" + return dep_extra_with_arch(dep, "optional") @register_filter("dep_extra") @@ -304,3 +309,11 @@ def add_comaintainers(request: Request, pkgbase: models.PackageBase, # Send out notifications. util.apply_all(notifications, lambda n: n.send()) + + +def pkg_required(pkgname: str, provides: List[str], limit: int): + targets = set(provides + [pkgname]) + query = db.query(PackageDependency).join(Package).filter( + PackageDependency.DepName.in_(targets) + ).order_by(Package.Name.asc()).limit(limit) + return query.all() diff --git a/aurweb/routers/packages.py b/aurweb/routers/packages.py index 382a096a..1ffd30a3 100644 --- a/aurweb/routers/packages.py +++ b/aurweb/routers/packages.py @@ -1,3 +1,4 @@ +from collections import defaultdict from datetime import datetime from http import HTTPStatus from typing import Any, Dict, List @@ -9,7 +10,7 @@ from sqlalchemy import and_, case import aurweb.filters import aurweb.packages.util -from aurweb import db, defaults, l10n, logging, models, util +from aurweb import config, db, defaults, l10n, logging, models, util from aurweb.auth import auth_required, creds from aurweb.exceptions import InvariantError, ValidationError from aurweb.models.package_request import ACCEPTED_ID, PENDING_ID, REJECTED_ID @@ -196,6 +197,16 @@ async def package(request: Request, name: str) -> Response: pkg = get_pkg_or_base(name, models.Package) pkgbase = pkg.PackageBase + rels = pkg.package_relations.order_by(models.PackageRelation.RelName.asc()) + rels_data = defaultdict(list) + for rel in rels: + if rel.RelTypeID == CONFLICTS_ID: + rels_data["c"].append(rel) + elif rel.RelTypeID == PROVIDES_ID: + rels_data["p"].append(rel) + elif rel.RelTypeID == REPLACES_ID: + rels_data["r"].append(rel) + # Add our base information. context = await make_single_context(request, pkgbase) context["package"] = pkg @@ -205,17 +216,14 @@ async def package(request: Request, name: str) -> Response: models.PackageSource.Source.asc()).all() # Package dependencies. - dependencies = db.query(models.PackageDependency).join( - models.Package).join(models.PackageBase).filter( - models.PackageBase.ID == pkgbase.ID) - context["dependencies"] = dependencies + max_depends = config.getint("options", "max_depends") + context["dependencies"] = pkg.package_dependencies.order_by( + models.PackageDependency.DepName.desc() + ).limit(max_depends).all() # Package requirements (other packages depend on this one). - required_by = db.query(models.PackageDependency).join( - models.Package).filter( - models.PackageDependency.DepName == pkgbase.Name).order_by( - models.Package.Name.asc()) - context["required_by"] = required_by + context["required_by"] = pkgutil.pkg_required( + pkg.Name, [p.RelName for p in rels_data.get("p", [])], max_depends) context["licenses"] = pkg.package_licenses diff --git a/templates/partials/packages/package_metadata.html b/templates/partials/packages/package_metadata.html index 9f5c8854..7f132c61 100644 --- a/templates/partials/packages/package_metadata.html +++ b/templates/partials/packages/package_metadata.html @@ -1,7 +1,7 @@
-

Dependencies ({{ dependencies.count() }})

+

Dependencies ({{ dependencies | length }})

-

Required by ({{ required_by.count() }})

+

Required by ({{ required_by | length }})

diff --git a/test/test_packages_routes.py b/test/test_packages_routes.py index 03ab5ab8..ffe05248 100644 --- a/test/test_packages_routes.py +++ b/test/test_packages_routes.py @@ -446,12 +446,12 @@ def test_package_dependencies(client: TestClient, maintainer: User, with db.begin(): dep_pkg = create_package("test-dep-1", maintainer) dep = create_package_dep(package, dep_pkg.Name) - dep.DepArch = "x86_64" # Also, create a makedepends. make_dep_pkg = create_package("test-dep-2", maintainer) make_dep = create_package_dep(package, make_dep_pkg.Name, dep_type_name="makedepends") + make_dep.DepArch = "x86_64" # And... a checkdepends! check_dep_pkg = create_package("test-dep-3", maintainer) @@ -496,13 +496,13 @@ def test_package_dependencies(client: TestClient, maintainer: User, official_dep.DepName ] pkgdeps = root.findall('.//ul[@id="pkgdepslist"]/li/a') - for i, expectation in enumerate(expected): + for i, expectation in enumerate(reversed(expected)): assert pkgdeps[i].text.strip() == expectation - # Let's make sure the DepArch was displayed for our first dep. - arch = root.findall('.//ul[@id="pkgdepslist"]/li')[0] - arch = arch.xpath('./em')[1] - assert arch.text.strip() == "(x86_64)" + # Let's make sure the DepArch was displayed for our target make dep. + arch = root.findall('.//ul[@id="pkgdepslist"]/li')[-2] + arch = arch.xpath('./em')[0] + assert arch.text.strip() == "(make, x86_64)" broken_node = root.find('.//ul[@id="pkgdepslist"]/li/span') assert broken_node.text.strip() == broken_dep.DepName