From be7a96076e47f372f853f66f35d739a46f1b9dba Mon Sep 17 00:00:00 2001 From: Kevin Morris Date: Thu, 30 Dec 2021 19:11:21 -0800 Subject: [PATCH] fix: handle broken packages which have valid provides Closes #226 Signed-off-by: Kevin Morris --- aurweb/models/package_dependency.py | 25 +++++++++++++++++ aurweb/packages/util.py | 28 ++++++------------- .../partials/packages/package_metadata.html | 24 +++++++++++----- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/aurweb/models/package_dependency.py b/aurweb/models/package_dependency.py index c4c5f6c1..44d9c839 100644 --- a/aurweb/models/package_dependency.py +++ b/aurweb/models/package_dependency.py @@ -1,3 +1,6 @@ +from typing import List + +from sqlalchemy import and_, literal from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import backref, relationship @@ -6,6 +9,7 @@ from aurweb.models.declarative import Base from aurweb.models.dependency_type import DependencyType as _DependencyType from aurweb.models.official_provider import OfficialProvider as _OfficialProvider from aurweb.models.package import Package as _Package +from aurweb.models.package_relation import PackageRelation class PackageDependency(Base): @@ -51,3 +55,24 @@ class PackageDependency(Base): official = db.query(_OfficialProvider).filter( _OfficialProvider.Name == self.DepName).exists() return db.query(pkg).scalar() or db.query(official).scalar() + + def provides(self) -> List[PackageRelation]: + from aurweb.models.relation_type import PROVIDES_ID + + rels = db.query(PackageRelation).join(_Package).filter( + and_(PackageRelation.RelTypeID == PROVIDES_ID, + PackageRelation.RelName == self.DepName) + ).with_entities( + _Package.Name, + literal(False).label("is_official") + ).order_by(_Package.Name.asc()) + + official_rels = db.query(_OfficialProvider).filter( + and_(_OfficialProvider.Provides == self.DepName, + _OfficialProvider.Name != self.DepName) + ).with_entities( + _OfficialProvider.Name, + literal(True).label("is_official") + ).order_by(_OfficialProvider.Name.asc()) + + return rels.union(official_rels).all() diff --git a/aurweb/packages/util.py b/aurweb/packages/util.py index 9a7b48d9..53af4446 100644 --- a/aurweb/packages/util.py +++ b/aurweb/packages/util.py @@ -5,18 +5,20 @@ from typing import Dict, List, Union import orjson from fastapi import HTTPException, Request -from sqlalchemy import and_, orm +from sqlalchemy import orm from aurweb import db, l10n, models, util from aurweb.models import Package, PackageBase, User from aurweb.models.official_provider import OFFICIAL_BASE, OfficialProvider from aurweb.models.package_comaintainer import PackageComaintainer from aurweb.models.package_dependency import PackageDependency -from aurweb.models.relation_type import PROVIDES_ID +from aurweb.models.package_relation import PackageRelation from aurweb.redis import redis_connection from aurweb.scripts import notify from aurweb.templates import register_filter +Providers = List[Union[PackageRelation, OfficialProvider]] + def dep_extra_with_arch(dep: models.PackageDependency, annotation: str) -> str: output = [annotation] @@ -77,27 +79,13 @@ def package_link(package: Union[Package, OfficialProvider]) -> str: return f"/packages/{package.Name}" -@register_filter("provides_list") -def provides_list(package: models.Package, depname: str) -> list: - providers = db.query(models.Package).join( - models.PackageRelation).join(models.RelationType).filter( - and_( - models.PackageRelation.RelName == depname, - models.RelationType.ID == PROVIDES_ID - ) - ) - - string = ", ".join([ +@register_filter("provides_markup") +def provides_markup(provides: Providers) -> str: + return ", ".join([ f'{pkg.Name}' - for pkg in providers + for pkg in provides ]) - if string: - # If we actually constructed a string, wrap it. - string = f"({string})" - - return string - def get_pkg_or_base( name: str, diff --git a/templates/partials/packages/package_metadata.html b/templates/partials/packages/package_metadata.html index 7f132c61..5f831711 100644 --- a/templates/partials/packages/package_metadata.html +++ b/templates/partials/packages/package_metadata.html @@ -1,23 +1,33 @@
-

Dependencies ({{ dependencies | length }})

+

{{ "Dependencies" | tr }} ({{ dependencies | length }})

    {% for dep in dependencies %} + {# Collect provides for `dep`. #} + {% set provides = dep.provides() %}
  • {% set broken = not dep.is_package() %} {% if broken %} - + {% if not provides %} + + {% endif %} {% else %} {% endif %} {{ dep.DepName }} {% if broken %} - + {% if not provides %} + + {% endif %} {% else %} {% endif %} - {{ dep.Package | provides_list(dep.DepName) | safe }} - {# If this dependency type is an optdepends (id: 4). #} + + {% if provides %} + ({{ provides | provides_markup | safe }}) + {% endif %} + {% if dep.DepTypeID == 4 %} + {# If this dependency type is an optdepends (id: 4). #} {{ dep | dep_extra_desc }} {% else %} {{ dep | dep_extra }} @@ -28,7 +38,7 @@
-

Required by ({{ required_by | length }})

+

{{ "Required by" | tr }} ({{ required_by | length }})

    {% for dep in required_by %}
  • @@ -49,7 +59,7 @@
-

Sources ({{ sources | length }})

+

{{ "Sources" | tr }} ({{ sources | length }})