patch architecture list in runtime (#66)

This commit is contained in:
2022-08-09 15:18:20 +03:00
committed by GitHub
parent 9d016f51b5
commit 8befee58fe
7 changed files with 244 additions and 6 deletions

View File

@ -25,6 +25,7 @@ from typing import List, Optional
from ahriman.core.lazy_logging import LazyLogging
from ahriman.core.util import check_output, walk
from ahriman.models.package import Package
from ahriman.models.pkgbuild_patch import PkgbuildPatch
from ahriman.models.remote_source import RemoteSource
from ahriman.models.repository_paths import RepositoryPaths
@ -42,6 +43,24 @@ class Sources(LazyLogging):
_check_output = check_output
@staticmethod
def extend_architectures(sources_dir: Path, architecture: str) -> None:
"""
extend existing PKGBUILD with repository architecture
Args:
sources_dir(Path): local path to directory with source files
architecture(str): repository architecture
"""
pkgbuild_path = sources_dir / "PKGBUILD"
if not pkgbuild_path.is_file():
return
architectures = Package.supported_architectures(sources_dir)
architectures.add(architecture)
patch = PkgbuildPatch("arch", list(architectures))
patch.write(pkgbuild_path)
@staticmethod
def fetch(sources_dir: Path, remote: Optional[RemoteSource]) -> None:
"""
@ -128,10 +147,9 @@ class Sources(LazyLogging):
shutil.copytree(cache_dir, sources_dir, dirs_exist_ok=True)
instance.fetch(sources_dir, package.remote)
if patch is None:
instance.logger.info("no patches found")
return
instance.patch_apply(sources_dir, patch)
if patch is not None:
instance.patch_apply(sources_dir, patch)
instance.extend_architectures(sources_dir, paths.architecture)
@staticmethod
def patch_create(sources_dir: Path, *pattern: str) -> str:

View File

@ -267,6 +267,26 @@ class Package(LazyLogging):
packages = set(srcinfo["packages"].keys())
return (depends | makedepends) - packages
@staticmethod
def supported_architectures(path: Path) -> Set[str]:
"""
load supported architectures from package sources
Args:
path(Path): path to package sources directory
Returns:
Set[str]: list of package supported architectures
Raises:
InvalidPackageInfo: if there are parsing errors
"""
srcinfo_source = Package._check_output("makepkg", "--printsrcinfo", exception=None, cwd=path)
srcinfo, errors = parse_srcinfo(srcinfo_source)
if errors:
raise InvalidPackageInfo(errors)
return set(srcinfo.get("arch", []))
def actual_version(self, paths: RepositoryPaths) -> str:
"""
additional method to handle VCS package versions

View File

@ -0,0 +1,92 @@
#
# Copyright (c) 2021-2022 ahriman team.
#
# This file is part of ahriman
# (see https://github.com/arcan1s/ahriman).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import shlex
from dataclasses import dataclass, field
from pathlib import Path
from typing import List, Union
@dataclass(frozen=True)
class PkgbuildPatch:
"""
wrapper for patching PKBGUILDs
Attributes:
key(str): name of the property in PKGBUILD, e.g. version, url etc
value(Union[str, List[str]]): value of the stored PKGBUILD property. It must be either string or list of string
values
unsafe(bool): if set, value will be not quoted, might break PKGBUILD
"""
key: str
value: Union[str, List[str]]
unsafe: bool = field(default=False, kw_only=True)
@property
def is_function(self) -> bool:
"""
parse key and define whether it function or not
Returns:
bool: True in case if key ends with parentheses and False otherwise
"""
return self.key.endswith("()")
def quote(self, value: str) -> str:
"""
quote value according to the unsafe flag
Args:
value(str): value to be quoted
Returns:
str: quoted string in case if unsafe is False and as is otherwise
"""
return value if self.unsafe else shlex.quote(value)
def serialize(self) -> str:
"""
serialize key-value pair into PKBGBUILD string. List values will be put inside parentheses. All string
values (including the ones inside list values) will be put inside quotes, no shell variables expanding supported
at the moment
Returns:
str: serialized key-value pair, print-friendly
"""
if isinstance(self.value, list): # list like
value = " ".join(map(self.quote, self.value))
return f"""{self.key}=({value})"""
# we suppose that function values are only supported in string-like values
if self.is_function:
return f"{self.key} {self.value}" # no quoting enabled here
return f"""{self.key}={self.quote(self.value)}"""
def write(self, pkgbuild_path: Path) -> None:
"""
write serialized value into PKGBUILD by specified path
Args:
pkgbuild_path(Path): path to PKGBUILD file
"""
with pkgbuild_path.open("a") as pkgbuild:
pkgbuild.write("\n") # in case if file ends without new line we are appending it at the end
pkgbuild.write(self.serialize())
pkgbuild.write("\n") # append new line after the values