|
|
|
#!/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))
|
|
|
|
|