diff --git a/package/archlinux/PKGBUILD b/package/archlinux/PKGBUILD
index 9d2c8ccd..f80beb08 100644
--- a/package/archlinux/PKGBUILD
+++ b/package/archlinux/PKGBUILD
@@ -23,7 +23,7 @@ optdepends=('aws-cli: sync to s3'
source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgname-$pkgver-src.tar.xz"
'ahriman.sysusers'
'ahriman.tmpfiles')
-sha512sums=('ef3c5bf73f95a87f226bc7ca90cee990abf8e7d7dacf56ce5ab346e689019a414a1ffe186a38c75bbf2c9fcc7e04822455e704c67fe2e125c5883dee8066f4bc'
+sha512sums=('70b2fd83859bdab15037137bf79a599116e52ddf901a401f0a7650f0009770f060e11936f8dd8e57800cd14f1a734ecfd31cde56456506896f7093fd7309034f'
'13718afec2c6786a18f0b223ef8e58dccf0688bca4cdbe203f14071f5031ed20120eb0ce38b52c76cfd6e8b6581a9c9eaa2743eb11abbaca637451a84c33f075'
'55b20f6da3d66e7bbf2add5d95a3b60632df121717d25a993e56e737d14f51fe063eb6f1b38bd81cc32e05db01c0c1d80aaa720c45cde87f238d8b46cdb8cbc4')
backup=('etc/ahriman.ini'
diff --git a/package/share/ahriman/build-status.jinja2 b/package/share/ahriman/build-status.jinja2
index e06d8269..1f372597 100644
--- a/package/share/ahriman/build-status.jinja2
+++ b/package/share/ahriman/build-status.jinja2
@@ -3,118 +3,20 @@
{{ repository|e }}
-
-
-
-
+ {% include "style.jinja2" %}
+ {% include "sorttable.jinja2" %}
+ {% include "search.jinja2" %}
ahriman {{ version|e }}
-
+ {% include "search-line.jinja2" %}
-
+
- {{ package.base|e }} |
+ {{ package.base|e }} |
{{ package.packages|join(" "|safe) }} |
{{ package.version|e }} |
{{ architecture|e }} |
diff --git a/package/share/ahriman/repo-index.jinja2 b/package/share/ahriman/repo-index.jinja2
index 38879212..952bf78d 100644
--- a/package/share/ahriman/repo-index.jinja2
+++ b/package/share/ahriman/repo-index.jinja2
@@ -2,31 +2,53 @@
{{ repository|e }}
+
+ {% include "style.jinja2" %}
+
+ {% include "sorttable.jinja2" %}
+ {% include "search.jinja2" %}
- Archlinux custom repository
+
+
Archlinux user repository
- {% if pgp_key is not none %}
-
This repository is signed with {{ pgp_key|e }}.
- {% endif %}
+
+ {% if pgp_key is not none %}
+ This repository is signed with {{ pgp_key|e }} by default.
+ {% endif %}
-
- $ cat /etc/pacman.conf
- [{{ repository|e }}]
- Server = {{ link_path|e }}
- SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly
-
+
+ $ cat /etc/pacman.conf
+ [{{ repository|e }}]
+ Server = {{ link_path|e }}
+ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly
+
+
-
Packages:
-
- {% for package, package_url in packages.items() %}
- - {{ package|e }}
- {% endfor %}
-
+ {% include "search-line.jinja2" %}
- {% if homepage is not none %}
-
- {% endif %}
+
+
+
+
+ {% for package in packages %}
+
+ {{ package.name|e }} |
+ {{ package.version|e }} |
+ {{ architecture|e }} |
+
+ {% endfor %}
+
+
+
+ {% if homepage is not none %}
+
+ {% endif %}
+
diff --git a/package/share/ahriman/search-line.jinja2 b/package/share/ahriman/search-line.jinja2
new file mode 100644
index 00000000..cb685672
--- /dev/null
+++ b/package/share/ahriman/search-line.jinja2
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/package/share/ahriman/search.jinja2 b/package/share/ahriman/search.jinja2
new file mode 100644
index 00000000..a1c80092
--- /dev/null
+++ b/package/share/ahriman/search.jinja2
@@ -0,0 +1,25 @@
+
\ No newline at end of file
diff --git a/package/share/ahriman/sorttable.jinja2 b/package/share/ahriman/sorttable.jinja2
new file mode 100644
index 00000000..12a1f08a
--- /dev/null
+++ b/package/share/ahriman/sorttable.jinja2
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/package/share/ahriman/style.jinja2 b/package/share/ahriman/style.jinja2
new file mode 100644
index 00000000..59e8cda3
--- /dev/null
+++ b/package/share/ahriman/style.jinja2
@@ -0,0 +1,74 @@
+
\ No newline at end of file
diff --git a/setup.py b/setup.py
index b385890c..8d45c432 100644
--- a/setup.py
+++ b/setup.py
@@ -57,6 +57,10 @@ setup(
('share/ahriman', [
'package/share/ahriman/build-status.jinja2',
'package/share/ahriman/repo-index.jinja2',
+ 'package/share/ahriman/search.jinja2',
+ 'package/share/ahriman/search-line.jinja2',
+ 'package/share/ahriman/sorttable.jinja2',
+ 'package/share/ahriman/style.jinja2',
]),
],
diff --git a/src/ahriman/application/application.py b/src/ahriman/application/application.py
index 0109cff3..7f808639 100644
--- a/src/ahriman/application/application.py
+++ b/src/ahriman/application/application.py
@@ -47,10 +47,10 @@ class Application:
return cls(args.architecture, config)
def _known_packages(self) -> Set[str]:
- known_packages = set()
+ known_packages: Set[str] = set()
# local set
for package in self.repository.packages():
- known_packages.update(package.packages)
+ known_packages.update(package.packages.keys())
known_packages.update(self.repository.pacman.all_packages())
return known_packages
diff --git a/src/ahriman/core/report/html.py b/src/ahriman/core/report/html.py
index 3cc6bc88..9d98b443 100644
--- a/src/ahriman/core/report/html.py
+++ b/src/ahriman/core/report/html.py
@@ -20,11 +20,12 @@
import jinja2
import os
-from typing import Dict
+from typing import Dict, Iterable
from ahriman.core.configuration import Configuration
from ahriman.core.report.report import Report
from ahriman.core.util import package_like
+from ahriman.models.package import Package
from ahriman.models.sign_settings import SignSettings
@@ -32,37 +33,42 @@ class HTML(Report):
def __init__(self, architecture: str, config: Configuration) -> None:
Report.__init__(self, architecture, config)
+ self.architecture = architecture
section = config.get_section_name('html', architecture)
self.report_path = config.get(section, 'path')
-
self.link_path = config.get(section, 'link_path')
self.template_path = config.get(section, 'template_path')
# base template vars
- self.sign_targets = [SignSettings.from_option(opt) for opt in config.getlist('sign', 'target')]
- self.pgp_key = config.get('sign', 'key', fallback=None)
self.homepage = config.get(section, 'homepage', fallback=None)
self.repository = config.get('repository', 'name')
- def generate(self, path: str) -> None:
+ sign_section = config.get_section_name('sign', architecture)
+ self.sign_targets = [SignSettings.from_option(opt) for opt in config.getlist(sign_section, 'target')]
+ self.pgp_key = config.get(sign_section, 'key') if self.sign_targets else None
+
+ def generate(self, packages: Iterable[Package]) -> None:
# idea comes from https://stackoverflow.com/a/38642558
templates_dir, template_name = os.path.split(self.template_path)
loader = jinja2.FileSystemLoader(searchpath=templates_dir)
environment = jinja2.Environment(loader=loader)
template = environment.get_template(template_name)
- packages: Dict[str, str] = {}
- for fn in sorted(os.listdir(path)):
- if not package_like(fn):
- continue
- packages[fn] = f'{self.link_path}/{fn}'
+ content = [
+ {
+ 'filename': filename,
+ 'name': package,
+ 'version': base.version
+ } for base in packages for package, filename in base.packages.items()
+ ]
html = template.render(
+ architecture=self.architecture,
homepage=self.homepage,
link_path=self.link_path,
has_package_signed=SignSettings.SignPackages in self.sign_targets,
has_repo_signed=SignSettings.SignRepository in self.sign_targets,
- packages=packages,
+ packages=content,
pgp_key=self.pgp_key,
repository=self.repository)
diff --git a/src/ahriman/core/report/report.py b/src/ahriman/core/report/report.py
index 47e3f92a..46716364 100644
--- a/src/ahriman/core/report/report.py
+++ b/src/ahriman/core/report/report.py
@@ -19,8 +19,11 @@
#
import logging
+from typing import Iterable
+
from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import ReportFailed
+from ahriman.models.package import Package
from ahriman.models.report_settings import ReportSettings
@@ -32,7 +35,7 @@ class Report:
self.config = config
@staticmethod
- def run(architecture: str, config: Configuration, target: str, path: str) -> None:
+ def run(architecture: str, config: Configuration, target: str, packages: Iterable[Package]) -> None:
provider = ReportSettings.from_option(target)
if provider == ReportSettings.HTML:
from ahriman.core.report.html import HTML
@@ -41,10 +44,10 @@ class Report:
report = Report(architecture, config)
try:
- report.generate(path)
+ report.generate(packages)
except Exception:
report.logger.exception('report generation failed', exc_info=True)
raise ReportFailed()
- def generate(self, path: str) -> None:
+ def generate(self, packages: Iterable[Package]) -> None:
pass
\ No newline at end of file
diff --git a/src/ahriman/core/repository.py b/src/ahriman/core/repository.py
index ee92d981..1f7f3baf 100644
--- a/src/ahriman/core/repository.py
+++ b/src/ahriman/core/repository.py
@@ -114,11 +114,12 @@ class Repository:
except Exception:
self.logger.exception(f'could not remove {package}', exc_info=True)
+ requested = set(packages)
for local in self.packages():
if local.base in packages:
- to_remove = local.packages
- elif local.packages.intersection(packages):
- to_remove = local.packages.intersection(packages)
+ to_remove = set(local.packages.keys())
+ elif requested.intersection(local.packages.keys()):
+ to_remove = requested.intersection(local.packages.keys())
else:
to_remove = set()
self.web.remove(local.base, to_remove)
@@ -131,7 +132,7 @@ class Repository:
if targets is None:
targets = self.config.getlist('report', 'target')
for target in targets:
- Report.run(self.architecture, self.config, target, self.paths.repository)
+ Report.run(self.architecture, self.config, target, self.packages())
def process_sync(self, targets: Optional[Iterable[str]]) -> None:
if targets is None:
diff --git a/src/ahriman/core/tree.py b/src/ahriman/core/tree.py
index e09bf748..7b573c93 100644
--- a/src/ahriman/core/tree.py
+++ b/src/ahriman/core/tree.py
@@ -61,8 +61,8 @@ class Leaf:
:param packages:
:return: true if any of packages is dependency of the leaf, false otherwise
'''
- for package in packages:
- if package.package.packages.intersection(self.dependencies):
+ for leaf in packages:
+ if self.dependencies.intersection(leaf.package.packages.keys()):
return False
return True
diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py
index 76b0483e..6b1a3123 100644
--- a/src/ahriman/models/package.py
+++ b/src/ahriman/models/package.py
@@ -24,9 +24,9 @@ import os
import shutil
import tempfile
-from dataclasses import dataclass, field
+from dataclasses import dataclass
from srcinfo.parse import parse_srcinfo
-from typing import List, Optional, Set, Type
+from typing import Dict, List, Optional, Set, Type
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.exceptions import InvalidPackageInfo
@@ -38,7 +38,7 @@ class Package:
base: str
version: str
aur_url: str
- packages: Set[str] = field(default_factory=set)
+ packages: Dict[str, str] # map of package name to archive name
@property
def git_url(self) -> str:
@@ -82,12 +82,12 @@ class Package:
@classmethod
def from_archive(cls: Type[Package], path: str, pacman: Pacman, aur_url: str) -> Package:
package = pacman.handle.load_pkg(path)
- return cls(package.base, package.version, aur_url, {package.name})
+ return cls(package.base, package.version, aur_url, {package.name: os.path.basename(path)})
@classmethod
def from_aur(cls: Type[Package], name: str, aur_url: str)-> Package:
package = aur.info(name)
- return cls(package.package_base, package.version, aur_url, {package.name})
+ return cls(package.package_base, package.version, aur_url, {package.name: ''})
@classmethod
def from_build(cls: Type[Package], path: str, aur_url: str) -> Package:
@@ -95,7 +95,7 @@ class Package:
src_info, errors = parse_srcinfo(fn.read())
if errors:
raise InvalidPackageInfo(errors)
- packages = set(src_info['packages'].keys())
+ packages = {key: '' for key in src_info['packages'].keys()}
version = cls.full_version(src_info.get('epoch'), src_info['pkgver'], src_info['pkgrel'])
return cls(src_info['pkgbase'], version, aur_url, packages)