You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.2 KiB
119 lines
3.2 KiB
#!/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)) |
|
|
|
|