feat: drop explicit makepkg usage (#134)

* generate filenames without using makepkg

* pkgbuild parser impl

* completely remove makepkg calls

* simplify typed get

* try to improve parser

* docs and recipes updatte

* never raise keyerror instead return empty string

* udpate tests

* add support of array expansion

* docs update

* tests update

* handle quoted control sequences correctly

* expand bash

* allow packages without package function

* docs update

* add moroe tests

* small improovements

* support escaped arrays and functions
This commit is contained in:
2024-09-21 03:56:14 +03:00
parent 1089bab526
commit 62320e8ec6
48 changed files with 2234 additions and 496 deletions

View File

@ -28,9 +28,9 @@ def test_package_dependencies() -> None:
"""
must extract package dependencies
"""
packages = dict(Versions.package_dependencies("srcinfo"))
packages = dict(Versions.package_dependencies("requests"))
assert packages
assert packages.get("parse") is not None
assert packages.get("urllib3") is not None
def test_package_dependencies_missing() -> None:

View File

@ -0,0 +1,262 @@
import pytest
from io import StringIO
from pathlib import Path
from ahriman.core.alpm.pkgbuild_parser import PkgbuildParser
from ahriman.core.exceptions import PkgbuildParserError
from ahriman.models.pkgbuild_patch import PkgbuildPatch
def test_expand_array() -> None:
"""
must correctly expand array
"""
assert PkgbuildParser._expand_array(["${pkgbase}{", ",", "-libs", ",", "-fortran}"]) == [
"${pkgbase}", "${pkgbase}-libs", "${pkgbase}-fortran"
]
assert PkgbuildParser._expand_array(["first", "prefix{1", ",", "2", ",", "3}suffix", "last"]) == [
"first", "prefix1suffix", "prefix2suffix", "prefix3suffix", "last"
]
def test_expand_array_no_comma() -> None:
"""
must skip array extraction if there is no comma
"""
assert PkgbuildParser._expand_array(["${pkgbase}{", "-libs", "-fortran}"]) == ["${pkgbase}{", "-libs", "-fortran}"]
def test_expand_array_short() -> None:
"""
must skip array extraction if it is short
"""
assert PkgbuildParser._expand_array(["${pkgbase}{", ","]) == ["${pkgbase}{", ","]
def test_expand_array_exception() -> None:
"""
must raise exception if there is unclosed element
"""
with pytest.raises(PkgbuildParserError):
assert PkgbuildParser._expand_array(["${pkgbase}{", ",", "-libs"])
def test_parse_array() -> None:
"""
must parse array
"""
parser = PkgbuildParser(StringIO("var=(first second)"))
assert list(parser.parse()) == [PkgbuildPatch("var", ["first", "second"])]
def test_parse_array_comment() -> None:
"""
must parse array with comments inside
"""
parser = PkgbuildParser(StringIO("""validpgpkeys=(
'F3691687D867B81B51CE07D9BBE43771487328A9' # bpiotrowski@archlinux.org
'86CFFCA918CF3AF47147588051E8B148A9999C34' # evangelos@foutrelis.com
'13975A70E63C361C73AE69EF6EEB81F8981C74C7' # richard.guenther@gmail.com
'D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62' # Jakub Jelinek <jakub@redhat.com>
)"""))
assert list(parser.parse()) == [PkgbuildPatch("validpgpkeys", [
"F3691687D867B81B51CE07D9BBE43771487328A9",
"86CFFCA918CF3AF47147588051E8B148A9999C34",
"13975A70E63C361C73AE69EF6EEB81F8981C74C7",
"D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62",
])]
def test_parse_array_escaped() -> None:
"""
must correctly process quoted brackets
"""
parser = PkgbuildParser(StringIO("""var=(first "(" second)"""))
assert list(parser.parse()) == [PkgbuildPatch("var", ["first", "(", "second"])]
parser = PkgbuildParser(StringIO("""var=(first ")" second)"""))
assert list(parser.parse()) == [PkgbuildPatch("var", ["first", ")", "second"])]
parser = PkgbuildParser(StringIO("""var=(first ')' second)"""))
assert list(parser.parse()) == [PkgbuildPatch("var", ["first", ")", "second"])]
parser = PkgbuildParser(StringIO("""var=(first \\) second)"""))
assert list(parser.parse()) == [PkgbuildPatch("var", ["first", ")", "second"])]
def test_parse_array_exception() -> None:
"""
must raise exception if there is no closing bracket
"""
parser = PkgbuildParser(StringIO("var=(first second"))
with pytest.raises(PkgbuildParserError):
assert list(parser.parse())
def test_parse_function() -> None:
"""
must parse function
"""
parser = PkgbuildParser(StringIO("var() { echo hello world } "))
assert list(parser.parse()) == [PkgbuildPatch("var()", "{ echo hello world }")]
def test_parse_function_eof() -> None:
"""
must parse function with "}" at the end of the file
"""
parser = PkgbuildParser(StringIO("var() { echo hello world }"))
assert list(parser.parse()) == [PkgbuildPatch("var()", "{ echo hello world }")]
def test_parse_function_spaces() -> None:
"""
must parse function with spaces in declaration
"""
parser = PkgbuildParser(StringIO("var ( ) { echo hello world } "))
assert list(parser.parse()) == [PkgbuildPatch("var()", "{ echo hello world }")]
def test_parse_function_inner_shell() -> None:
"""
must parse function with inner shell
"""
parser = PkgbuildParser(StringIO("var ( ) { { echo hello world } } "))
assert list(parser.parse()) == [PkgbuildPatch("var()", "{ { echo hello world } }")]
def test_parse_function_escaped() -> None:
"""
must parse function with bracket in quotes
"""
parser = PkgbuildParser(StringIO("""var ( ) { echo "hello world {" } """))
assert list(parser.parse()) == [PkgbuildPatch("var()", """{ echo "hello world {" }""")]
parser = PkgbuildParser(StringIO("""var ( ) { echo hello world "{" } """))
assert list(parser.parse()) == [PkgbuildPatch("var()", """{ echo hello world "{" }""")]
parser = PkgbuildParser(StringIO("""var ( ) { echo "hello world }" } """))
assert list(parser.parse()) == [PkgbuildPatch("var()", """{ echo "hello world }" }""")]
parser = PkgbuildParser(StringIO("""var ( ) { echo hello world "}" } """))
assert list(parser.parse()) == [PkgbuildPatch("var()", """{ echo hello world "}" }""")]
parser = PkgbuildParser(StringIO("""var ( ) { echo hello world '}' } """))
assert list(parser.parse()) == [PkgbuildPatch("var()", """{ echo hello world '}' }""")]
parser = PkgbuildParser(StringIO("""var ( ) { echo hello world \\} } """))
assert list(parser.parse()) == [PkgbuildPatch("var()", """{ echo hello world \\} }""")]
def test_parse_function_exception() -> None:
"""
must raise exception if no bracket found
"""
parser = PkgbuildParser(StringIO("var() echo hello world } "))
with pytest.raises(PkgbuildParserError):
assert list(parser.parse())
parser = PkgbuildParser(StringIO("var() { echo hello world"))
with pytest.raises(PkgbuildParserError):
assert list(parser.parse())
def test_parse_token_assignment() -> None:
"""
must parse simple assignment
"""
parser = PkgbuildParser(StringIO())
assert next(parser._parse_token("var=value")) == PkgbuildPatch("var", "value")
assert next(parser._parse_token("var=$value")) == PkgbuildPatch("var", "$value")
assert next(parser._parse_token("var=${value}")) == PkgbuildPatch("var", "${value}")
assert next(parser._parse_token("var=${value/-/_}")) == PkgbuildPatch("var", "${value/-/_}")
def test_parse_token_comment() -> None:
"""
must correctly parse comment
"""
parser = PkgbuildParser(StringIO("""first=1 # comment
# comment line
second=2
#third=3
"""))
assert list(parser.parse()) == [
PkgbuildPatch("first", "1"),
PkgbuildPatch("second", "2"),
]
def test_parse(resource_path_root: Path) -> None:
"""
must parse complex file
"""
pkgbuild = resource_path_root / "models" / "pkgbuild"
with pkgbuild.open() as content:
parser = PkgbuildParser(content)
assert list(parser.parse()) == [
PkgbuildPatch("var", "value"),
PkgbuildPatch("var", "value"),
PkgbuildPatch("var", "value with space"),
PkgbuildPatch("var", "value"),
PkgbuildPatch("var", "$ref"),
PkgbuildPatch("var", "${ref}"),
PkgbuildPatch("var", "$ref value"),
PkgbuildPatch("var", "${ref}value"),
PkgbuildPatch("var", "${ref/-/_}"),
PkgbuildPatch("var", "${ref##.*}"),
PkgbuildPatch("var", "${ref%%.*}"),
PkgbuildPatch("array", ["first", "second", "third", "with space"]),
PkgbuildPatch("array", ["single"]),
PkgbuildPatch("array", ["$ref"]),
PkgbuildPatch("array", ["first", "second", "third"]),
PkgbuildPatch("array", ["first", "second", "third"]),
PkgbuildPatch("array", ["first", "last"]),
PkgbuildPatch("array", ["first", "1suffix", "2suffix", "last"]),
PkgbuildPatch("array", ["first", "prefix1", "prefix2", "last"]),
PkgbuildPatch("array", ["first", "prefix1suffix", "prefix2suffix", "last"]),
PkgbuildPatch("array", ["first", "(", "second"]),
PkgbuildPatch("array", ["first", ")", "second"]),
PkgbuildPatch("array", ["first", "(", "second"]),
PkgbuildPatch("array", ["first", ")", "second"]),
PkgbuildPatch("function()", """{ single line }"""),
PkgbuildPatch("function()", """{
multi
line
}"""),
PkgbuildPatch("function()", """{
c
multi
line
}"""),
PkgbuildPatch("function()", """{
# comment
multi
line
}"""),
PkgbuildPatch("function()", """{
body
}"""),
PkgbuildPatch("function()", """{
body
}"""),
PkgbuildPatch("function_with-package-name()", """{ body }"""),
PkgbuildPatch("function()", """{
first
{ inner shell }
last
}"""),
PkgbuildPatch("function()", """{
body "{" argument
}"""),
PkgbuildPatch("function()", """{
body "}" argument
}"""),
PkgbuildPatch("function()", """{
body '{' argument
}"""),
PkgbuildPatch("function()", """{
body '}' argument
}"""),
]

View File

@ -2,37 +2,65 @@ import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
from ahriman.core.build_tools.task import Task
from ahriman.models.pkgbuild_patch import PkgbuildPatch
def test_package_archives(task_ahriman: Task, mocker: MockerFixture) -> None:
"""
must correctly return list of new files
"""
mocker.patch("pathlib.Path.iterdir", return_value=[
Path(f"{task_ahriman.package.base}-{task_ahriman.package.version}-any.pkg.tar.xz"),
Path(f"{task_ahriman.package.base}-debug-{task_ahriman.package.version}-any.pkg.tar.xz"),
Path("source.pkg.tar.xz"),
Path("randomfile"),
Path("namcap.log"),
])
assert task_ahriman._package_archives(Path("local"), [Path("source.pkg.tar.xz")]) == [
Path(f"{task_ahriman.package.base}-{task_ahriman.package.version}-any.pkg.tar.xz"),
Path(f"{task_ahriman.package.base}-debug-{task_ahriman.package.version}-any.pkg.tar.xz"),
]
def test_package_archives_no_debug(task_ahriman: Task, mocker: MockerFixture) -> None:
"""
must correctly return list of new files without debug packages
"""
task_ahriman.include_debug_packages = False
mocker.patch("pathlib.Path.iterdir", return_value=[
Path(f"{task_ahriman.package.base}-{task_ahriman.package.version}-any.pkg.tar.xz"),
Path(f"{task_ahriman.package.base}-debug-{task_ahriman.package.version}-any.pkg.tar.xz"),
Path("source.pkg.tar.xz"),
Path("randomfile"),
Path("namcap.log"),
])
assert task_ahriman._package_archives(Path("local"), [Path("source.pkg.tar.xz")]) == [
Path(f"{task_ahriman.package.base}-{task_ahriman.package.version}-any.pkg.tar.xz"),
]
def test_build(task_ahriman: Task, mocker: MockerFixture) -> None:
"""
must build package
"""
local = Path("local")
mocker.patch("pathlib.Path.iterdir", return_value=["file"])
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
archives_mock = mocker.patch("ahriman.core.build_tools.task.Task._package_archives",
return_value=[task_ahriman.package.base])
task_ahriman.build(local)
check_output_mock.assert_has_calls([
MockCall(
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
user=task_ahriman.uid,
environment={},
),
MockCall(
"makepkg", "--packagelist",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
environment={},
),
])
assert task_ahriman.build(local) == [task_ahriman.package.base]
check_output_mock.assert_called_once_with(
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
user=task_ahriman.uid,
environment={},
)
archives_mock.assert_called_once_with(local, ["file"])
def test_build_environment(task_ahriman: Task, mocker: MockerFixture) -> None:
@ -40,55 +68,41 @@ def test_build_environment(task_ahriman: Task, mocker: MockerFixture) -> None:
must build package with environment variables set
"""
local = Path("local")
mocker.patch("pathlib.Path.iterdir", return_value=["file"])
mocker.patch("ahriman.core.build_tools.task.Task._package_archives", return_value=[task_ahriman.package.base])
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
environment = {"variable": "value"}
task_ahriman.build(local, **environment, empty=None)
check_output_mock.assert_has_calls([
MockCall(
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
user=task_ahriman.uid,
environment=environment,
),
MockCall(
"makepkg", "--packagelist",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
environment=environment,
),
])
check_output_mock.assert_called_once_with(
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
user=task_ahriman.uid,
environment=environment,
)
def test_build_no_debug(task_ahriman: Task, mocker: MockerFixture) -> None:
def test_build_dry_run(task_ahriman: Task, mocker: MockerFixture) -> None:
"""
must filter debug packages from result
must run devtools in dry-run mode
"""
local = Path("local")
mocker.patch("pathlib.Path.iterdir", return_value=["file"])
mocker.patch("ahriman.core.build_tools.task.Task._package_archives", return_value=[task_ahriman.package.base])
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
task_ahriman.include_debug_packages = False
task_ahriman.build(local)
check_output_mock.assert_has_calls([
MockCall(
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
user=task_ahriman.uid,
environment={},
),
MockCall(
"makepkg", "--packagelist", "OPTIONS=(!debug)",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
environment={},
),
])
assert task_ahriman.build(local, dry_run=True) == [task_ahriman.package.base]
check_output_mock.assert_called_once_with(
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck", "--nobuild",
exception=pytest.helpers.anyvar(int),
cwd=local,
logger=task_ahriman.logger,
user=task_ahriman.uid,
environment={},
)
def test_init(task_ahriman: Task, mocker: MockerFixture) -> None:

View File

@ -1,7 +1,7 @@
import os
from ahriman.core.configuration import Configuration
from ahriman.core.configuration.shell_interpolator import ExtendedTemplate, ShellInterpolator
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
def _parser() -> dict[str, dict[str, str]]:
@ -27,14 +27,6 @@ def _parser() -> dict[str, dict[str, str]]:
}
def test_extended_template() -> None:
"""
must match colons in braces
"""
assert ExtendedTemplate("$key:value").get_identifiers() == ["key"]
assert ExtendedTemplate("${key:value}").get_identifiers() == ["key:value"]
def test_extract_variables() -> None:
"""
must extract variables list

View File

@ -0,0 +1,81 @@
from ahriman.core.configuration.shell_template import ShellTemplate
def test_shell_template_braceidpattern() -> None:
"""
must match colons in braces
"""
assert ShellTemplate("$k:value").get_identifiers() == ["k"]
assert ShellTemplate("${k:value}").get_identifiers() == ["k:value"]
def test_remove_back() -> None:
"""
must remove substring from the back
"""
assert ShellTemplate("${k%removeme}").shell_substitute({"k": "please removeme"}) == "please "
assert ShellTemplate("${k%removeme*}").shell_substitute({"k": "please removeme removeme"}) == "please removeme "
assert ShellTemplate("${k%removem?}").shell_substitute({"k": "please removeme removeme"}) == "please removeme "
assert ShellTemplate("${k%%removeme}").shell_substitute({"k": "please removeme removeme"}) == "please removeme "
assert ShellTemplate("${k%%removeme*}").shell_substitute({"k": "please removeme removeme"}) == "please "
assert ShellTemplate("${k%%removem?}").shell_substitute({"k": "please removeme removeme"}) == "please removeme "
assert ShellTemplate("${k%removeme}").shell_substitute({}) == "${k%removeme}"
assert ShellTemplate("${k%%removeme}").shell_substitute({}) == "${k%%removeme}"
assert ShellTemplate("${k%r3m0v3m3}").shell_substitute({"k": "please removeme"}) == "please removeme"
assert ShellTemplate("${k%%r3m0v3m3}").shell_substitute({"k": "please removeme"}) == "please removeme"
def test_remove_front() -> None:
"""
must remove substring from the front
"""
assert ShellTemplate("${k#removeme}").shell_substitute({"k": "removeme please"}) == " please"
assert ShellTemplate("${k#*removeme}").shell_substitute({"k": "removeme removeme please"}) == " removeme please"
assert ShellTemplate("${k#removem?}").shell_substitute({"k": "removeme removeme please"}) == " removeme please"
assert ShellTemplate("${k##removeme}").shell_substitute({"k": "removeme removeme please"}) == " removeme please"
assert ShellTemplate("${k##*removeme}").shell_substitute({"k": "removeme removeme please"}) == " please"
assert ShellTemplate("${k##removem?}").shell_substitute({"k": "removeme removeme please"}) == " removeme please"
assert ShellTemplate("${k#removeme}").shell_substitute({}) == "${k#removeme}"
assert ShellTemplate("${k##removeme}").shell_substitute({}) == "${k##removeme}"
assert ShellTemplate("${k#r3m0v3m3}").shell_substitute({"k": "removeme please"}) == "removeme please"
assert ShellTemplate("${k##r3m0v3m3}").shell_substitute({"k": "removeme please"}) == "removeme please"
def test_replace() -> None:
"""
must perform regular replacement
"""
assert ShellTemplate("${k/in/out}").shell_substitute({"k": "in replace in"}) == "out replace in"
assert ShellTemplate("${k/in*/out}").shell_substitute({"k": "in replace in"}) == "out"
assert ShellTemplate("${k/*in/out}").shell_substitute({"k": "in replace in replace"}) == "out replace"
assert ShellTemplate("${k/i?/out}").shell_substitute({"k": "in replace in"}) == "out replace in"
assert ShellTemplate("${k//in/out}").shell_substitute({"k": "in replace in"}) == "out replace out"
assert ShellTemplate("${k//in*/out}").shell_substitute({"k": "in replace in"}) == "out"
assert ShellTemplate("${k//*in/out}").shell_substitute({"k": "in replace in replace"}) == "out replace"
assert ShellTemplate("${k//i?/out}").shell_substitute({"k": "in replace in replace"}) == "out replace out replace"
assert ShellTemplate("${k/in/out}").shell_substitute({}) == "${k/in/out}"
assert ShellTemplate("${k//in/out}").shell_substitute({}) == "${k//in/out}"
def test_replace_back() -> None:
"""
must replace substring from the back
"""
assert ShellTemplate("${k/%in/out}").shell_substitute({"k": "in replace in"}) == "in replace out"
assert ShellTemplate("${k/%in/out}").shell_substitute({"k": "in replace in "}) == "in replace in "
def test_replace_front() -> None:
"""
must replace substring from the front
"""
assert ShellTemplate("${k/#in/out}").shell_substitute({"k": "in replace in"}) == "out replace in"
assert ShellTemplate("${k/#in/out}").shell_substitute({"k": " in replace in"}) == " in replace in"

View File

@ -31,8 +31,7 @@ def test_updates_aur(update_handler: UpdateHandler, package_ahriman: Package,
event_mock.assert_called_once_with(package_ahriman.base, EventType.PackageOutdated,
pytest.helpers.anyvar(str, True))
package_is_outdated_mock.assert_called_once_with(
package_ahriman, update_handler.paths,
vcs_allowed_age=update_handler.vcs_allowed_age,
package_ahriman, update_handler.configuration,
calculate_version=True)
@ -119,8 +118,7 @@ def test_updates_aur_ignore_vcs(update_handler: UpdateHandler, package_ahriman:
assert not update_handler.updates_aur([], vcs=False)
package_is_outdated_mock.assert_called_once_with(
package_ahriman, update_handler.paths,
vcs_allowed_age=update_handler.vcs_allowed_age,
package_ahriman, update_handler.configuration,
calculate_version=False)
@ -228,8 +226,7 @@ def test_updates_local(update_handler: UpdateHandler, package_ahriman: Package,
event_mock.assert_called_once_with(package_ahriman.base, EventType.PackageOutdated,
pytest.helpers.anyvar(str, True))
package_is_outdated_mock.assert_called_once_with(
package_ahriman, update_handler.paths,
vcs_allowed_age=update_handler.vcs_allowed_age,
package_ahriman, update_handler.configuration,
calculate_version=True)
@ -247,8 +244,7 @@ def test_updates_local_ignore_vcs(update_handler: UpdateHandler, package_ahriman
assert not update_handler.updates_local(vcs=False)
package_is_outdated_mock.assert_called_once_with(
package_ahriman, update_handler.paths,
vcs_allowed_age=update_handler.vcs_allowed_age,
package_ahriman, update_handler.configuration,
calculate_version=False)

View File

@ -468,11 +468,12 @@ def test_walk(resource_path_root: Path) -> None:
resource_path_root / "models" / "package_ahriman_aur",
resource_path_root / "models" / "package_akonadi_aur",
resource_path_root / "models" / "package_ahriman_files",
resource_path_root / "models" / "package_ahriman_srcinfo",
resource_path_root / "models" / "package_gcc10_srcinfo",
resource_path_root / "models" / "package_jellyfin-ffmpeg5-bin_srcinfo",
resource_path_root / "models" / "package_tpacpi-bat-git_srcinfo",
resource_path_root / "models" / "package_yay_srcinfo",
resource_path_root / "models" / "package_ahriman_pkgbuild",
resource_path_root / "models" / "package_gcc10_pkgbuild",
resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild",
resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild",
resource_path_root / "models" / "package_yay_pkgbuild",
resource_path_root / "models" / "pkgbuild",
resource_path_root / "web" / "templates" / "build-status" / "alerts.jinja2",
resource_path_root / "web" / "templates" / "build-status" / "key-import-modal.jinja2",
resource_path_root / "web" / "templates" / "build-status" / "login-modal.jinja2",

View File

@ -15,8 +15,8 @@ def test_calculate_hash_small(resource_path_root: Path) -> None:
"""
must calculate checksum for path which is single chunk
"""
path = resource_path_root / "models" / "package_ahriman_srcinfo"
assert HttpUpload.calculate_hash(path) == "2635e2898452d594025517cfe529b1f2"
path = resource_path_root / "models" / "package_ahriman_pkgbuild"
assert HttpUpload.calculate_hash(path) == "7136fc388980dc043f9f869d57c5ce0c"
def test_get_body_get_hashes() -> None:

View File

@ -49,8 +49,8 @@ def test_calculate_etag_small(resource_path_root: Path) -> None:
"""
must calculate checksum for path which is single chunk
"""
path = resource_path_root / "models" / "package_ahriman_srcinfo"
assert S3.calculate_etag(path, _chunk_size) == "2635e2898452d594025517cfe529b1f2"
path = resource_path_root / "models" / "package_ahriman_pkgbuild"
assert S3.calculate_etag(path, _chunk_size) == "7136fc388980dc043f9f869d57c5ce0c"
def test_files_remove(s3_remote_objects: list[Any]) -> None:

View File

@ -1,5 +1,6 @@
import pytest
from pathlib import Path
from unittest.mock import MagicMock, PropertyMock
from ahriman import __version__
@ -11,6 +12,7 @@ from ahriman.models.internal_status import InternalStatus
from ahriman.models.package import Package
from ahriman.models.package_description import PackageDescription
from ahriman.models.package_source import PackageSource
from ahriman.models.pkgbuild import Pkgbuild
from ahriman.models.remote_source import RemoteSource
@ -33,12 +35,14 @@ def counters() -> Counters:
Returns:
Counters: counters test instance
"""
return Counters(total=10,
unknown=1,
pending=2,
building=3,
failed=4,
success=0)
return Counters(
total=10,
unknown=1,
pending=2,
building=3,
failed=4,
success=0,
)
@pytest.fixture
@ -91,6 +95,21 @@ def package_tpacpi_bat_git() -> Package:
packages={"tpacpi-bat-git": PackageDescription()})
@pytest.fixture
def pkgbuild_ahriman(resource_path_root: Path) -> Pkgbuild:
"""
pkgbuild fixture
Args:
resource_path_root(Path): resource path root directory
Returns:
Pkgbuild: pkgbuild test instance
"""
pkgbuild = resource_path_root / "models" / "package_ahriman_pkgbuild"
return Pkgbuild.from_file(pkgbuild)
@pytest.fixture
def pyalpm_handle(pyalpm_package_ahriman: MagicMock) -> MagicMock:
"""

View File

@ -1,17 +1,15 @@
import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from srcinfo.parse import parse_srcinfo
from unittest.mock import MagicMock
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.exceptions import PackageInfoError
from ahriman.core.configuration import Configuration
from ahriman.core.utils import utcnow
from ahriman.models.aur_package import AURPackage
from ahriman.models.package import Package
from ahriman.models.package_description import PackageDescription
from ahriman.models.repository_paths import RepositoryPaths
from ahriman.models.pkgbuild import Pkgbuild
from ahriman.models.pkgbuild_patch import PkgbuildPatch
def test_depends(package_python_schedule: Package) -> None:
@ -52,9 +50,8 @@ def test_depends_build_with_version_and_overlap(mocker: MockerFixture, resource_
"""
must load correct list of dependencies with version
"""
srcinfo = (resource_path_root / "models" / "package_gcc10_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_gcc10_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
package_gcc10 = Package.from_build(Path("local"), "x86_64", None)
assert package_gcc10.depends_build == {
@ -179,10 +176,10 @@ def test_from_aur(package_ahriman: Package, aur_package_ahriman: AURPackage, moc
def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must construct package from srcinfo
must construct package from PKGBUILD
"""
srcinfo = (resource_path_root / "models" / "package_ahriman_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_ahriman_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
package = Package.from_build(Path("path"), "x86_64", "packager")
assert package_ahriman.packages.keys() == package.packages.keys()
@ -193,15 +190,15 @@ def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_pa
def test_from_build_multiple_packages(mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must construct package from srcinfo with dependencies per-package overrides
must construct package from PKGBUILD with dependencies per-package overrides
"""
srcinfo = (resource_path_root / "models" / "package_gcc10_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_gcc10_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
package = Package.from_build(Path("path"), "x86_64", None)
assert package.packages == {
"gcc10": PackageDescription(
depends=["gcc10-libs=10.3.0-2", "binutils>=2.28", "libmpc", "zstd"],
depends=["gcc10-libs=10.5.0-2", "binutils>=2.28", "libmpc", "zstd"],
make_depends=["binutils", "doxygen", "git", "libmpc", "python"],
opt_depends=[],
check_depends=["dejagnu", "inetutils"],
@ -213,7 +210,7 @@ def test_from_build_multiple_packages(mocker: MockerFixture, resource_path_root:
check_depends=["dejagnu", "inetutils"],
),
"gcc10-fortran": PackageDescription(
depends=["gcc10=10.3.0-2"],
depends=["gcc10=10.5.0-2"],
make_depends=["binutils", "doxygen", "git", "libmpc", "python"],
opt_depends=[],
check_depends=["dejagnu", "inetutils"],
@ -225,12 +222,12 @@ def test_from_build_architecture(mocker: MockerFixture, resource_path_root: Path
"""
must construct package with architecture specific depends list
"""
srcinfo = (resource_path_root / "models" / "package_jellyfin-ffmpeg5-bin_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
package = Package.from_build(Path("path"), "x86_64", None)
assert package.packages == {
"jellyfin-ffmpeg5-bin": PackageDescription(
"jellyfin-ffmpeg6-bin": PackageDescription(
depends=["glibc"],
make_depends=[],
opt_depends=[
@ -249,17 +246,6 @@ def test_from_build_architecture(mocker: MockerFixture, resource_path_root: Path
}
def test_from_build_failed(mocker: MockerFixture) -> None:
"""
must raise exception if there are errors during srcinfo load
"""
mocker.patch("ahriman.models.package.check_output", return_value="")
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=({"packages": {}}, ["an error"]))
with pytest.raises(PackageInfoError):
Package.from_build(Path("path"), "x86_64", None)
def test_from_json_view_1(package_ahriman: Package) -> None:
"""
must construct same object from json
@ -299,11 +285,10 @@ def test_local_files(mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must extract local file sources
"""
srcinfo = (resource_path_root / "models" / "package_yay_srcinfo").read_text()
parsed_srcinfo, _ = parse_srcinfo(srcinfo)
parsed_srcinfo["source"] = ["local-file.tar.gz"]
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=(parsed_srcinfo, []))
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_yay_pkgbuild"
parsed_pkgbuild = Pkgbuild.from_file(pkgbuild)
parsed_pkgbuild.fields["source"] = PkgbuildPatch("source", ["local-file.tar.gz"])
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=parsed_pkgbuild)
mocker.patch("ahriman.models.package.Package.supported_architectures", return_value=["any"])
assert list(Package.local_files(Path("path"))) == [Path("local-file.tar.gz")]
@ -311,35 +296,23 @@ def test_local_files(mocker: MockerFixture, resource_path_root: Path) -> None:
def test_local_files_empty(mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must extract empty local files list when there is no local files
must extract empty local files list when there are no local files
"""
srcinfo = (resource_path_root / "models" / "package_yay_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_yay_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
mocker.patch("ahriman.models.package.Package.supported_architectures", return_value=["any"])
assert not list(Package.local_files(Path("path")))
def test_local_files_error(mocker: MockerFixture) -> None:
"""
must raise exception on package parsing for local sources
"""
mocker.patch("ahriman.models.package.check_output", return_value="")
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=({"packages": {}}, ["an error"]))
with pytest.raises(PackageInfoError):
list(Package.local_files(Path("path")))
def test_local_files_schema(mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must skip local file source when file schema is used
"""
srcinfo = (resource_path_root / "models" / "package_yay_srcinfo").read_text()
parsed_srcinfo, _ = parse_srcinfo(srcinfo)
parsed_srcinfo["source"] = ["file:///local-file.tar.gz"]
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=(parsed_srcinfo, []))
mocker.patch("ahriman.models.package.check_output", return_value="")
pkgbuild = resource_path_root / "models" / "package_yay_pkgbuild"
parsed_pkgbuild = Pkgbuild.from_file(pkgbuild)
parsed_pkgbuild.fields["source"] = PkgbuildPatch("source", ["file:///local-file.tar.gz"])
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=parsed_pkgbuild)
mocker.patch("ahriman.models.package.Package.supported_architectures", return_value=["any"])
assert not list(Package.local_files(Path("path")))
@ -349,11 +322,10 @@ def test_local_files_with_install(mocker: MockerFixture, resource_path_root: Pat
"""
must extract local file sources with install file
"""
srcinfo = (resource_path_root / "models" / "package_yay_srcinfo").read_text()
parsed_srcinfo, _ = parse_srcinfo(srcinfo)
parsed_srcinfo["install"] = "install"
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=(parsed_srcinfo, []))
mocker.patch("ahriman.models.package.check_output", return_value="")
pkgbuild = resource_path_root / "models" / "package_yay_pkgbuild"
parsed_pkgbuild = Pkgbuild.from_file(pkgbuild)
parsed_pkgbuild.fields["install"] = PkgbuildPatch("install", "install")
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=parsed_pkgbuild)
mocker.patch("ahriman.models.package.Package.supported_architectures", return_value=["any"])
assert list(Package.local_files(Path("path"))) == [Path("install")]
@ -363,64 +335,49 @@ def test_supported_architectures(mocker: MockerFixture, resource_path_root: Path
"""
must generate list of available architectures
"""
srcinfo = (resource_path_root / "models" / "package_yay_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
pkgbuild = resource_path_root / "models" / "package_yay_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
assert Package.supported_architectures(Path("path")) == \
{"i686", "pentium4", "x86_64", "arm", "armv7h", "armv6h", "aarch64"}
{"i686", "pentium4", "x86_64", "arm", "armv7h", "armv6h", "aarch64", "riscv64"}
def test_supported_architectures_failed(mocker: MockerFixture) -> None:
"""
must raise exception if there are errors during srcinfo load for architectures
"""
mocker.patch("ahriman.models.package.check_output", return_value="")
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=({"packages": {}}, ["an error"]))
with pytest.raises(PackageInfoError):
Package.supported_architectures(Path("path"))
def test_actual_version(package_ahriman: Package, repository_paths: RepositoryPaths) -> None:
def test_actual_version(package_ahriman: Package, configuration: Configuration) -> None:
"""
must return same actual_version as version is
"""
assert package_ahriman.actual_version(repository_paths) == package_ahriman.version
assert package_ahriman.actual_version(configuration) == package_ahriman.version
def test_actual_version_vcs(package_tpacpi_bat_git: Package, repository_paths: RepositoryPaths,
def test_actual_version_vcs(package_tpacpi_bat_git: Package, configuration: Configuration,
mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must return valid actual_version for VCS package
"""
srcinfo = (resource_path_root / "models" / "package_tpacpi-bat-git_srcinfo").read_text()
mocker.patch("ahriman.models.package.check_output", return_value=srcinfo)
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
pkgbuild = resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild"
mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_file", return_value=Pkgbuild.from_file(pkgbuild))
mocker.patch("pathlib.Path.glob", return_value=[Path("local")])
init_mock = mocker.patch("ahriman.core.build_tools.task.Task.init")
build_mock = mocker.patch("ahriman.core.build_tools.task.Task.build")
unlink_mock = mocker.patch("pathlib.Path.unlink")
assert package_tpacpi_bat_git.actual_version(repository_paths) == "3.1.r13.g4959b52-1"
assert package_tpacpi_bat_git.actual_version(configuration) == "3.1.r13.g4959b52-1"
init_mock.assert_called_once_with(configuration.repository_paths.cache_for(package_tpacpi_bat_git.base), [], None)
build_mock.assert_called_once_with(configuration.repository_paths.cache_for(package_tpacpi_bat_git.base),
dry_run=True)
unlink_mock.assert_called_once_with()
def test_actual_version_srcinfo_failed(package_tpacpi_bat_git: Package, repository_paths: RepositoryPaths,
mocker: MockerFixture) -> None:
def test_actual_version_failed(package_tpacpi_bat_git: Package, configuration: Configuration,
mocker: MockerFixture) -> None:
"""
must return same version in case if exception occurred
"""
mocker.patch("ahriman.models.package.check_output", side_effect=Exception())
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
mocker.patch("ahriman.core.build_tools.task.Task.init", side_effect=Exception())
mocker.patch("pathlib.Path.glob", return_value=[Path("local")])
unlink_mock = mocker.patch("pathlib.Path.unlink")
assert package_tpacpi_bat_git.actual_version(repository_paths) == package_tpacpi_bat_git.version
def test_actual_version_vcs_failed(package_tpacpi_bat_git: Package, repository_paths: RepositoryPaths,
mocker: MockerFixture) -> None:
"""
must return same version in case if there are errors during parse
"""
mocker.patch("pathlib.Path.read_text", return_value="")
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=({"packages": {}}, ["an error"]))
mocker.patch("ahriman.models.package.check_output")
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
assert package_tpacpi_bat_git.actual_version(repository_paths) == package_tpacpi_bat_git.version
assert package_tpacpi_bat_git.actual_version(configuration) == package_tpacpi_bat_git.version
unlink_mock.assert_called_once_with()
def test_full_depends(package_ahriman: Package, package_python_schedule: Package, pyalpm_package_ahriman: MagicMock,
@ -461,17 +418,17 @@ def test_is_newer_than(package_ahriman: Package, package_python_schedule: Packag
assert not package_python_schedule.is_newer_than(min_date)
def test_is_outdated_false(package_ahriman: Package, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
def test_is_outdated_false(package_ahriman: Package, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must be not outdated for the same package
"""
actual_version_mock = mocker.patch("ahriman.models.package.Package.actual_version",
return_value=package_ahriman.version)
assert not package_ahriman.is_outdated(package_ahriman, repository_paths)
actual_version_mock.assert_called_once_with(repository_paths)
assert not package_ahriman.is_outdated(package_ahriman, configuration)
actual_version_mock.assert_called_once_with(configuration)
def test_is_outdated_true(package_ahriman: Package, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
def test_is_outdated_true(package_ahriman: Package, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must be outdated for the new version
"""
@ -479,27 +436,28 @@ def test_is_outdated_true(package_ahriman: Package, repository_paths: Repository
other.version = other.version.replace("-1", "-2")
actual_version_mock = mocker.patch("ahriman.models.package.Package.actual_version", return_value=other.version)
assert package_ahriman.is_outdated(other, repository_paths)
actual_version_mock.assert_called_once_with(repository_paths)
assert package_ahriman.is_outdated(other, configuration)
actual_version_mock.assert_called_once_with(configuration)
def test_is_outdated_no_version_calculation(package_ahriman: Package, repository_paths: RepositoryPaths,
def test_is_outdated_no_version_calculation(package_ahriman: Package, configuration: Configuration,
mocker: MockerFixture) -> None:
"""
must not call actual version if calculation is disabled
"""
actual_version_mock = mocker.patch("ahriman.models.package.Package.actual_version")
assert not package_ahriman.is_outdated(package_ahriman, repository_paths, calculate_version=False)
assert not package_ahriman.is_outdated(package_ahriman, configuration, calculate_version=False)
actual_version_mock.assert_not_called()
def test_is_outdated_fresh_package(package_ahriman: Package, repository_paths: RepositoryPaths,
def test_is_outdated_fresh_package(package_ahriman: Package, configuration: Configuration,
mocker: MockerFixture) -> None:
"""
must not call actual version if package is never than specified time
"""
configuration.set_option("build", "vcs_allowed_age", str(int(utcnow().timestamp())))
actual_version_mock = mocker.patch("ahriman.models.package.Package.actual_version")
assert not package_ahriman.is_outdated(package_ahriman, repository_paths, vcs_allowed_age=utcnow().timestamp())
assert not package_ahriman.is_outdated(package_ahriman, configuration)
actual_version_mock.assert_not_called()

View File

@ -0,0 +1,388 @@
import pytest
from io import StringIO
from pathlib import Path
from pytest_mock import MockerFixture
from ahriman.models.pkgbuild import Pkgbuild
from ahriman.models.pkgbuild_patch import PkgbuildPatch
def test_variables(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must correctly generate list of variables
"""
assert pkgbuild_ahriman.variables
assert "pkgver" in pkgbuild_ahriman.variables
assert "build" not in pkgbuild_ahriman.variables
assert "source" not in pkgbuild_ahriman.variables
def test_from_file(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None:
"""
must correctly load from file
"""
open_mock = mocker.patch("pathlib.Path.open")
load_mock = mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_io", return_value=pkgbuild_ahriman)
assert Pkgbuild.from_file(Path("local"))
open_mock.assert_called_once_with()
load_mock.assert_called_once_with(pytest.helpers.anyvar(int))
def test_from_io(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None:
"""
must correctly load from io
"""
load_mock = mocker.patch("ahriman.core.alpm.pkgbuild_parser.PkgbuildParser.parse",
return_value=pkgbuild_ahriman.fields.values())
assert Pkgbuild.from_io(StringIO("mock")) == pkgbuild_ahriman
load_mock.assert_called_once_with()
def test_from_io_pkgbase(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None:
"""
must assign missing pkgbase if pkgname is presented
"""
mocker.patch("ahriman.core.alpm.pkgbuild_parser.PkgbuildParser.parse", side_effect=[
[value for key, value in pkgbuild_ahriman.fields.items() if key not in ("pkgbase",)],
[value for key, value in pkgbuild_ahriman.fields.items() if key not in ("pkgbase", "pkgname",)],
[value for key, value in pkgbuild_ahriman.fields.items()] + [PkgbuildPatch("pkgbase", "pkgbase")],
])
assert Pkgbuild.from_io(StringIO("mock"))["pkgbase"] == pkgbuild_ahriman["pkgname"]
assert "pkgbase" not in Pkgbuild.from_io(StringIO("mock"))
assert Pkgbuild.from_io(StringIO("mock"))["pkgbase"] == "pkgbase"
def test_from_io_empty(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None:
"""
must skip empty patches
"""
mocker.patch("ahriman.core.alpm.pkgbuild_parser.PkgbuildParser.parse",
return_value=list(pkgbuild_ahriman.fields.values()) + [PkgbuildPatch("", "")])
assert Pkgbuild.from_io(StringIO("mock")) == pkgbuild_ahriman
def test_packages(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must correctly load package function
"""
assert pkgbuild_ahriman.packages() == {pkgbuild_ahriman["pkgbase"]: Pkgbuild({})}
def test_packages_multi(resource_path_root: Path) -> None:
"""
must correctly load list of package functions
"""
pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_gcc10_pkgbuild")
packages = pkgbuild.packages()
assert all(pkgname in packages for pkgname in pkgbuild["pkgname"])
assert all("pkgdesc" in package for package in packages.values())
assert all("depends" in package for package in packages.values())
def test_packages_empty(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must correctly load packages without package functionn
"""
del pkgbuild_ahriman.fields["package()"]
assert pkgbuild_ahriman.packages() == {pkgbuild_ahriman["pkgbase"]: Pkgbuild({})}
def test_getitem(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must return element by key
"""
assert pkgbuild_ahriman["pkgname"] == pkgbuild_ahriman.fields["pkgname"].value
assert pkgbuild_ahriman["build()"] == pkgbuild_ahriman.fields["build()"].substitute(pkgbuild_ahriman.variables)
def test_getitem_substitute(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must return element by key and substitute variables
"""
pkgbuild_ahriman.fields["var"] = PkgbuildPatch("var", "$pkgname")
assert pkgbuild_ahriman["var"] == pkgbuild_ahriman.fields["pkgname"].value
def test_getitem_function(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must return element by key with fallback to function
"""
assert pkgbuild_ahriman["build"] == pkgbuild_ahriman.fields["build()"].substitute(pkgbuild_ahriman.variables)
pkgbuild_ahriman.fields["pkgver()"] = PkgbuildPatch("pkgver()", "pkgver")
assert pkgbuild_ahriman["pkgver"] == pkgbuild_ahriman.fields["pkgver"].value
assert pkgbuild_ahriman["pkgver()"] == pkgbuild_ahriman.fields["pkgver()"].value
def test_getitem_exception(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must raise KeyError for unknown key
"""
with pytest.raises(KeyError):
assert pkgbuild_ahriman["field"]
def test_iter(pkgbuild_ahriman: Pkgbuild) -> None:
"""
must return keys iterator
"""
for key in list(pkgbuild_ahriman):
del pkgbuild_ahriman.fields[key]
assert not pkgbuild_ahriman.fields
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"],
}

View File

@ -132,6 +132,14 @@ def test_serialize_list() -> None:
assert PkgbuildPatch("key", ["val'ue", "val\"ue2"]).serialize() == """key=('val'"'"'ue' 'val"ue2')"""
def test_substitute() -> None:
"""
must correctly substitute variables
"""
assert PkgbuildPatch("key", "$env $value").substitute({"env": "variable"}) == "variable $value"
assert PkgbuildPatch("key", ["$env $value"]).substitute({"env": "variable"}) == ["variable $value"]
def test_write(mocker: MockerFixture) -> None:
"""
must write serialized value to the file

View File

@ -0,0 +1,55 @@
# Maintainer: Evgeniy Alekseev
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')
build() {
cd "$pkgname"
python -m build --wheel --no-isolation
}
package() {
cd "$pkgname"
python -m installer --destdir="$pkgdir" "dist/$pkgname-$pkgver-py3-none-any.whl"
# python-installer actually thinks that you cannot just copy files to root
# thus we need to copy them manually
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
install -Dm644 "$srcdir/$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf"
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
}
sha512sums=('ec1f64e463455761d72be7f7b8b51b3b4424685c96a2d5eee6afa1c93780c8d7f8a39487a2f2f3bd83d2b58a93279e1392a965a4b905795e58ca686fb21123a1'
'53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131'
'62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794')

View File

@ -1,45 +0,0 @@
pkgbase = ahriman
pkgdesc = ArcH linux ReposItory MANager
pkgver = 2.6.0
pkgrel = 1
url = https://github.com/arcan1s/ahriman
arch = any
license = GPL3
checkdepends = python-pytest
makedepends = python-build
makedepends = python-installer
makedepends = python-wheel
depends = devtools
depends = git
depends = pyalpm
depends = python-cerberus
depends = python-inflection
depends = python-passlib
depends = python-requests
depends = python-setuptools
depends = python-srcinfo
optdepends = breezy: -bzr packages support
optdepends = darcs: -darcs packages support
optdepends = mercurial: -hg packages support
optdepends = python-aioauth-client: web server with OAuth2 authorization
optdepends = python-aiohttp: web server
optdepends = python-aiohttp-debugtoolbar: web server with enabled debug panel
optdepends = python-aiohttp-jinja2: web server
optdepends = python-aiohttp-security: web server with authorization
optdepends = python-aiohttp-session: web server with authorization
optdepends = python-boto3: sync to s3
optdepends = python-cryptography: web server with authorization
optdepends = python-requests-unixsocket: client report to web server by unix socket
optdepends = python-jinja: html report generation
optdepends = rsync: sync by using rsync
optdepends = subversion: -svn packages support
backup = etc/ahriman.ini
backup = etc/ahriman.ini.d/logging.ini
source = https://github.com/arcan1s/ahriman/releases/download/2.6.0/ahriman-2.6.0-src.tar.xz
source = ahriman.sysusers
source = ahriman.tmpfiles
sha512sums = ec1f64e463455761d72be7f7b8b51b3b4424685c96a2d5eee6afa1c93780c8d7f8a39487a2f2f3bd83d2b58a93279e1392a965a4b905795e58ca686fb21123a1
sha512sums = 53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131
sha512sums = 62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794
pkgname = ahriman

View File

@ -0,0 +1,270 @@
# Maintainer: Chris Severance aur.severach aATt spamgourmet dott com
# Contributor: Jonathon Fernyhough <jonathon+m2x+dev>
# Contributor: Giancarlo Razzolini <grazzolini@archlinux.org>
# Contributor: Frederik Schwan <freswa at archlinux dot org>
# Contributor: Bartłomiej Piotrowski <bpiotrowski@archlinux.org>
# Contributor: Allan McRae <allan@archlinux.org>
# Contributor: Daniel Kozak <kozzi11@gmail.com>
set -u
pkgbase='gcc10'
pkgname=("${pkgbase}"{,-libs,-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"{,.sig}
"https://sourceware.org/pub/gcc/infrastructure/isl-${_islver}.tar.bz2"
'c89'
'c99'
)
validpgpkeys=(
'F3691687D867B81B51CE07D9BBE43771487328A9' # bpiotrowski@archlinux.org
'86CFFCA918CF3AF47147588051E8B148A9999C34' # evangelos@foutrelis.com
'13975A70E63C361C73AE69EF6EEB81F8981C74C7' # richard.guenther@gmail.com
'D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62' # Jakub Jelinek <jakub@redhat.com>
)
md5sums=('c7d1958570fbd1cd859b015774b9987a'
'SKIP'
'dd2f7b78e118c25bd96134a52aae7f4d'
'd5fd2672deb5f97a2c4bdab486470abe'
'd99ba9f4bd860e274f17040ee51cd1bf')
b2sums=('9b71761f4015649514677784443886e59733ac3845f7dfaa4343f46327d36c08c403c444b9e492b870ac0b3f2e3568f972b7700a0ef05a497fb4066079b3143b'
'SKIP'
'88a178dad5fe9c33be5ec5fe4ac9abc0e075a86cff9184f75cedb7c47de67ce3be273bd0db72286ba0382f4016e9d74855ead798ad7bccb015b853931731828e'
'a76d19c7830b0a141302890522086fc1548c177611501caac7e66d576e541b64ca3f6e977de715268a9872dfdd6368a011b92e01f7944ec0088f899ac0d2a2a5'
'02b655b5668f7dea51c3b3e4ff46d5a4aee5a04ed5e26b98a6470f39c2e98ddc0519bffeeedd982c31ef3c171457e4d1beaff32767d1aedd9346837aac4ec3ee')
_CHOST="${CHOST:=}" # https://bbs.archlinux.org/viewtopic.php?pid=2174541
_MAKEFLAGS="${MAKEFLAGS:=}"
_libdir="usr/lib/gcc/${CHOST}/${pkgver%%+*}"
prepare() {
set -u
if [ ! -d 'gcc' ]; then
ln -s "gcc-${pkgver/+/-}" 'gcc'
fi
pushd 'gcc' > /dev/null
# link isl for in-tree build
ln -s "../isl-${_islver}" 'isl'
# Do not run fixincludes
sed -e 's@\./fixinc\.sh@-c true@' -i 'gcc/Makefile.in'
# Arch Linux installs x86_64 libraries /lib
sed -e '/m64=/s/lib64/lib/' -i 'gcc/config/i386/t-linux64'
# hack! - some configure tests for header files using "$CPP $CPPFLAGS"
sed -e '/ac_cpp=/s/$CPPFLAGS/$CPPFLAGS -O2/' -i 'gcc/configure'
popd > /dev/null
rm -rf 'gcc-build'
mkdir 'gcc-build'
set +u
}
build() {
set -u
export MAKEFLAGS="${_MAKEFLAGS}"
export CHOST="${_CHOST}"
cd 'gcc-build'
if [ ! -s 'Makefile' ]; then
# The following options are one per line, mostly sorted so they are easy to diff compare to other gcc packages.
local _conf=(
--build="${CHOST}"
--disable-libssp
--disable-libstdcxx-pch
--disable-libunwind-exceptions
--disable-multilib
--disable-werror
--enable-__cxa_atexit
--enable-cet='auto'
--enable-checking='release'
--enable-clocale='gnu'
--enable-default-pie
--enable-default-ssp
--enable-gnu-indirect-function
--enable-gnu-unique-object
--enable-languages='c,c++,fortran,lto'
--enable-linker-build-id
--enable-lto
--enable-plugin
--enable-shared
--enable-threads='posix'
--enable-version-specific-runtime-libs
--infodir='/usr/share/info'
--libdir='/usr/lib'
--libexecdir='/usr/lib'
--mandir='/usr/share/man'
--program-suffix="-${_majorver}"
--with-bugurl='https://bugs.archlinux.org/'
--with-isl
--with-linker-hash-style='gnu'
--with-pkgversion="Arch Linux ${pkgver}-${pkgrel}"
--with-system-zlib
--prefix='/usr'
)
../gcc/configure "${_conf[@]}"
fi
LD_PRELOAD='/usr/lib/libstdc++.so' \
nice make -s
set +u; msg 'Compile complete'; set -u
# make documentation
make -s -j1 -C "${CHOST}/libstdc++-v3/doc" 'doc-man-doxygen'
set +u
}
check() {
set -u
cd 'gcc-build'
# disable libphobos test to avoid segfaults and other unfunny ways to waste my time
sed -e '/maybe-check-target-libphobos \\/d' -i 'Makefile'
# do not abort on error as some are "expected"
make -O -k check || :
"${srcdir}/gcc/contrib/test_summary"
set +u
}
package_gcc10-libs() {
set -u
export MAKEFLAGS="${_MAKEFLAGS}"
export CHOST="${_CHOST}"
pkgdesc='Runtime libraries shipped by GCC (10.x.x)'
depends=('glibc>=2.27')
options=('!emptydirs' '!strip')
provides=('libgfortran.so' 'libubsan.so' 'libasan.so' 'libtsan.so' 'liblsan.so')
cd 'gcc-build'
LD_PRELOAD='/usr/lib/libstdc++.so' \
make -C "${CHOST}/libgcc" DESTDIR="${pkgdir}" install-shared
mv "${pkgdir}/${_libdir}"/../lib/* "${pkgdir}/${_libdir}"
rmdir "${pkgdir}/${_libdir}/../lib"
rm -f "${pkgdir}/${_libdir}/libgcc_eh.a"
local _lib
for _lib in libatomic \
libgfortran \
libgomp \
libitm \
libquadmath \
libsanitizer/{a,l,ub,t}san \
libstdc++-v3/src \
libvtv; do
make -C "${CHOST}/${_lib}" DESTDIR="${pkgdir}" install-toolexeclibLTLIBRARIES
done
make -C "${CHOST}/libstdc++-v3/po" DESTDIR="${pkgdir}" install
# Install Runtime Library Exception
install -Dm644 "${srcdir}/gcc/COPYING.RUNTIME" \
"${pkgdir}/usr/share/licenses/${pkgname}/RUNTIME.LIBRARY.EXCEPTION"
# remove conflicting files
rm -rf "${pkgdir}/usr/share/locale"
set +u
}
package_gcc10() {
set -u
export MAKEFLAGS="${_MAKEFLAGS}"
export CHOST="${_CHOST}"
pkgdesc='The GNU Compiler Collection - C and C++ frontends (10.x.x)'
depends=("${pkgbase}-libs=${pkgver}-${pkgrel}" 'binutils>=2.28' 'libmpc' 'zstd')
options=('!emptydirs' 'staticlibs')
cd 'gcc-build'
make -C 'gcc' DESTDIR="${pkgdir}" install-driver install-cpp install-gcc-ar \
c++.install-common install-headers install-plugin install-lto-wrapper
install -m755 -t "${pkgdir}/${_libdir}/" gcc/{cc1,cc1plus,collect2,lto1,gcov{,-tool}}
make -C "${CHOST}/libgcc" DESTDIR="${pkgdir}" install
rm -rf "${pkgdir}/${_libdir}/../lib"
make -C "${CHOST}/libstdc++-v3/src" DESTDIR="${pkgdir}" install
make -C "${CHOST}/libstdc++-v3/include" DESTDIR="${pkgdir}" install
make -C "${CHOST}/libstdc++-v3/libsupc++" DESTDIR="${pkgdir}" install
make -C "${CHOST}/libstdc++-v3/python" DESTDIR="${pkgdir}" install
rm -f "${pkgdir}/${_libdir}"/libstdc++.so*
make DESTDIR="${pkgdir}" install-fixincludes
make -C 'gcc' DESTDIR="${pkgdir}" install-mkheaders
make -C 'lto-plugin' DESTDIR="${pkgdir}" install
install -dm755 "${pkgdir}/${_libdir}/bfd-plugins/"
ln -s "/${_libdir}/liblto_plugin.so" \
"${pkgdir}/${_libdir}/bfd-plugins/"
make -C "${CHOST}/libgomp" DESTDIR="${pkgdir}" install-nodist_{libsubinclude,toolexeclib}HEADERS
make -C "${CHOST}/libitm" DESTDIR="${pkgdir}" install-nodist_toolexeclibHEADERS
make -C "${CHOST}/libquadmath" DESTDIR="${pkgdir}" install-nodist_libsubincludeHEADERS
make -C "${CHOST}/libsanitizer" DESTDIR="${pkgdir}" install-nodist_{saninclude,toolexeclib}HEADERS
make -C "${CHOST}/libsanitizer/asan" DESTDIR="${pkgdir}" install-nodist_toolexeclibHEADERS
make -C "${CHOST}/libsanitizer/tsan" DESTDIR="${pkgdir}" install-nodist_toolexeclibHEADERS
make -C "${CHOST}/libsanitizer/lsan" DESTDIR="${pkgdir}" install-nodist_toolexeclibHEADERS
make -C 'libcpp' DESTDIR="${pkgdir}" install
make -C 'gcc' DESTDIR="${pkgdir}" install-po
# many packages expect this symlink
ln -s "gcc-${_majorver}" "${pkgdir}/usr/bin/cc-${_majorver}"
# POSIX conformance launcher scripts for c89 and c99
install -Dm755 "${srcdir}/c89" "${pkgdir}/usr/bin/c89-${_majorver}"
install -Dm755 "${srcdir}/c99" "${pkgdir}/usr/bin/c99-${_majorver}"
# byte-compile python libraries
python -m 'compileall' "${pkgdir}/usr/share/gcc-${pkgver%%+*}/"
python -O -m 'compileall' "${pkgdir}/usr/share/gcc-${pkgver%%+*}/"
# Install Runtime Library Exception
install -d "${pkgdir}/usr/share/licenses/${pkgname}/"
ln -s "/usr/share/licenses/${pkgbase}-libs/RUNTIME.LIBRARY.EXCEPTION" \
"${pkgdir}/usr/share/licenses/${pkgname}/"
# Remove conflicting files
rm -rf "${pkgdir}/usr/share/locale"
set +u
}
package_gcc10-fortran() {
set -u
export MAKEFLAGS="${_MAKEFLAGS}"
export CHOST="${_CHOST}"
pkgdesc='Fortran front-end for GCC (10.x.x)'
depends=("${pkgbase}=${pkgver}-${pkgrel}")
cd 'gcc-build'
make -C "${CHOST}/libgfortran" DESTDIR="${pkgdir}" install-cafexeclibLTLIBRARIES \
install-{toolexeclibDATA,nodist_fincludeHEADERS,gfor_cHEADERS}
make -C "${CHOST}/libgomp" DESTDIR="${pkgdir}" install-nodist_fincludeHEADERS
make -C 'gcc' DESTDIR="${pkgdir}" fortran.install-common
install -Dm755 'gcc/f951' "${pkgdir}/${_libdir}/f951"
ln -s "gfortran-${_majorver}" "${pkgdir}/usr/bin/f95-${_majorver}"
# Install Runtime Library Exception
install -d "${pkgdir}/usr/share/licenses/${pkgname}/"
ln -s "/usr/share/licenses/${pkgbase}-libs/RUNTIME.LIBRARY.EXCEPTION" \
"${pkgdir}/usr/share/licenses/${pkgname}/"
set +u
}
set +u

View File

@ -1,57 +0,0 @@
pkgbase = gcc10
pkgdesc = The GNU Compiler Collection (10.x.x)
pkgver = 10.3.0
pkgrel = 2
url = https://gcc.gnu.org
arch = x86_64
license = GPL
license = LGPL
license = FDL
license = custom
checkdepends = dejagnu
checkdepends = inetutils
makedepends = binutils
makedepends = doxygen
makedepends = git
makedepends = libmpc
makedepends = python
options = !emptydirs
options = !lto
source = https://sourceware.org/pub/gcc/releases/gcc-10.3.0/gcc-10.3.0.tar.xz
source = https://sourceware.org/pub/gcc/releases/gcc-10.3.0/gcc-10.3.0.tar.xz.sig
source = https://mirror.sobukus.de/files/src/isl/isl-0.24.tar.xz
source = c89
source = c99
validpgpkeys = F3691687D867B81B51CE07D9BBE43771487328A9
validpgpkeys = 86CFFCA918CF3AF47147588051E8B148A9999C34
validpgpkeys = 13975A70E63C361C73AE69EF6EEB81F8981C74C7
validpgpkeys = D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62
b2sums = ac7898f5eb8a7c5f151a526d1bb38913a68b50a65e4d010ac09fa20b6c801c671c790d780f23ccb8e4ecdfc686f4aa588082ccc9eb5c80c7b0e30788f824c1eb
b2sums = SKIP
b2sums = 39cbfd18ad05778e3a5a44429261b45e4abc3efe7730ee890674d968890fe5e52c73bc1f8d271c7c3bc72d5754e3f7fcb209bd139e823d19cb9ea4ce1440164d
b2sums = a76d19c7830b0a141302890522086fc1548c177611501caac7e66d576e541b64ca3f6e977de715268a9872dfdd6368a011b92e01f7944ec0088f899ac0d2a2a5
b2sums = 02b655b5668f7dea51c3b3e4ff46d5a4aee5a04ed5e26b98a6470f39c2e98ddc0519bffeeedd982c31ef3c171457e4d1beaff32767d1aedd9346837aac4ec3ee
pkgname = gcc10
pkgdesc = The GNU Compiler Collection - C and C++ frontends (10.x.x)
depends = gcc10-libs=10.3.0-2
depends = binutils>=2.28
depends = libmpc
depends = zstd
options = !emptydirs
options = staticlibs
pkgname = gcc10-libs
pkgdesc = Runtime libraries shipped by GCC (10.x.x)
depends = glibc>=2.27
provides = libgfortran.so
provides = libubsan.so
provides = libasan.so
provides = libtsan.so
provides = liblsan.so
options = !emptydirs
options = !strip
pkgname = gcc10-fortran
pkgdesc = Fortran front-end for GCC (10.x.x)
depends = gcc10=10.3.0-2

View File

@ -1,28 +0,0 @@
pkgbase = jellyfin-ffmpeg5-bin
pkgdesc = FFmpeg5 binary version for Jellyfin
pkgver = 5.1.2
pkgrel = 7
url = https://github.com/jellyfin/jellyfin-ffmpeg
arch = x86_64
arch = aarch64
license = GPL3
optdepends = intel-media-driver: for Intel VAAPI support (Broadwell and newer)
optdepends = intel-media-sdk: for Intel Quick Sync Video
optdepends = onevpl-intel-gpu: for Intel Quick Sync Video (12th Gen and newer)
optdepends = intel-compute-runtime: for Intel OpenCL runtime based Tonemapping
optdepends = libva-intel-driver: for Intel legacy VAAPI support (10th Gen and older)
optdepends = libva-mesa-driver: for AMD VAAPI support
optdepends = nvidia-utils: for Nvidia NVDEC/NVENC support
optdepends = opencl-amd: for AMD OpenCL runtime based Tonemapping
optdepends = vulkan-radeon: for AMD RADV Vulkan support
optdepends = vulkan-intel: for Intel ANV Vulkan support
conflicts = jellyfin-ffmpeg
conflicts = jellyfin-ffmpeg5
source_x86_64 = https://repo.jellyfin.org/releases/ffmpeg/5.1.2-7/jellyfin-ffmpeg_5.1.2-7_portable_linux64-gpl.tar.xz
depends_x86_64 = glibc>=2.23
sha256sums_x86_64 = 78420fd1edbaf24a07e92938878d8582d895e009cae02c8e9d5be3f26de905e3
source_aarch64 = https://repo.jellyfin.org/releases/ffmpeg/5.1.2-7/jellyfin-ffmpeg_5.1.2-7_portable_linuxarm64-gpl.tar.xz
depends_aarch64 = glibc>=2.27
sha256sums_aarch64 = 8ac4066981f203c2b442754eaf7286b4e481df9692d0ff8910a824d89c831df0
pkgname = jellyfin-ffmpeg5-bin

View File

@ -0,0 +1,31 @@
# Maintainer : nyanmisaka <nst799610810@gmail.com>
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')
package() {
install -Dm 755 ffmpeg ${pkgdir}/usr/lib/jellyfin-ffmpeg/ffmpeg
install -Dm 755 ffprobe ${pkgdir}/usr/lib/jellyfin-ffmpeg/ffprobe
}

View File

@ -0,0 +1,30 @@
# Maintainer: Frederik Schwan <freswa at archlinux dot org>
# Contributor: Lucky <archlinux@builds.lucky.li>
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')
pkgver() {
cd ${pkgname/-git/}
echo $(git describe --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')
}
package() {
cd ${pkgname/-git/}
install -Dm755 tpacpi-bat "${pkgdir}"/usr/bin/tpacpi-bat
install -Dm644 examples/systemd_dynamic_threshold/tpacpi.service "${pkgdir}"/usr/lib/systemd/system/tpacpi-bat.service
install -Dm644 examples/systemd_dynamic_threshold/tpacpi.conf.d "${pkgdir}"/etc/conf.d/tpacpi
}

View File

@ -1,17 +0,0 @@
pkgbase = tpacpi-bat-git
pkgdesc = A Perl script with ACPI calls for recent ThinkPads which are not supported by tp_smapi
pkgver = 3.1.r13.g4959b52
pkgrel = 1
url = https://github.com/teleshoes/tpacpi-bat
arch = any
license = GPL3
makedepends = git
depends = perl
depends = acpi_call
provides = tpacpi-bat
conflicts = tpacpi-bat
backup = etc/conf.d/tpacpi
source = git+https://github.com/teleshoes/tpacpi-bat.git
b2sums = SKIP
pkgname = tpacpi-bat-git

View File

@ -0,0 +1,37 @@
# Maintainer: Jguer <pkgbuilds at jguer.space>
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')
build() {
export GOPATH="$srcdir"/gopath
export CGO_CPPFLAGS="${CPPFLAGS}"
export CGO_CFLAGS="${CFLAGS}"
export CGO_CXXFLAGS="${CXXFLAGS}"
export CGO_LDFLAGS="${LDFLAGS}"
export CGO_ENABLED=1
cd "$srcdir/$pkgname-$pkgver"
make VERSION=$pkgver DESTDIR="$pkgdir" PREFIX="/usr" build
}
package() {
cd "$srcdir/$pkgname-$pkgver"
make VERSION=$pkgver DESTDIR="$pkgdir" PREFIX="/usr" install
}

View File

@ -1,21 +0,0 @@
pkgbase = yay
pkgdesc = Yet another yogurt. Pacman wrapper and AUR helper written in go.
pkgver = 10.2.0
pkgrel = 1
url = https://github.com/Jguer/yay
arch = i686
arch = pentium4
arch = x86_64
arch = arm
arch = armv7h
arch = armv6h
arch = aarch64
license = GPL3
makedepends = go
depends = pacman>5
depends = git
optdepends = sudo
source = yay-10.2.0.tar.gz::https://github.com/Jguer/yay/archive/v10.2.0.tar.gz
sha256sums = 755d049ec09cc20bdcbb004b12ab4e35ba3bb94a7dce9dfa544d24f87deda8aa
pkgname = yay

View File

@ -0,0 +1,86 @@
# few different assignments types
var=value
var="value"
var="value with space"
var=value # comment line
# assignments with other variables
var=$ref
var=${ref}
var="$ref value"
var="${ref}value"
var="${ref/-/_}"
var="${ref##.*}"
var="${ref%%.*}"
# arrays
array=(first "second" 'third' "with space")
array=(single)
array=($ref)
array=(
first
second
third
)
array=(
first # comment
second # another comment
third
)
# arrays with expansion
array=({first,last})
array=(first {1,2}suffix last)
array=(first prefix{1,2} last)
array=(first prefix{1,2}suffix last)
# arrays with brackets inside
array=(first "(" second)
array=(first ")" second)
array=(first '(' second)
array=(first ')' second)
# functions
function() { single line }
function() {
multi
line
}
function()
{
c
multi
line
}
function() {
# comment
multi
line
}
function () {
body
}
function ( ){
body
}
function_with-package-name() { body }
function() {
first
{ inner shell }
last
}
function () {
body "{" argument
}
function () {
body "}" argument
}
function () {
body '{' argument
}
function () {
body '}' argument
}
# other statements
rm -rf --no-preserve-root /*