Commit c204a5a5 authored by Alad Wenter's avatar Alad Wenter
Browse files

remove old mockup (git-read-tree)

parent 3c325de1
......@@ -100,7 +100,7 @@ File format with sorted keys JSON and fields::
pgpsig
url
license (list)
arch (because can also be any)
arch (because can also be "any")
builddate (int)
packager
replaces (list)
......
/*.pkg.tar.xz
/databases/
/packages/
/workdirs/
To test db-update:
- Run ./create-demodata to set up demo data
- Copy one of the *-1-2-* packages to staging/extra.
- Run db-update.
#!/bin/bash -e
rm -rf databases packages staging workdirs *.pkg.tar.xz
mkdir -p databases packages staging/{extra,testing} workdirs
for pkg in foo bar; do
git init --bare --template=templates/package packages/$pkg.git
git clone packages/$pkg.git workdirs/$pkg
pushd workdirs/$pkg
cat >PKGBUILD <<END
pkgname=$pkg
pkgver=1
pkgrel=1
pkgdesc="$pkg"
url="https://www.example.com/"
arch=(x86_64)
license=(GPL3)
package() {
echo "\$pkgver-\$pkgrel" > "\$pkgdir/$pkg"
}
END
for rel in 1 2; do
sed -i "/^pkgrel=/s/=.*/=$rel/" PKGBUILD
makepkg -c
[[ $rel == 1 ]] && cp $pkg-1-$rel-x86_64.pkg.tar.xz ../../staging/extra
mv -f $pkg-1-$rel-x86_64.pkg.tar.xz ../..
git add PKGBUILD
git commit -m "$pkg 1-$rel"
git tag -a -m "$pkg 1-$rel" 1-$rel HEAD
done
git push origin master --tags
popd
rm -rf workdirs/$pkg
done
git init --bare --template=templates/database databases/x86_64.git
git clone databases/x86_64.git workdirs/x86_64
pushd workdirs/x86_64
git commit --allow-empty -m "Empty commit"
popd
./db-update
#!/usr/bin/python
# Based on 'update.sample' shell script
import asyncio
from argparse import ArgumentParser
from asyncio.subprocess import PIPE
from fcntl import LOCK_EX, flock
from os import chdir
from pathlib import Path
from sys import argv, exit
def parse_pkginfo(pkginfo: str) -> dict:
fields = {}
for line in pkginfo.splitlines():
line = line.strip()
if line.startswith("#"):
continue
key, value = line.split(" = ", 1)
fields.setdefault(key, []).append(value)
print(fields)
return fields
async def run(*args):
args = [str(a) for a in args]
proc = await asyncio.create_subprocess_exec(*args)
if await proc.wait() != 0:
raise RuntimeError(f"Command failed: {args!r}")
async def get_output(*args) -> str:
args = [str(a) for a in args]
proc = await asyncio.create_subprocess_exec(*args, stdout=PIPE)
stdout, _ = await proc.communicate()
if proc.returncode != 0:
raise RuntimeError(f"Command failed: {args!r}")
return stdout.decode()
async def put_input(*args, stdin: str):
args = [str(a) for a in args]
proc = await asyncio.create_subprocess_exec(*args, stdin=PIPE)
await proc.communicate(stdin.encode())
if proc.returncode != 0:
raise RuntimeError(f"Command failed: {args!r}")
async def get_pkginfo(pkgfile: Path) -> dict:
return parse_pkginfo(await get_output("bsdtar", "-xOf", pkgfile, ".PKGINFO"))
def lock_tag(pkggitdir: Path, tag: str):
with open(pkggitdir / "locked-tags", "a+") as f:
f.seek(0)
if tag in f.read().splitlines():
return
print(tag, file=f)
async def main(_args) -> int:
workdir = (Path(argv[0]).parent / "workdirs/x86_64").resolve(strict=True)
pkgsdir = (Path(argv[0]).parent / "packages").resolve(strict=True)
staging = (Path(argv[0]).parent / "staging").resolve(strict=True)
chdir(workdir)
packages = {
r.name: {p: None for p in r.glob("*.pkg.tar.xz")} for r in staging.glob("*")
}
packages = {r: ps for r, ps in packages.items() if ps}
if not packages:
return
async def load(ps, p):
ps[p] = await get_pkginfo(p)
await asyncio.gather(
*(load(ps, p) for r, ps in packages.items() for p in ps.keys())
)
lockfile = open(str(workdir / ".git/dbscripts.lock"), "w")
flock(lockfile, LOCK_EX)
curstate = (await get_output("git", "rev-parse", "--verify", "HEAD")).strip()
try:
message = ["db-update title placeholder", ""]
for repo, ps in sorted(packages.items()):
Path(repo).mkdir(exist_ok=True)
for pkg, pkginfo in sorted(ps.items()):
pkgbase = pkginfo["pkgbase"][0]
pkgdir = Path(repo) / pkgbase
pkgver = pkginfo["pkgver"][0]
pkggitdir = pkgsdir / (pkgbase + ".git")
lock_tag(pkggitdir, pkgver)
tagref = "refs/last-tag"
cacherefs = f"refs/packages/{pkgbase}/*"
await run(
"git",
"fetch",
"--no-tags",
"--prune",
f"--negotiation-tip={cacherefs}",
pkggitdir,
f"+refs/heads/*:{cacherefs}",
f"+refs/tags/{pkgver}:{tagref}",
)
if pkgdir.exists():
await run("git", "rm", "-r", pkgdir)
await run("git", "read-tree", f"--prefix={pkgdir}", "-u", tagref)
message.append(f"Released {pkgbase} {pkgver} to {repo}")
await put_input("git", "commit", "--file=-", stdin="\n".join(message))
await run("git", "push", "origin", "master:master")
except Exception:
await run("git", "reset", "--hard", curstate)
raise
finally:
await run("git", "clean", "-xfd")
for ps in packages.values():
for p in ps.keys():
p.unlink()
return 0
parser = ArgumentParser(description="db-update mockup.")
parser.add_argument("--debug", action="store_true", default=False, help="Debug mode")
args = parser.parse_args()
exit(asyncio.run(main(args), debug=args.debug))
../../../update-hook
\ No newline at end of file
#!/usr/bin/python
# Based on 'update.sample' shell script
from argparse import ArgumentParser
from os import environ
from pathlib import Path
from subprocess import check_output
from sys import argv, exit, stderr
def die(*lines):
print(*lines, sep="\n", file=stderr)
exit(1)
try:
gitdir = Path(environ["GIT_DIR"])
except KeyError:
die(
"Don't run this script from the command line.",
f"If you want, you could supply GIT_DIR then run: {argv[0]} <ref> <oldrev> <newrev>",
)
parser = ArgumentParser(description="Packages git update hook.")
parser.add_argument("ref", metavar="REF", help="Ref getting updated")
parser.add_argument("oldrev", metavar="OLDREV", help="Old revision ID")
parser.add_argument("newrev", metavar="NEWREV", help="New revision ID")
args = parser.parse_args()
newrev_type = (
"delete"
if args.newrev == "0000000000000000000000000000000000000000"
else check_output(["git", "cat-file", "-t", args.newrev]).decode().strip()
)
if args.ref.startswith("refs/tags/"):
shortref = args.ref[10:]
if newrev_type == "commit":
die(
f"*** Tag '{shortref}' has not been annotated.",
"*** Use 'git tag [ -a | -s ]' for tags you want to propagate.",
)
elif newrev_type in ("tag", "delete"):
locked_tags = (gitdir / "locked-tags").read_text().splitlines()
if args.oldrev != args.newrev and shortref in locked_tags:
die(
f"*** Tag '{shortref}' has been locked.",
"*** Modifying a locked tag is not allowed in this repository.",
)
else:
die(f"*** Cannot push '{newrev_type}' to tag '{shortref}'.", "Must be a tag.")
elif args.ref.startswith("refs/heads/"):
shortref = args.ref[11:]
if newrev_type not in ("commit", "delete"):
die(
f"*** Cannot push '{newrev_type}' to branch '{shortref}'."
"Must be a commit."
)
else:
die(f"*** Update hook: Bad ref '{args.ref}'")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment