Mercurial > hg
comparison mercurial/archival.py @ 11558:d8f6458434ec
archival: remove prefix argument from archivers
When the archivers work on the full we can reuse the same archiver
with different prefixes (for different subrepositories).
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Wed, 14 Jul 2010 20:25:31 +0200 |
parents | 57bdc2239535 |
children | 1ef70bdd1e62 |
comparison
equal
deleted
inserted
replaced
11557:57bdc2239535 | 11558:d8f6458434ec |
---|---|
10 import cmdutil | 10 import cmdutil |
11 import util | 11 import util |
12 import cStringIO, os, stat, tarfile, time, zipfile | 12 import cStringIO, os, stat, tarfile, time, zipfile |
13 import zlib, gzip | 13 import zlib, gzip |
14 | 14 |
15 def tidyprefix(dest, prefix, suffixes): | 15 def tidyprefix(dest, kind, prefix): |
16 '''choose prefix to use for names in archive. make sure prefix is | 16 '''choose prefix to use for names in archive. make sure prefix is |
17 safe for consumers.''' | 17 safe for consumers.''' |
18 | 18 |
19 if prefix: | 19 if prefix: |
20 prefix = util.normpath(prefix) | 20 prefix = util.normpath(prefix) |
21 else: | 21 else: |
22 if not isinstance(dest, str): | 22 if not isinstance(dest, str): |
23 raise ValueError('dest must be string if no prefix') | 23 raise ValueError('dest must be string if no prefix') |
24 prefix = os.path.basename(dest) | 24 prefix = os.path.basename(dest) |
25 lower = prefix.lower() | 25 lower = prefix.lower() |
26 for sfx in suffixes: | 26 for sfx in exts.get(kind, []): |
27 if lower.endswith(sfx): | 27 if lower.endswith(sfx): |
28 prefix = prefix[:-len(sfx)] | 28 prefix = prefix[:-len(sfx)] |
29 break | 29 break |
30 lpfx = os.path.normpath(util.localpath(prefix)) | 30 lpfx = os.path.normpath(util.localpath(prefix)) |
31 prefix = util.pconvert(lpfx) | 31 prefix = util.pconvert(lpfx) |
78 self.fileobj.write('\002') | 78 self.fileobj.write('\002') |
79 self.fileobj.write('\377') | 79 self.fileobj.write('\377') |
80 if fname: | 80 if fname: |
81 self.fileobj.write(fname + '\000') | 81 self.fileobj.write(fname + '\000') |
82 | 82 |
83 def __init__(self, dest, prefix, mtime, kind=''): | 83 def __init__(self, dest, mtime, kind=''): |
84 self.prefix = tidyprefix(dest, prefix, ['.tar', '.tar.bz2', '.tar.gz', | |
85 '.tgz', '.tbz2']) | |
86 self.mtime = mtime | 84 self.mtime = mtime |
87 | 85 |
88 def taropen(name, mode, fileobj=None): | 86 def taropen(name, mode, fileobj=None): |
89 if kind == 'gz': | 87 if kind == 'gz': |
90 mode = mode[0] | 88 mode = mode[0] |
102 else: | 100 else: |
103 # Python 2.5-2.5.1 have a regression that requires a name arg | 101 # Python 2.5-2.5.1 have a regression that requires a name arg |
104 self.z = taropen(name='', mode='w|', fileobj=dest) | 102 self.z = taropen(name='', mode='w|', fileobj=dest) |
105 | 103 |
106 def addfile(self, name, mode, islink, data): | 104 def addfile(self, name, mode, islink, data): |
107 i = tarfile.TarInfo(self.prefix + name) | 105 i = tarfile.TarInfo(name) |
108 i.mtime = self.mtime | 106 i.mtime = self.mtime |
109 i.size = len(data) | 107 i.size = len(data) |
110 if islink: | 108 if islink: |
111 i.type = tarfile.SYMTYPE | 109 i.type = tarfile.SYMTYPE |
112 i.mode = 0777 | 110 i.mode = 0777 |
141 | 139 |
142 class zipit(object): | 140 class zipit(object): |
143 '''write archive to zip file or stream. can write uncompressed, | 141 '''write archive to zip file or stream. can write uncompressed, |
144 or compressed with deflate.''' | 142 or compressed with deflate.''' |
145 | 143 |
146 def __init__(self, dest, prefix, mtime, compress=True): | 144 def __init__(self, dest, mtime, compress=True): |
147 self.prefix = tidyprefix(dest, prefix, ('.zip',)) | |
148 if not isinstance(dest, str): | 145 if not isinstance(dest, str): |
149 try: | 146 try: |
150 dest.tell() | 147 dest.tell() |
151 except (AttributeError, IOError): | 148 except (AttributeError, IOError): |
152 dest = tellable(dest) | 149 dest = tellable(dest) |
154 compress and zipfile.ZIP_DEFLATED or | 151 compress and zipfile.ZIP_DEFLATED or |
155 zipfile.ZIP_STORED) | 152 zipfile.ZIP_STORED) |
156 self.date_time = time.gmtime(mtime)[:6] | 153 self.date_time = time.gmtime(mtime)[:6] |
157 | 154 |
158 def addfile(self, name, mode, islink, data): | 155 def addfile(self, name, mode, islink, data): |
159 i = zipfile.ZipInfo(self.prefix + name, self.date_time) | 156 i = zipfile.ZipInfo(name, self.date_time) |
160 i.compress_type = self.z.compression | 157 i.compress_type = self.z.compression |
161 # unzip will not honor unix file modes unless file creator is | 158 # unzip will not honor unix file modes unless file creator is |
162 # set to unix (id 3). | 159 # set to unix (id 3). |
163 i.create_system = 3 | 160 i.create_system = 3 |
164 ftype = stat.S_IFREG | 161 ftype = stat.S_IFREG |
172 self.z.close() | 169 self.z.close() |
173 | 170 |
174 class fileit(object): | 171 class fileit(object): |
175 '''write archive as files in directory.''' | 172 '''write archive as files in directory.''' |
176 | 173 |
177 def __init__(self, name, prefix, mtime): | 174 def __init__(self, name, mtime): |
178 if prefix: | |
179 raise util.Abort(_('cannot give prefix when archiving to files')) | |
180 self.basedir = name | 175 self.basedir = name |
181 self.opener = util.opener(self.basedir) | 176 self.opener = util.opener(self.basedir) |
182 | 177 |
183 def addfile(self, name, mode, islink, data): | 178 def addfile(self, name, mode, islink, data): |
184 if islink: | 179 if islink: |
194 pass | 189 pass |
195 | 190 |
196 archivers = { | 191 archivers = { |
197 'files': fileit, | 192 'files': fileit, |
198 'tar': tarit, | 193 'tar': tarit, |
199 'tbz2': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'bz2'), | 194 'tbz2': lambda name, mtime: tarit(name, mtime, 'bz2'), |
200 'tgz': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'gz'), | 195 'tgz': lambda name, mtime: tarit(name, mtime, 'gz'), |
201 'uzip': lambda name, prefix, mtime: zipit(name, prefix, mtime, False), | 196 'uzip': lambda name, mtime: zipit(name, mtime, False), |
202 'zip': zipit, | 197 'zip': zipit, |
203 } | 198 } |
204 | 199 |
205 def archive(repo, dest, node, kind, decode=True, matchfn=None, | 200 def archive(repo, dest, node, kind, decode=True, matchfn=None, |
206 prefix=None, mtime=None): | 201 prefix=None, mtime=None): |
215 hgrc. | 210 hgrc. |
216 | 211 |
217 matchfn is function to filter names of files to write to archive. | 212 matchfn is function to filter names of files to write to archive. |
218 | 213 |
219 prefix is name of path to put before every archive member.''' | 214 prefix is name of path to put before every archive member.''' |
215 | |
216 if kind == 'files': | |
217 if prefix: | |
218 raise util.Abort(_('cannot give prefix when archiving to files')) | |
219 else: | |
220 prefix = tidyprefix(dest, kind, prefix) | |
220 | 221 |
221 def write(name, mode, islink, getdata): | 222 def write(name, mode, islink, getdata): |
222 if matchfn and not matchfn(name): | 223 if matchfn and not matchfn(name): |
223 return | 224 return |
224 data = getdata() | 225 data = getdata() |
225 if decode: | 226 if decode: |
226 data = repo.wwritedata(name, data) | 227 data = repo.wwritedata(name, data) |
227 archiver.addfile(name, mode, islink, data) | 228 archiver.addfile(prefix + name, mode, islink, data) |
228 | 229 |
229 if kind not in archivers: | 230 if kind not in archivers: |
230 raise util.Abort(_("unknown archive type '%s'") % kind) | 231 raise util.Abort(_("unknown archive type '%s'") % kind) |
231 | 232 |
232 ctx = repo[node] | 233 ctx = repo[node] |
233 archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0]) | 234 archiver = archivers[kind](dest, mtime or ctx.date()[0]) |
234 | 235 |
235 if repo.ui.configbool("ui", "archivemeta", True): | 236 if repo.ui.configbool("ui", "archivemeta", True): |
236 def metadata(): | 237 def metadata(): |
237 base = 'repo: %s\nnode: %s\nbranch: %s\n' % ( | 238 base = 'repo: %s\nnode: %s\nbranch: %s\n' % ( |
238 hex(repo.changelog.node(0)), hex(node), ctx.branch()) | 239 hex(repo.changelog.node(0)), hex(node), ctx.branch()) |