3 ### GNU Affero General Public License compliance
5 ### (c) 2013 Mark Wooding
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of Chopwood: a password-changing service.
12 ### Chopwood is free software; you can redistribute it and/or modify
13 ### it under the terms of the GNU Affero General Public License as
14 ### published by the Free Software Foundation; either version 3 of the
15 ### License, or (at your option) any later version.
17 ### Chopwood is distributed in the hope that it will be useful,
18 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ### GNU Affero General Public License for more details.
22 ### You should have received a copy of the GNU Affero General Public
23 ### License along with Chopwood; if not, see
24 ### <http://www.gnu.org/licenses/>.
26 import contextlib as CTX
32 import subprocess as SUB
38 from cStringIO import StringIO
40 from auto import PACKAGE, VERSION
47 finally: SH.rmtree(d, ignore_errors = True)
51 for m in SYS.modules.itervalues():
53 except AttributeError: continue
54 d = OS.path.realpath(OS.path.dirname(f))
55 if d.startswith('/usr/') and not d.startswith('/usr/local/'): continue
61 if d.startswith(last): continue
66 def exists_subdir(subdir):
67 return lambda dir: OS.path.isdir(OS.path.join(dir, subdir))
71 kid = SUB.Popen(SL.split(cmd), stdout = SUB.PIPE, cwd = dir)
74 buf = kid.stdout.read(16384)
82 if f.startswith('./'): f = f[2:]
87 raise U.ExpectedError, \
88 (500, "trailing junk from `%s' in `%s'" % (cmd, dir))
92 (exists_subdir('.git'), [filez('git ls-files -coz --exclude-standard'),
93 filez('find .git -print0')]),
94 (lambda d: True, [filez('find . ( ! -perm +004 -prune ) -o -print0')])]
96 def dump_dir(dir, tf, root):
97 for test, listers in DUMPERS:
100 raise U.ExpectedError, (500, "no dumper for `%s'" % dir)
101 for lister in listers:
102 base = OS.path.basename(dir)
103 for file in lister(dir):
104 tf.add(OS.path.join(dir, file), OS.path.join(root, base, file),
108 if SYS.version_info >= (2, 6):
109 tf = TAR.open(fileobj = out, mode = 'w|gz', format = TAR.USTAR_FORMAT)
111 tf = TAR.open(fileobj = out, mode = 'w|gz')
113 root = '%s-%s' % (PACKAGE, VERSION)
117 for dir in dirs_to_dump():
118 dir = dir.rstrip('/')
119 base = OS.path.basename(dir)
124 name = '%s.%d' % (base, i)
125 if name not in seen: break
126 dirmap.append((dir + '/', name))
127 festout.write('%s = %s\n' % (name, dir))
128 fest = festout.getvalue()
129 ti = TAR.TarInfo(OS.path.join(root, 'MANIFEST'))
133 ti.type = TAR.REGTYPE
134 uid = OS.getuid(); ti.uid, ti.uname = uid, PW.getpwuid(uid).pw_name
135 gid = OS.getgid(); ti.gid, ti.gname = gid, GR.getgrgid(gid).gr_name
136 tf.addfile(ti, fileobj = StringIO(fest))
137 for dir, name in dirmap:
138 dump_dir(dir, tf, root)
141 ###----- That's all, folks --------------------------------------------------