strict typing, change colors a bit, architecture depending lock

This commit is contained in:
Evgenii Alekseev 2021-03-13 16:57:58 +03:00
parent 9410c521a1
commit 4b98b21a70
12 changed files with 45 additions and 25 deletions

View File

@ -47,7 +47,11 @@
background-color: rgba(235, 235, 255, 1); background-color: rgba(235, 235, 255, 1);
} }
tr.header, tr.package:hover { tr.package:hover {
background-color: rgba(255, 255, 225, 1);
}
tr.header{
background-color: rgba(200, 200, 255, 1); background-color: rgba(200, 200, 255, 1);
} }

View File

@ -113,5 +113,5 @@ if __name__ == '__main__':
parser.print_help() parser.print_help()
exit(1) exit(1)
with Lock(args.lock, args.force): with Lock(args.lock, args.architecture, args.force):
args.fn(args) args.fn(args)

View File

@ -17,28 +17,33 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from __future__ import annotations
import os import os
from typing import Optional from types import TracebackType
from typing import Literal, Optional, Type
from ahriman.core.exceptions import DuplicateRun from ahriman.core.exceptions import DuplicateRun
class Lock: class Lock:
def __init__(self, path: Optional[str], force: bool) -> None: def __init__(self, path: Optional[str], architecture: str, force: bool) -> None:
self.path = path self.path: Optional[str] = f'{path}_{architecture}' if self.path is not None else None
self.force = force self.force = force
def __enter__(self): def __enter__(self) -> Lock:
if self.force: if self.force:
self.remove() self.remove()
self.check() self.check()
self.create() self.create()
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type: Optional[Type[Exception]], exc_val: Optional[Exception],
exc_tb: TracebackType) -> Literal[False]:
self.remove() self.remove()
return False
def check(self) -> None: def check(self) -> None:
if self.path is None: if self.path is None:

View File

@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from pyalpm import Handle from pyalpm import Handle # type: ignore
from typing import List, Set from typing import List, Set
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration

View File

@ -20,11 +20,10 @@
import jinja2 import jinja2
import os import os
from typing import Dict, Iterable from typing import Callable, Dict, Iterable
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.report.report import Report from ahriman.core.report.report import Report
from ahriman.core.util import package_like
from ahriman.models.package import Package from ahriman.models.package import Package
from ahriman.models.sign_settings import SignSettings from ahriman.models.sign_settings import SignSettings
@ -61,6 +60,7 @@ class HTML(Report):
'version': base.version 'version': base.version
} for base in packages for package, filename in base.packages.items() } for base in packages for package, filename in base.packages.items()
] ]
comparator: Callable[[Dict[str, str]], str] = lambda item: item['filename']
html = template.render( html = template.render(
architecture=self.architecture, architecture=self.architecture,
@ -68,7 +68,7 @@ class HTML(Report):
link_path=self.link_path, link_path=self.link_path,
has_package_signed=SignSettings.SignPackages in self.sign_targets, has_package_signed=SignSettings.SignPackages in self.sign_targets,
has_repo_signed=SignSettings.SignRepository in self.sign_targets, has_repo_signed=SignSettings.SignRepository in self.sign_targets,
packages= sorted(content, key=lambda item: item['filename']), packages=sorted(content, key=comparator),
pgp_key=self.pgp_key, pgp_key=self.pgp_key,
repository=self.repository) repository=self.repository)

View File

@ -56,13 +56,17 @@ class Leaf:
self.package = package self.package = package
self.dependencies: Set[str] = set() self.dependencies: Set[str] = set()
@property
def items(self) -> Iterable[str]:
return self.package.packages.keys()
def is_root(self, packages: Iterable[Leaf]) -> bool: def is_root(self, packages: Iterable[Leaf]) -> bool:
''' '''
:param packages: :param packages:
:return: true if any of packages is dependency of the leaf, false otherwise :return: true if any of packages is dependency of the leaf, false otherwise
''' '''
for leaf in packages: for leaf in packages:
if self.dependencies.intersection(leaf.package.packages.keys()): if self.dependencies.intersection(leaf.items):
return False return False
return True return True

View File

@ -24,7 +24,7 @@ from typing import Optional
def check_output(*args: str, exception: Optional[Exception], def check_output(*args: str, exception: Optional[Exception],
cwd = None, stderr: int = subprocess.STDOUT, cwd: Optional[str] = None, stderr: int = subprocess.STDOUT,
logger: Optional[Logger] = None) -> str: logger: Optional[Logger] = None) -> str:
try: try:
result = subprocess.check_output(args, cwd=cwd, stderr=stderr).decode('utf8').strip() result = subprocess.check_output(args, cwd=cwd, stderr=stderr).decode('utf8').strip()

View File

@ -19,13 +19,14 @@
# #
from __future__ import annotations from __future__ import annotations
import aur import aur # type: ignore
import os import os
import shutil import shutil
import tempfile import tempfile
from dataclasses import dataclass from dataclasses import dataclass
from srcinfo.parse import parse_srcinfo from pyalpm import vercmp # type: ignore
from srcinfo.parse import parse_srcinfo # type: ignore
from typing import Dict, List, Optional, Set, Type from typing import Dict, List, Optional, Set, Type
from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.pacman import Pacman
@ -137,5 +138,5 @@ class Package:
def is_outdated(self, remote: Package) -> bool: def is_outdated(self, remote: Package) -> bool:
remote_version = remote.actual_version() # either normal version or updated VCS remote_version = remote.actual_version() # either normal version or updated VCS
result = check_output('vercmp', self.version, remote_version, exception=None) result: int = vercmp(self.version, remote_version)
return True if int(result) < 0 else False return result < 0

View File

@ -17,15 +17,19 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from aiohttp.web import middleware, Request, Response from aiohttp.web import middleware, Request
from aiohttp.web_exceptions import HTTPClientError from aiohttp.web_exceptions import HTTPClientError
from aiohttp.web_response import StreamResponse
from logging import Logger from logging import Logger
from typing import Callable from typing import Awaitable, Callable
def exception_handler(logger: Logger) -> Callable: HandlerType = Callable[[Request], Awaitable[StreamResponse]]
def exception_handler(logger: Logger) -> Callable[[Request, HandlerType], Awaitable[StreamResponse]]:
@middleware @middleware
async def handle(request: Request, handler: Callable) -> Response: async def handle(request: Request, handler: HandlerType) -> StreamResponse:
try: try:
return await handler(request) return await handler(request)
except HTTPClientError: except HTTPClientError:

View File

@ -27,4 +27,5 @@ class BaseView(View):
@property @property
def service(self) -> Watcher: def service(self) -> Watcher:
return self.request.app['watcher'] watcher: Watcher = self.request.app['watcher']
return watcher

View File

@ -17,7 +17,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
from aiohttp_jinja2 import template import aiohttp_jinja2 # type: ignore
from typing import Any, Dict from typing import Any, Dict
import ahriman.version as version import ahriman.version as version
@ -27,7 +28,7 @@ from ahriman.web.views.base import BaseView
class IndexView(BaseView): class IndexView(BaseView):
@template("build-status.jinja2") @aiohttp_jinja2.template("build-status.jinja2") # type: ignore
async def get(self) -> Dict[str, Any]: async def get(self) -> Dict[str, Any]:
# some magic to make it jinja-friendly # some magic to make it jinja-friendly
packages = [ packages = [

View File

@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import aiohttp_jinja2 import aiohttp_jinja2 # type: ignore
import jinja2 import jinja2
import logging import logging