#!/usr/bin/env python3
def pkgbuild_ver():
for line in open("PKGBUILD", "r"):
if line.startswith("pkgver="):
return line[7:].strip()
def pkgbuild_new_ver(ver, sha256sum=None, rel="1", sumtype="sha256", sum=None):
import os
sumpfx = sumtype + "sums=("
if sha256sum:
sum = sha256sum
# Skip one line with a checksum
skipsumln = False
# Skip the whole rest of the checksum section
skipsumlines = False
with open("PKGBUILD.new", "w") as outf:
for line in open("PKGBUILD"):
if skipsumln:
if ')' in line:
skipsumln = False
elif "'" not in line:
continue
else:
skipsumln = False
continue
if skipsumlines:
if ')' in line:
skipsumlines = False
continue
if line.startswith("pkgver="):
outf.write("pkgver=" + ver + "\n")
elif line.startswith("pkgrel="):
outf.write(f"pkgrel={rel}\n")
elif line.startswith(sumpfx):
if sum:
outf.write(sumpfx + "'" + sum + "'\n")
if "'" not in line:
skipsumln = True
else:
if ")" not in line:
skipsumlines = True
else:
outf.write(line)
os.rename("PKGBUILD", "PKGBUILD.old")
os.rename("PKGBUILD.new", "PKGBUILD")
return
def ssl_ctx():
import ssl
cabundle = "/etc/pki/tls/certs/ca-bundle.crt"
ctx = ssl.create_default_context(cafile=cabundle)
return ctx
def _log(desc):
with open("/sources/autoupdaters/results.log", "a") as f:
f.seek(0,2)
f.write(desc + "\n")
def mpkg(pkg, ver=None, carch=None):
statepath = "/tmp/armlfs-evt"
activepath = statepath + "/active"
donepath = statepath + "/done"
failpath = statepath + "/failed"
from os import makedirs, chdir, getcwd, rename, environ
from os.path import join
from subprocess import run, CalledProcessError
desc = f"{pkg} {ver}" if ver else pkg
fn = desc.replace(" ","-")
makedirs(activepath, exist_ok=True)
fpath = join(activepath,fn)
with open(fpath,"w") as f:
f.write(desc + "\n")
prev_path = getcwd()
chdir("/sources/base-pkgbuilds")
myenv = None
if carch:
myenv = dict(environ, CARCH=carch)
try:
run(["./mpkg.sh", pkg], env=myenv, check=True)
chdir(prev_path)
makedirs(donepath, exist_ok=True)
rename(fpath, join(donepath,fn))
_log(desc + " DONE")
except CalledProcessError:
chdir(prev_path)
makedirs(failpath, exist_ok=True)
rename(fpath, join(failpath,fn))
_log(desc + " FAIL")
raise
def parse_pkgbuild_ver_sum(fn):
meta = {}
sumnextln = False
for line in open(fn):
if sumnextln:
if "'" in line:
_,meta['sum'],_ = line.strip().split("'")
sumnextln = False
if ")" in line:
sumnextln = False
continue
if line.startswith("pkgver=") and 'ver' not in meta:
meta['ver'] = line[7:].strip()
elif "sums=(" in line and 'sum' not in meta:
type, sum = line.strip().split("sums=(",maxsplit=1)
if type not in ("b2", "sha512", "sha384", "sha256", "sha224", "sha1", "md5", "ck"):
continue
if "'" not in sum:
sumnextln = True
else:
_,meta['sum'],_ = sum.strip().split("'")
meta['sumtype'] = type
if 'ver' in meta and 'sum' in meta:
break
return meta
def get_arch_pkgbuild_ver_sum(pkg):
from tempfile import TemporaryDirectory
from subprocess import run
url = f"https://gitlab.archlinux.org/archlinux/packaging/packages/{pkg}.git"
with TemporaryDirectory(prefix=f"tmp-{pkg}-") as dir:
cmd = ["git", "clone", "--depth=1", url, dir ]
run(cmd, check=True)
return parse_pkgbuild_ver_sum(dir + '/PKGBUILD')
def _months_ago(n):
from datetime import date, timedelta
# This allows float "months" <3
d = date.today() - timedelta(days=int(n*30))
return d.isoformat()
def arch_arm_pkgbuild_update(pkg,aarepo="extra"):
"""Update our PKGBUILD (and accompanying files) based on Arch-ARM PKGBUILDs repo"""
from tempfile import TemporaryDirectory
from subprocess import run, PIPE, STDOUT
from os import path, getcwd, chdir, mkdir
url = "https://github.com/archlinuxarm/PKGBUILDs"
ourdir = f"/sources/base-pkgbuilds/{pkg}"
upcommits = ourdir + "/autoupdate-commits"
upcommit_fn = ourdir + "/.upstream_commit"
if path.exists(upcommits):
return "Previous update unfinished"
cwd = getcwd()
with TemporaryDirectory(prefix=f"tmp-{pkg}-") as dir:
cmd = ["git", "clone", f"--shallow-since={_months_ago(3)}", url, dir ]
run(cmd, check=True)
chdir(dir)
path = f"{aarepo}/{pkg}"
with open(upcommit_fn) as f:
upstream_commit = f.read().strip()
cmd2 = [ "git", "rev-list", f"^{upstream_commit}", "HEAD", "--", path ]
revlistp = run(cmd2, text=True, stdout=PIPE, stderr=STDOUT, check=True)
rl = []
for rev in revlistp.stdout.splitlines():
r = rev.strip()
if len(r):
rl.append(r)
if len(rl) < 1:
chdir(cwd)
return "No update necessary"
mkdir(upcommits)
commits = []
# We're recording what we're about to try and apply, to help with manual recovery
# when a patch inevitably fails :P
with open(upcommits + "/order", 'w') as orderf:
for index, rev in enumerate(reversed(rl),start=1):
# Changes to .SRCINFO are 1) pointless and 2) ofter fail -> filter them out
exclude_srcinfo = f":(exclude){path}/.SRCINFO"
cmd3 = [ "git", "format-patch", "--start-number", str(index), "-o", upcommits, "-1", rev, '--', path, exclude_srcinfo ]
patchp = run(cmd3, text=True, stdout=PIPE, stderr=STDOUT, check=True)
patchfn = patchp.stdout.strip()
t = f"{rev} {patchfn}\n"
orderf.write(t)
commits.append((rev,patchfn))
chdir(ourdir)
# Recording of the changes is complete, get rid of the repo (thus exit the with block ^^)
for rev, patchfn in commits:
cmd = [ "patch", "-Np3" ]
with open(patchfn) as patchf:
print(f"Applying {patchfn}...")
pp = run(cmd, stdin=patchf)
if pp.returncode:
msg = f"Applying patch {patchfn} failed"
_log(pkg + ": " + msg)
return msg
with open(upcommit_fn, 'w') as f:
f.write(rev)
print("Patches applied succesfully")
# Patches applied succesfully, get rid of the patch dir
run(["rm", "-r", upcommits])
# None as in No problems, go ahead and build the new version
chdir(cwd)
return None