diff --git a/src/ahriman/core/alpm/pkgbuild_parser.py b/src/ahriman/core/alpm/pkgbuild_parser.py index 94e2be88..f88b64d7 100644 --- a/src/ahriman/core/alpm/pkgbuild_parser.py +++ b/src/ahriman/core/alpm/pkgbuild_parser.py @@ -100,7 +100,7 @@ class PkgbuildParser(shlex.shlex): self._io = stream # direct access without type casting # ignore substitution and extend bash symbols - self.wordchars += "${}#:+-@" + self.wordchars += "${}#:+-@!" # in case of default behaviour, it will ignore, for example, segment part of url outside of quotes self.commenters = "" diff --git a/src/ahriman/models/pkgbuild.py b/src/ahriman/models/pkgbuild.py index 559b0358..6c33c2e8 100644 --- a/src/ahriman/models/pkgbuild.py +++ b/src/ahriman/models/pkgbuild.py @@ -85,7 +85,7 @@ class Pkgbuild(Mapping[str, Any]): # however, pkgname is not presented is "package()" functions which we are parsing here too, # thus, in our terms, it is optional too if "pkgbase" not in fields and "pkgname" in fields: - fields["pkgbase"] = fields["pkgname"] + fields["pkgbase"] = PkgbuildPatch("pkgbase", fields["pkgname"].value) return cls({key: value for key, value in fields.items() if key}) diff --git a/tests/ahriman/models/test_pkgbuild.py b/tests/ahriman/models/test_pkgbuild.py index e77c0429..b45df6a4 100644 --- a/tests/ahriman/models/test_pkgbuild.py +++ b/tests/ahriman/models/test_pkgbuild.py @@ -140,3 +140,249 @@ def test_len(pkgbuild_ahriman: Pkgbuild) -> None: must return length of the map """ assert len(pkgbuild_ahriman) == len(pkgbuild_ahriman.fields) + + +def test_parse_ahriman(resource_path_root: Path) -> None: + """ + must parse real PKGBUILDs correctly (ahriman) + """ + pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_ahriman_pkgbuild") + values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function} + assert values == { + "pkgbase": "ahriman", + "pkgname": "ahriman", + "pkgver": "2.6.0", + "pkgrel": "1", + "pkgdesc": "ArcH linux ReposItory MANager", + "arch": ["any"], + "url": "https://github.com/arcan1s/ahriman", + "license": ["GPL3"], + "depends": [ + "devtools", + "git", + "pyalpm", + "python-cerberus", + "python-inflection", + "python-passlib", + "python-requests", + "python-setuptools", + "python-srcinfo", + ], + "makedepends": [ + "python-build", + "python-installer", + "python-wheel", + ], + "optdepends": [ + "breezy: -bzr packages support", + "darcs: -darcs packages support", + "mercurial: -hg packages support", + "python-aioauth-client: web server with OAuth2 authorization", + "python-aiohttp: web server", + "python-aiohttp-debugtoolbar: web server with enabled debug panel", + "python-aiohttp-jinja2: web server", + "python-aiohttp-security: web server with authorization", + "python-aiohttp-session: web server with authorization", + "python-boto3: sync to s3", + "python-cryptography: web server with authorization", + "python-requests-unixsocket: client report to web server by unix socket", + "python-jinja: html report generation", + "rsync: sync by using rsync", + "subversion: -svn packages support", + ], + "source": [ + "https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgname-$pkgver-src.tar.xz", + "ahriman.sysusers", + "ahriman.tmpfiles", + ], + "backup": [ + "etc/ahriman.ini", + "etc/ahriman.ini.d/logging.ini", + ], + "sha512sums": [ + "ec1f64e463455761d72be7f7b8b51b3b4424685c96a2d5eee6afa1c93780c8d7f8a39487a2f2f3bd83d2b58a93279e1392a965a4b905795e58ca686fb21123a1", + "53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131", + "62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794", + ], + } + + +def test_parse_gcc10(resource_path_root: Path) -> None: + """ + must parse real PKGBUILDs correctly (gcc10) + """ + pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_gcc10_pkgbuild") + values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function} + assert values == { + "pkgbase": "gcc10", + "pkgname": [ + "${pkgbase}", + "${pkgbase}-libs", + "${pkgbase}-fortran", + ], + "pkgver": "10.5.0", + "_majorver": "${pkgver%%.*}", + "_islver": "0.24", + "pkgrel": "2", + "pkgdesc": "The GNU Compiler Collection (10.x.x)", + "arch": ["x86_64"], + "url": "https://gcc.gnu.org", + "license": [ + "GPL-3.0-or-later", + "LGPL-3.0+", + "GFDL-1.3", + "LicenseRef-custom", + ], + "makedepends": [ + "binutils", + "doxygen", + "git", + "libmpc", + "python", + ], + "checkdepends": [ + "dejagnu", + "inetutils", + ], + "options": [ + "!emptydirs", + "!lto", + "!buildflags", + ], + "source": [ + "https://sourceware.org/pub/gcc/releases/gcc-${pkgver}/gcc-${pkgver}.tar.xz", + "https://sourceware.org/pub/gcc/releases/gcc-${pkgver}/gcc-${pkgver}.tar.xz.sig", + "https://sourceware.org/pub/gcc/infrastructure/isl-${_islver}.tar.bz2", + "c89", + "c99", + ], + "validpgpkeys": [ + "F3691687D867B81B51CE07D9BBE43771487328A9", + "86CFFCA918CF3AF47147588051E8B148A9999C34", + "13975A70E63C361C73AE69EF6EEB81F8981C74C7", + "D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62", + ], + "md5sums": [ + "c7d1958570fbd1cd859b015774b9987a", + "SKIP", + "dd2f7b78e118c25bd96134a52aae7f4d", + "d5fd2672deb5f97a2c4bdab486470abe", + "d99ba9f4bd860e274f17040ee51cd1bf", + ], + "b2sums": [ + "9b71761f4015649514677784443886e59733ac3845f7dfaa4343f46327d36c08c403c444b9e492b870ac0b3f2e3568f972b7700a0ef05a497fb4066079b3143b", + "SKIP", + "88a178dad5fe9c33be5ec5fe4ac9abc0e075a86cff9184f75cedb7c47de67ce3be273bd0db72286ba0382f4016e9d74855ead798ad7bccb015b853931731828e", + "a76d19c7830b0a141302890522086fc1548c177611501caac7e66d576e541b64ca3f6e977de715268a9872dfdd6368a011b92e01f7944ec0088f899ac0d2a2a5", + "02b655b5668f7dea51c3b3e4ff46d5a4aee5a04ed5e26b98a6470f39c2e98ddc0519bffeeedd982c31ef3c171457e4d1beaff32767d1aedd9346837aac4ec3ee", + ], + "_CHOST": "${CHOST:=}", + "_MAKEFLAGS": "${MAKEFLAGS:=}", + "_libdir": "usr/lib/gcc/${CHOST}/${pkgver%%+*}", + } + + +def test_parse_jellyfin_ffmpeg6_bin(resource_path_root: Path) -> None: + """ + must parse real PKGBUILDs correctly (jellyfin-ffmpeg6-bin) + """ + pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild") + values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function} + assert values == { + "pkgbase": "jellyfin-ffmpeg6-bin", + "pkgname": "jellyfin-ffmpeg6-bin", + "pkgver": "6.0", + "pkgrel": "6", + "pkgdesc": "FFmpeg6 binary version for Jellyfin", + "arch": ["x86_64", "aarch64"], + "url": "https://github.com/jellyfin/jellyfin-ffmpeg", + "license": ["GPL3"], + "depends_x86_64": ["glibc>=2.23"], + "depends_aarch64": ["glibc>=2.27"], + "optdepends": [ + "intel-media-driver: for Intel VAAPI support (Broadwell and newer)", + "intel-media-sdk: for Intel Quick Sync Video", + "onevpl-intel-gpu: for Intel Quick Sync Video (12th Gen and newer)", + "intel-compute-runtime: for Intel OpenCL runtime based Tonemapping", + "libva-intel-driver: for Intel legacy VAAPI support (10th Gen and older)", + "libva-mesa-driver: for AMD VAAPI support", + "nvidia-utils: for Nvidia NVDEC/NVENC support", + "opencl-amd: for AMD OpenCL runtime based Tonemapping", + "vulkan-radeon: for AMD RADV Vulkan support", + "vulkan-intel: for Intel ANV Vulkan support", + ], + "conflicts": [ + "jellyfin-ffmpeg", + "jellyfin-ffmpeg5", + "jellyfin-ffmpeg5-bin", + "jellyfin-ffmpeg6", + ], + "source_x86_64": ["https://repo.jellyfin.org/releases/ffmpeg/${pkgver}-${pkgrel}/jellyfin-ffmpeg_${pkgver}-${pkgrel}_portable_linux64-gpl.tar.xz"], + "source_aarch64": ["https://repo.jellyfin.org/releases/ffmpeg/${pkgver}-${pkgrel}/jellyfin-ffmpeg_${pkgver}-${pkgrel}_portable_linuxarm64-gpl.tar.xz"], + "sha256sums_x86_64": ["32cbe40942d26072faa1182835ccc89029883766de11778c731b529aa632ff37"], + "sha256sums_aarch64": ["22b8f2a3c92c6b1c9e6830a6631f08f3f0a7ae80739ace71ad30704a28045184"], + } + + +def test_parse_tpacpi_bat_git(resource_path_root: Path) -> None: + """ + must parse real PKGBUILDs correctly (tpacpi-bat-git) + """ + pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild") + values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function} + assert values == { + "pkgbase": "tpacpi-bat-git", + "pkgname": "tpacpi-bat-git", + "pkgver": "3.1.r13.g4959b52", + "pkgrel": "1", + "pkgdesc": "A Perl script with ACPI calls for recent ThinkPads which are not supported by tp_smapi", + "arch": ["any"], + "url": "https://github.com/teleshoes/tpacpi-bat", + "license": ["GPL3"], + "depends": ["perl", "acpi_call"], + "makedepends": ["git"], + "provides": ["tpacpi-bat"], + "conflicts": ["tpacpi-bat"], + "backup": ["etc/conf.d/tpacpi"], + "source": ["git+https://github.com/teleshoes/tpacpi-bat.git"], + "b2sums": ["SKIP"], + } + + +def test_parse_yay(resource_path_root: Path) -> None: + """ + must parse real PKGBUILDs correctly (yay) + """ + pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_yay_pkgbuild") + values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function} + assert values == { + "pkgbase": "yay", + "pkgname": "yay", + "pkgver": "12.3.5", + "pkgrel": "1", + "pkgdesc": "Yet another yogurt. Pacman wrapper and AUR helper written in go.", + "arch": [ + "i686", + "pentium4", + "x86_64", + "arm", + "armv7h", + "armv6h", + "aarch64", + "riscv64", + ], + "url": "https://github.com/Jguer/yay", + "options": ["!lto"], + "license": ["GPL-3.0-or-later"], + "depends": [ + "pacman>6.1", + "git", + ], + "optdepends": [ + "sudo: privilege elevation", + "doas: privilege elevation", + ], + "makedepends": ["go>=1.21"], + "source": ["${pkgname}-${pkgver}.tar.gz::https://github.com/Jguer/yay/archive/v${pkgver}.tar.gz"], + "sha256sums": ["2fb6121a6eb4c5e6afaf22212b2ed15022500a4bc34bb3dc0f9782c1d43c3962"], + }