17
17
"""Export a Tree to a non-versioned directory.
25
from bzrlib import export, osutils
26
29
from bzrlib.export import _export_iter_entries
27
30
from bzrlib.filters import (
28
31
ContentFilterContext,
29
32
filtered_output_bytes,
31
from bzrlib.trace import mutter
34
def tar_exporter(tree, dest, root, subdir, compression=None, filtered=False,
35
per_file_timestamps=False):
36
"""Export this tree to a new tar file.
38
`dest` will be created holding the contents of this tree; if it
39
already exists, it will be clobbered, like with "tar -c".
36
def export_tarball(tree, ball, root, subdir=None, filtered=False,
38
"""Export tree contents to a tarball.
40
:param tree: Tree to export
41
:param ball: Tarball to export to
42
:param filtered: Whether to apply filters
43
:param subdir: Sub directory to export
44
:param force_mtime: Option mtime to force, instead of using
41
mutter('export version %r', tree)
43
compression = str(compression or '')
45
# XXX: If no root is given, the output tarball will contain files
46
# named '-/foo'; perhaps this is the most reasonable thing.
47
ball = tarfile.open(None, 'w|' + compression, sys.stdout)
50
root = export.get_root_name(dest)
52
# tarfile.open goes on to do 'os.getcwd() + dest' for opening
53
# the tar file. With dest being unicode, this throws UnicodeDecodeError
54
# unless we encode dest before passing it on. This works around
55
# upstream python bug http://bugs.python.org/issue8396
56
# (fixed in Python 2.6.5 and 2.7b1)
57
ball = tarfile.open(dest.encode(osutils._fs_enc), 'w:' + compression)
59
47
for dp, ie in _export_iter_entries(tree, subdir):
60
48
filename = osutils.pathjoin(root, dp).encode('utf8')
61
49
item = tarfile.TarInfo(filename)
62
if per_file_timestamps:
50
if force_mtime is not None:
51
item.mtime = force_mtime
63
53
item.mtime = tree.get_file_mtime(ie.file_id, dp)
66
54
if ie.kind == "file":
67
55
item.type = tarfile.REGTYPE
68
56
if tree.is_executable(ie.file_id):
90
78
item.type = tarfile.SYMTYPE
93
item.linkname = ie.symlink_target
81
item.linkname = tree.get_symlink_target(ie.file_id)
96
raise BzrError("don't know how to export {%s} of kind %r" %
84
raise errors.BzrError("don't know how to export {%s} of kind %r" %
97
85
(ie.file_id, ie.kind))
98
86
ball.addfile(item, fileobj)
102
def tgz_exporter(tree, dest, root, subdir, filtered=False,
103
per_file_timestamps=False):
104
tar_exporter(tree, dest, root, subdir, compression='gz',
105
filtered=filtered, per_file_timestamps=per_file_timestamps)
108
def tbz_exporter(tree, dest, root, subdir, filtered=False,
109
per_file_timestamps=False):
110
tar_exporter(tree, dest, root, subdir, compression='bz2',
111
filtered=filtered, per_file_timestamps=per_file_timestamps)
89
def tgz_exporter(tree, dest, root, subdir, filtered=False, force_mtime=None):
90
"""Export this tree to a new tar file.
92
`dest` will be created holding the contents of this tree; if it
93
already exists, it will be clobbered, like with "tar -c".
96
if force_mtime is not None:
97
root_mtime = force_mtime
98
elif (getattr(tree, "repository", None) and
99
getattr(tree, "get_revision_id", None)):
100
# If this is a revision tree, use the revisions' timestamp
101
rev = tree.repository.get_revision(tree.get_revision_id())
102
root_mtime = rev.timestamp
103
elif tree.get_root_id() is not None:
104
root_mtime = tree.get_file_mtime(tree.get_root_id())
111
stream = open(dest, 'wb')
112
# gzip file is used with an explicit fileobj so that
113
# the basename can be stored in the gzip file rather than
115
basename = os.path.basename(dest)
117
stream = gzip.GzipFile(basename, 'w', fileobj=stream, mtime=root_mtime)
119
# Python < 2.7 doesn't support the mtime argument
120
stream = gzip.GzipFile(basename, 'w', fileobj=stream)
121
ball = tarfile.open(None, 'w|', fileobj=stream)
122
export_tarball(tree, ball, root, subdir, filtered=filtered,
123
force_mtime=force_mtime)
127
def tbz_exporter(tree, dest, root, subdir, filtered=False, force_mtime=None):
128
"""Export this tree to a new tar file.
130
`dest` will be created holding the contents of this tree; if it
131
already exists, it will be clobbered, like with "tar -c".
134
ball = tarfile.open(None, 'w|bz2', sys.stdout)
136
# tarfile.open goes on to do 'os.getcwd() + dest' for opening
137
# the tar file. With dest being unicode, this throws UnicodeDecodeError
138
# unless we encode dest before passing it on. This works around
139
# upstream python bug http://bugs.python.org/issue8396
140
# (fixed in Python 2.6.5 and 2.7b1)
141
ball = tarfile.open(dest.encode(osutils._fs_enc), 'w:bz2')
142
export_tarball(tree, ball, root, subdir, filtered=filtered,
143
force_mtime=force_mtime)
147
def plain_tar_exporter(tree, dest, root, subdir, compression=None,
148
filtered=False, force_mtime=None):
149
"""Export this tree to a new tar file.
151
`dest` will be created holding the contents of this tree; if it
152
already exists, it will be clobbered, like with "tar -c".
157
stream = open(dest, 'wb')
158
ball = tarfile.open(None, 'w|', stream)
159
export_tarball(tree, ball, root, subdir, filtered=filtered,
160
force_mtime=force_mtime)
164
def tar_xz_exporter(tree, dest, root, subdir, filtered=False,
166
return tar_lzma_exporter(tree, dest, root, subdir, filtered=filtered,
167
force_mtime=force_mtime, compression_format="xz")
170
def tar_lzma_exporter(tree, dest, root, subdir, filtered=False, force_mtime=None, compression_format="alone"):
171
"""Export this tree to a new .tar.lzma file.
173
`dest` will be created holding the contents of this tree; if it
174
already exists, it will be clobbered, like with "tar -c".
177
raise errors.BzrError("Writing to stdout not supported for .tar.lzma")
181
except ImportError, e:
182
raise errors.DependencyNotPresent('lzma', e)
184
stream = lzma.LZMAFile(dest.encode(osutils._fs_enc), 'w',
185
options={"format": compression_format})
186
ball = tarfile.open(None, 'w:', fileobj=stream)
187
export_tarball(tree, ball, root, subdir, filtered=filtered,
188
force_mtime=force_mtime)