author | Bryan O'Sullivan <bos@serpentine.com> |
Wed, 20 Feb 2008 13:38:16 -0800 | |
changeset 6151 | 8bc4fe428103 |
parent 6020 | 20b05618b3e2 |
child 6183 | 0750e4ba9d3d |
permissions | -rw-r--r-- |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
1 |
# archival.py - revision archival for mercurial |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
2 |
# |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
3 |
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
4 |
# |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms of |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
6 |
# the GNU General Public License, incorporated herein by reference. |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
7 |
|
3891 | 8 |
from i18n import _ |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
9 |
from node import * |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
3615
diff
changeset
|
10 |
import cStringIO, os, stat, tarfile, time, util, zipfile |
4652
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
11 |
import zlib, gzip |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
12 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
13 |
def tidyprefix(dest, prefix, suffixes): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
14 |
'''choose prefix to use for names in archive. make sure prefix is |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
15 |
safe for consumers.''' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
16 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
17 |
if prefix: |
5842
111ed8c871bf
Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents:
4951
diff
changeset
|
18 |
prefix = util.normpath(prefix) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
19 |
else: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
20 |
if not isinstance(dest, str): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
21 |
raise ValueError('dest must be string if no prefix') |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
22 |
prefix = os.path.basename(dest) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
23 |
lower = prefix.lower() |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
24 |
for sfx in suffixes: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
25 |
if lower.endswith(sfx): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
26 |
prefix = prefix[:-len(sfx)] |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
27 |
break |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
28 |
lpfx = os.path.normpath(util.localpath(prefix)) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
29 |
prefix = util.pconvert(lpfx) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
30 |
if not prefix.endswith('/'): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
31 |
prefix += '/' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
32 |
if prefix.startswith('../') or os.path.isabs(lpfx) or '/../' in prefix: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
33 |
raise util.Abort(_('archive prefix contains illegal components')) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
34 |
return prefix |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
35 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
36 |
class tarit: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
37 |
'''write archive to tar file or stream. can write uncompressed, |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
38 |
or compress with gzip or bzip2.''' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
39 |
|
4652
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
40 |
class GzipFileWithTime(gzip.GzipFile): |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
41 |
|
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
42 |
def __init__(self, *args, **kw): |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
43 |
timestamp = None |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
44 |
if 'timestamp' in kw: |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
45 |
timestamp = kw.pop('timestamp') |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
46 |
if timestamp == None: |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
47 |
self.timestamp = time.time() |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
48 |
else: |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
49 |
self.timestamp = timestamp |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
50 |
gzip.GzipFile.__init__(self, *args, **kw) |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
51 |
|
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
52 |
def _write_gzip_header(self): |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
53 |
self.fileobj.write('\037\213') # magic header |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
54 |
self.fileobj.write('\010') # compression method |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
55 |
fname = self.filename[:-3] |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
56 |
flags = 0 |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
57 |
if fname: |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
58 |
flags = gzip.FNAME |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
59 |
self.fileobj.write(chr(flags)) |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
60 |
gzip.write32u(self.fileobj, long(self.timestamp)) |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
61 |
self.fileobj.write('\002') |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
62 |
self.fileobj.write('\377') |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
63 |
if fname: |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
64 |
self.fileobj.write(fname + '\000') |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
65 |
|
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
66 |
def __init__(self, dest, prefix, mtime, kind=''): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
67 |
self.prefix = tidyprefix(dest, prefix, ['.tar', '.tar.bz2', '.tar.gz', |
3615
1d2fdea875bc
Fixed directory name having an extra dot on "hg archive -t tbz2 foo.tbz2".
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2857
diff
changeset
|
68 |
'.tgz', '.tbz2']) |
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
69 |
self.mtime = mtime |
4652
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
70 |
|
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
71 |
def taropen(name, mode, fileobj=None): |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
72 |
if kind == 'gz': |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
73 |
mode = mode[0] |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
74 |
if not fileobj: |
4731 | 75 |
fileobj = open(name, mode + 'b') |
4652
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
76 |
gzfileobj = self.GzipFileWithTime(name, mode + 'b', |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
77 |
zlib.Z_BEST_COMPRESSION, |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
78 |
fileobj, timestamp=mtime) |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
79 |
return tarfile.TarFile.taropen(name, mode, gzfileobj) |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
80 |
else: |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
81 |
return tarfile.open(name, mode + kind, fileobj) |
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
82 |
|
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
83 |
if isinstance(dest, str): |
4652
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
84 |
self.z = taropen(dest, mode='w:') |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
85 |
else: |
4357
3f1b0c0fb4fd
Work around python 2.5.1 tarfile regression
Brendan Cully <brendan@kublai.com>
parents:
3615
diff
changeset
|
86 |
# Python 2.5-2.5.1 have a regression that requires a name arg |
4652
06de65673ec2
timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents:
4370
diff
changeset
|
87 |
self.z = taropen(name='', mode='w|', fileobj=dest) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
88 |
|
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
89 |
def addfile(self, name, mode, islink, data): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
90 |
i = tarfile.TarInfo(self.prefix + name) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
91 |
i.mtime = self.mtime |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
92 |
i.size = len(data) |
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
93 |
if islink: |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
94 |
i.type = tarfile.SYMTYPE |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
95 |
i.mode = 0777 |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
96 |
i.linkname = data |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
97 |
data = None |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
98 |
else: |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
99 |
i.mode = mode |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
100 |
data = cStringIO.StringIO(data) |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
101 |
self.z.addfile(i, data) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
102 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
103 |
def done(self): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
104 |
self.z.close() |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
105 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
106 |
class tellable: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
107 |
'''provide tell method for zipfile.ZipFile when writing to http |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
108 |
response file object.''' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
109 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
110 |
def __init__(self, fp): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
111 |
self.fp = fp |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
112 |
self.offset = 0 |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
113 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
114 |
def __getattr__(self, key): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
115 |
return getattr(self.fp, key) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
116 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
117 |
def write(self, s): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
118 |
self.fp.write(s) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
119 |
self.offset += len(s) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
120 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
121 |
def tell(self): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
122 |
return self.offset |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
123 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
124 |
class zipit: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
125 |
'''write archive to zip file or stream. can write uncompressed, |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
126 |
or compressed with deflate.''' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
127 |
|
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
128 |
def __init__(self, dest, prefix, mtime, compress=True): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
129 |
self.prefix = tidyprefix(dest, prefix, ('.zip',)) |
2168
dd4ec4576cc8
Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents:
2112
diff
changeset
|
130 |
if not isinstance(dest, str): |
dd4ec4576cc8
Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents:
2112
diff
changeset
|
131 |
try: |
dd4ec4576cc8
Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents:
2112
diff
changeset
|
132 |
dest.tell() |
2169
4564794b6f55
Combine catching exceptions added in dd4ec4576cc8 in one except statement.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2168
diff
changeset
|
133 |
except (AttributeError, IOError): |
2168
dd4ec4576cc8
Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents:
2112
diff
changeset
|
134 |
dest = tellable(dest) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
135 |
self.z = zipfile.ZipFile(dest, 'w', |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
136 |
compress and zipfile.ZIP_DEFLATED or |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
137 |
zipfile.ZIP_STORED) |
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
138 |
self.date_time = time.gmtime(mtime)[:6] |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
139 |
|
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
140 |
def addfile(self, name, mode, islink, data): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
141 |
i = zipfile.ZipInfo(self.prefix + name, self.date_time) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
142 |
i.compress_type = self.z.compression |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
143 |
# unzip will not honor unix file modes unless file creator is |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
144 |
# set to unix (id 3). |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
145 |
i.create_system = 3 |
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
146 |
ftype = stat.S_IFREG |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
147 |
if islink: |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
148 |
mode = 0777 |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
149 |
ftype = stat.S_IFLNK |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
150 |
i.external_attr = (mode | ftype) << 16L |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
151 |
self.z.writestr(i, data) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
152 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
153 |
def done(self): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
154 |
self.z.close() |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
155 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
156 |
class fileit: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
157 |
'''write archive as files in directory.''' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
158 |
|
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
159 |
def __init__(self, name, prefix, mtime): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
160 |
if prefix: |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
161 |
raise util.Abort(_('cannot give prefix when archiving to files')) |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
162 |
self.basedir = name |
4830
74f36b1027f4
archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4731
diff
changeset
|
163 |
self.opener = util.opener(self.basedir) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
164 |
|
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
165 |
def addfile(self, name, mode, islink, data): |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
166 |
if islink: |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
167 |
self.opener.symlink(data, name) |
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
168 |
return |
4830
74f36b1027f4
archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4731
diff
changeset
|
169 |
f = self.opener(name, "w", atomictemp=True) |
74f36b1027f4
archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4731
diff
changeset
|
170 |
f.write(data) |
74f36b1027f4
archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4731
diff
changeset
|
171 |
f.rename() |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
172 |
destfile = os.path.join(self.basedir, name) |
4830
74f36b1027f4
archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4731
diff
changeset
|
173 |
os.chmod(destfile, mode) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
174 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
175 |
def done(self): |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
176 |
pass |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
177 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
178 |
archivers = { |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
179 |
'files': fileit, |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
180 |
'tar': tarit, |
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
181 |
'tbz2': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'bz2'), |
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
182 |
'tgz': lambda name, prefix, mtime: tarit(name, prefix, mtime, 'gz'), |
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
183 |
'uzip': lambda name, prefix, mtime: zipit(name, prefix, mtime, False), |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
184 |
'zip': zipit, |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
185 |
} |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
186 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
187 |
def archive(repo, dest, node, kind, decode=True, matchfn=None, |
2477
857591c586e0
use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2353
diff
changeset
|
188 |
prefix=None, mtime=None): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
189 |
'''create archive of repo as it was at node. |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
190 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
191 |
dest can be name of directory, name of archive file, or file |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
192 |
object to write archive to. |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
193 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
194 |
kind is type of archive to create. |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
195 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
196 |
decode tells whether to put files through decode filters from |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
197 |
hgrc. |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
198 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
199 |
matchfn is function to filter names of files to write to archive. |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
200 |
|
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
201 |
prefix is name of path to put before every archive member.''' |
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
202 |
|
4951
667290b6c95e
archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4831
diff
changeset
|
203 |
def write(name, mode, islink, getdata): |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
204 |
if matchfn and not matchfn(name): return |
4951
667290b6c95e
archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4831
diff
changeset
|
205 |
data = getdata() |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
206 |
if decode: |
4005
656e06eebda7
replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents:
3968
diff
changeset
|
207 |
data = repo.wwritedata(name, data) |
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
208 |
archiver.addfile(name, mode, islink, data) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
209 |
|
3968
033082ba1d1a
archival.py: use contexts
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3891
diff
changeset
|
210 |
ctx = repo.changectx(node) |
6019
b70a530bdb93
cleanly abort on unknown archive type (issue966)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
4951
diff
changeset
|
211 |
if kind not in archivers: |
b70a530bdb93
cleanly abort on unknown archive type (issue966)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
4951
diff
changeset
|
212 |
raise util.Abort(_("unknown archive type '%s'" % kind)) |
3968
033082ba1d1a
archival.py: use contexts
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3891
diff
changeset
|
213 |
archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0]) |
033082ba1d1a
archival.py: use contexts
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3891
diff
changeset
|
214 |
m = ctx.manifest() |
2857
18cf5349a361
Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2840
diff
changeset
|
215 |
items = m.items() |
18cf5349a361
Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2840
diff
changeset
|
216 |
items.sort() |
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
217 |
write('.hg_archival.txt', 0644, False, |
4951
667290b6c95e
archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4831
diff
changeset
|
218 |
lambda: 'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node))) |
2857
18cf5349a361
Fix some bugs introduced during the manifest refactoring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2840
diff
changeset
|
219 |
for filename, filenode in items: |
4831
6f08bc1bd00b
archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4830
diff
changeset
|
220 |
write(filename, m.execf(filename) and 0755 or 0644, m.linkf(filename), |
4951
667290b6c95e
archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4831
diff
changeset
|
221 |
lambda: repo.file(filename).read(filenode)) |
2112
2b03c6733efa
add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
222 |
archiver.done() |