X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/chopwood/blobdiff_plain/a2916c0635fec5b45ad742904db9f5769b48f53d..5dea00528b8c53b3462583b675cf9badafe68cbe:/agpl.py?ds=sidebyside diff --git a/agpl.py b/agpl.py index b89330c..43eba82 100644 --- a/agpl.py +++ b/agpl.py @@ -24,13 +24,18 @@ ### . import contextlib as CTX +import grp as GR import os as OS +import pwd as PW import shlex as SL import shutil as SH import subprocess as SUB import sys as SYS import tarfile as TAR import tempfile as TF +import time as T + +from cStringIO import StringIO from auto import PACKAGE, VERSION import util as U @@ -74,9 +79,10 @@ def filez(cmd): z = buf.find('\0', i) if z < 0: break f = buf[i:z] + i = z + 1 + if f == '.': continue if f.startswith('./'): f = f[2:] yield f - i = z + 1 left = buf[i:] if left: raise U.ExpectedError, \ @@ -88,16 +94,31 @@ DUMPERS = [ filez('find .git -print0')]), (lambda d: True, [filez('find . ( ! -perm +004 -prune ) -o -print0')])] -def dump_dir(dir, tf, root): +def dump_dir(name, dir, dirmap, tf, root): for test, listers in DUMPERS: if test(dir): break else: raise U.ExpectedError, (500, "no dumper for `%s'" % dir) + tf.add(dir, OS.path.join(root, name), recursive = False) for lister in listers: - base = OS.path.basename(dir) for file in lister(dir): - tf.add(OS.path.join(dir, file), OS.path.join(root, base, file), - recursive = False) + full = OS.path.join(dir, file) + tarname = OS.path.join(root, name, file) + skip = False + if OS.path.islink(full): + dest = OS.path.realpath(full) + for d, local in dirmap: + if dest.startswith(d): + fix = OS.path.relpath(OS.path.join('/', local, dest[len(d):]), + OS.path.join('/', name, + OS.path.dirname(file))) + st = OS.stat(full) + ti = tf.gettarinfo(full, tarname) + ti.linkname = fix + tf.addfile(ti) + skip = True + if not skip: + tf.add(full, tarname, recursive = False) def source(out): if SYS.version_info >= (2, 6): @@ -105,8 +126,32 @@ def source(out): else: tf = TAR.open(fileobj = out, mode = 'w|gz') tf.posix = True - for d in dirs_to_dump(): - dump_dir(d, tf, '%s-%s' % (PACKAGE, VERSION)) + root = '%s-%s' % (PACKAGE, VERSION) + seen = set() + dirmap = [] + festout = StringIO() + for dir in dirs_to_dump(): + dir = dir.rstrip('/') + base = OS.path.basename(dir) + if base not in seen: + name = base + else: + for i in I.count(): + name = '%s.%d' % (base, i) + if name not in seen: break + dirmap.append((dir + '/', name)) + festout.write('%s = %s\n' % (name, dir)) + fest = festout.getvalue() + ti = TAR.TarInfo(OS.path.join(root, 'MANIFEST')) + ti.size = len(fest) + ti.mtime = T.time() + ti.mode = 0664 + ti.type = TAR.REGTYPE + uid = OS.getuid(); ti.uid, ti.uname = uid, PW.getpwuid(uid).pw_name + gid = OS.getgid(); ti.gid, ti.gname = gid, GR.getgrgid(gid).gr_name + tf.addfile(ti, fileobj = StringIO(fest)) + for dir, name in dirmap: + dump_dir(name, dir, dirmap, tf, root) tf.close() ###----- That's all, folks --------------------------------------------------