#!/usr/bin/env python3 # (c) 2014 Taeyeon MORI import os import argparse import subprocess import hashlib import contextlib import sys import termios import shutil system = lambda *a: subprocess.check_call(a) class Package: def __init__(self, x): self.fqn = x self.repo, self.name = x.split("/") def parse_args(argv): parser = argparse.ArgumentParser(prog=argv[0]) def add_option(option, default, help=None): parser.add_argument(option, default=default) def add_switch(option, default=False, help=None): parser.add_argument(option, default=default, action="store_const", const=not default) parser.add_argument("package", type=Package) add_option("-buildroot", "/tmp/abs-%i" % os.getuid()) add_option("-makepkg", "makepkg") add_switch("-nobuild") add_switch("-install") return parser.parse_args(argv[1:]) def file_sha1(name): with open(name, "rb") as f: hash = hashlib.sha1() while True: data = f.read(2048) if not data: return hash.digest() hash.update(data) @contextlib.contextmanager def rawinput(file): fd = file.fileno() if hasattr(file, "fileno") else file flags = save = termios.tcgetattr(fd) flags[3] &= ~termios.ICANON flags[6][termios.VMIN] = 1 flags[6][termios.VTIME] = 0 termios.tcsetattr(fd, termios.TCSADRAIN, flags) yield termios.tcsetattr(fd, termios.TCSADRAIN, save) def yesno(prompt): ch = "" while ch not in "yYnN": sys.stdout.write(prompt) sys.stdout.write(" [Y/N] ") sys.stdout.flush() with rawinput(sys.stdin): ch = sys.stdin.read(1) sys.stdout.write("\r") sys.stdout.write("\n") return ch in "yY" def main(argv): args = parse_args(argv) print("===> Synchronizing ABS") system("sudo", "abs", args.package.fqn) print("===> Updating build directory") ABS_DIR = os.path.join("/var/abs", args.package.fqn) if not os.path.exists(ABS_DIR): print("=ERROR=> No such pacakge: %s" % args.package.fqn) return 1 REPODIR = os.path.join(args.buildroot, args.package.repo) PACKDIR = os.path.join(REPODIR, args.package.name) if not os.path.exists(PACKDIR): os.makedirs(PACKDIR) for path, dirs, files in os.walk(ABS_DIR): rel_path = os.path.relpath(path, ABS_DIR) dest_path = os.path.join(PACKDIR, rel_path) for dir in dirs: dest = os.path.join(dest_path, dir) os.path.exists(dest) or os.mkdir(dest) for file in files: source = os.path.join(path, file) dest = os.path.join(dest_path, file) (not os.path.exists(dest) or (file_sha1(source) != file_sha1(dest) and yesno("=> Overwrite %s?" % os.path.join(rel_path, file)))) and shutil.copy(source, dest) yesno("=> Edit %s PKGBUILD?" % args.package.fqn) and system(os.environ.get("EDITOR", "vim"), os.path.join(PACKDIR, "PKGBUILD")) if not args.nobuild: print("===> Building Package %s" % args.package.fqn) os.chdir(PACKDIR) if args.install: system(args.makepkg, "-i") else: system(args.makepkg) return 0 if __name__ == "__main__": sys.exit(main(sys.argv))