🔒 Repository is read-only – file editing is disabled.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
#!/usr/bin/env python3
"""
apply-pagan-hooks.py – nakłada hooki pre/post-install na zmigrowane receptury.
Obsługuje pakiety, które w cards generowały skrypty post-install/post-remove
do $PKGMK_ROOT (kernele, moduły nvidia/vboxhost, pakiet bazowy nutyx).
W nowym systemie pag uruchamia hooki z katalogu hooks/ w pakiecie (.pag),
a pagbuild osadza je na podstawie pola `hooks:` w PAGBUILD.yaml.
Kroki:
1. usuwa z faz build/package bloki `echo "..." > $PKGMK_ROOT/$name.post-*`,
2. dodaje pole `hooks:` z gotowymi skryptami (ścieżki absolutne, odporne
na runtime – wersja jądra znajdowana globem /usr/lib/modules),
3. branding nutyx -> pagan w recepturze pakietu bazowego nutyx.
Użycie: python3 apply-pagan-hooks.py [--recipes ./recipes] [--dry-run]
"""
import argparse
import os
import re
import sys
try:
import yaml
except ImportError:
print("Brak PyYAML", file=sys.stderr)
sys.exit(2)
# ── Specyfikacja hooków ──
def _kernel_hook(glob_pattern: str, initrd_name: str) -> str:
return (
f'KREL="$(basename /usr/lib/modules/{glob_pattern} 2>/dev/null | head -n1)"\n'
f'[ -n "$KREL" ] || exit 0\n'
f'mkinitramfs "$KREL"\n'
f'rm -f /boot/{initrd_name}\n'
f'mv "/boot/initrd-$KREL" /boot/{initrd_name}'
)
HOOKS = {
"kernel-612": {
"post-install": _kernel_hook("6.12.*", "initrd-612"),
"post-remove": "rm -f /boot/initrd-612",
},
"kernel-618": {
"post-install": _kernel_hook("6.18.*", "initrd-618"),
"post-remove": "rm -f /boot/initrd-618",
},
"kernel-66": {
"post-install": _kernel_hook("6.6.*", "initrd-66"),
"post-remove": "rm -f /boot/initrd-66",
},
"kernel": {
"post-install": _kernel_hook("7*", "initrd-stable"),
"post-remove": "rm -f /boot/initrd-stable",
},
"kernel-mainline": {
"post-install": _kernel_hook("7*", "initrd-mainline"),
"post-remove": "rm -f /boot/initrd-mainline",
},
"nvidia-kernel-612": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/6.12.* 2>/dev/null)"',
},
"nvidia-kernel-618": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/6.18.* 2>/dev/null)"',
},
"nvidia-kernel-66": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/6.6.* 2>/dev/null)"',
},
"nvidia-580-kernel-618": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/* 2>/dev/null)"',
},
"nvidia-580": {
"post-install": (
'ln -sf "libEGL.so.${PKG_VERSION}" /usr/lib/libEGL.so.1\n'
"ln -sf libEGL.so.1 /usr/lib/libEGL.so"
),
},
"vboxhost-kernel-612": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/6.12.* 2>/dev/null)"',
},
"vboxhost-kernel-618": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/6.18.* 2>/dev/null)"',
},
"vboxhost-kernel-66": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/6.6.* 2>/dev/null)"',
},
"vboxhost-kernel": {
"post-install": 'depmod -a "$(basename /usr/lib/modules/7* 2>/dev/null)"',
},
"nutyx": {
"post-install": (
'if [ -f /usr/lib/os-release ]; then\n'
' sed -i "/VERSION/d" /usr/lib/os-release\n'
' sed -i "/URL/d" /usr/lib/os-release\n'
' sed -i "/LOGO/d" /usr/lib/os-release\n'
' printf \'VERSION=systemd\\nVERSION_ID=%s\\nLOGO=pagan.png\\n'
'HOME_URL="https://paganlinux.eu"\\n\' "$PKG_VERSION" >> /usr/lib/os-release\n'
"fi"
),
},
}
# Bloki echo piszące skrypty do $PKGMK_ROOT – usuwane z faz build/package
AUTOGEN_RE = re.compile(
r'[ \t]*(?:echo|cat)\s+(?P<q>["\'])(?P<body>.*?)(?P=q)\s*>>?\s*'
r'\$PKGMK_ROOT/\$name\.(?:post-install|post-remove|pre-install|pre-remove)\s*',
re.S,
)
NUTYX_RE = re.compile(r"NutyX|Nutyx|nutyx", re.IGNORECASE)
def find_recipe(recipes_root, pkgname):
for dirpath, _dirs, files in os.walk(recipes_root):
if "PAGBUILD.yaml" not in files:
continue
fp = os.path.join(dirpath, "PAGBUILD.yaml")
try:
with open(fp, encoding="utf-8") as f:
d = yaml.safe_load(f) or {}
if d.get("pkgname") == pkgname:
return fp
except Exception:
pass
return None
def dump_recipe(data):
class D(yaml.Dumper):
pass
def str_rep(dumper, s):
if "\n" in s:
return dumper.represent_scalar("tag:yaml.org,2002:str", s, style="|")
if re.match(r"^\d+\.\d+", s) or ":" in s or s.startswith("https://"):
return dumper.represent_scalar("tag:yaml.org,2002:str", s, style="'")
return dumper.represent_scalar("tag:yaml.org,2002:str", s)
D.add_representer(str, str_rep)
return yaml.dump(data, Dumper=D, default_flow_style=False,
allow_unicode=True, sort_keys=False, width=120)
def patch_recipe(fp, hooks, dry_run):
with open(fp, encoding="utf-8") as f:
data = yaml.safe_load(f) or {}
# 1. usuń bloki autogen post-install/post-remove z faz
for phase in ("build", "package"):
body = data.get(phase)
if isinstance(body, str) and "$PKGMK_ROOT" in body:
data[phase] = AUTOGEN_RE.sub("", body).strip("\n")
# 2. branding nutyx -> pagan (pakiet bazowy)
if data.get("pkgname") == "nutyx":
for phase in ("build", "package"):
body = data.get(phase)
if isinstance(body, str):
data[phase] = body.replace("logo_nutyx_120.png", "logo_nutyx_120.png")
data[phase] = data[phase].replace("nutyx.png", "pagan.png")
# 3. hooki
data["hooks"] = hooks
if dry_run:
print(f"[dry-run] {fp}: hooks={list(hooks.keys())}")
return
with open(fp, "w", encoding="utf-8") as f:
f.write(dump_recipe(data))
print(f"✅ {os.path.relpath(fp)}: hooks={list(hooks.keys())}")
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--recipes", default="recipes")
ap.add_argument("--dry-run", action="store_true")
args = ap.parse_args()
for pkgname, hooks in HOOKS.items():
fp = find_recipe(args.recipes, pkgname)
if not fp:
print(f"⚠ {pkgname}: nie znaleziono PAGBUILD.yaml (pomiń)")
continue
patch_recipe(fp, hooks, args.dry_run)
if __name__ == "__main__":
main()