/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5724.1.3 by John Arbash Meinel
Change the exporters to ensure that we are writing the data out in binary mode.
1
# Copyright (C) 2005, 2006, 2008-2011 Canonical Ltd
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
2
#
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
7
#
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
12
#
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
16
6006.3.4 by Martin Pool
Support exporting tarballs from ContentFilterTree
17
"""Export a tree to a tarball."""
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
18
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
19
import os
3368.2.32 by Ian Clatworthy
add --filters to export command
20
import StringIO
21
import sys
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
22
import tarfile
3408.7.1 by Martin Pool
Support tarball export to stdout
23
5718.1.1 by Jelmer Vernooij
Fix import of BzrError.
24
from bzrlib import (
25
    errors,
26
    osutils,
27
    )
3613.2.2 by Robert Collins
Refactor exporters to remove obvious duplication to a helper function.
28
from bzrlib.export import _export_iter_entries
5718.5.2 by Jelmer Vernooij
Factor out export_tarball.
29
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
30
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
31
def prepare_tarball_item(tree, root, final_path, tree_path, entry, force_mtime=None):
5952.1.17 by geoffreyfishing at gmail
Renamed export item function in tar exporter.
32
    """Prepare a tarball item for exporting
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
33
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
34
    :param tree: Tree to export
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
35
    :param final_path: Final path to place item
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
36
    :param tree_path: Path for the entry in the tree
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
37
    :param entry: Entry to export
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
38
    :param force_mtime: Option mtime to force, instead of using tree
39
        timestamps.
40
5952.1.17 by geoffreyfishing at gmail
Renamed export item function in tar exporter.
41
    Returns a (tarinfo, fileobj) tuple
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
42
    """
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
43
    filename = osutils.pathjoin(root, final_path).encode('utf8')
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
44
    item = tarfile.TarInfo(filename)
45
    if force_mtime is not None:
46
        item.mtime = force_mtime
47
    else:
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
48
        item.mtime = tree.get_file_mtime(entry.file_id, tree_path)
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
49
    if entry.kind == "file":
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
50
        item.type = tarfile.REGTYPE
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
51
        if tree.is_executable(entry.file_id, tree_path):
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
52
            item.mode = 0755
53
        else:
54
            item.mode = 0644
6006.3.4 by Martin Pool
Support exporting tarballs from ContentFilterTree
55
        # This brings the whole file into memory, but that's almost needed for
56
        # the tarfile contract, which wants the size of the file up front.  We
57
        # want to make sure it doesn't change, and we need to read it in one
58
        # go for content filtering.
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
59
        content = tree.get_file_text(entry.file_id, tree_path)
6006.3.4 by Martin Pool
Support exporting tarballs from ContentFilterTree
60
        item.size = len(content)
61
        fileobj = StringIO.StringIO(content)
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
62
    elif entry.kind == "directory":
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
63
        item.type = tarfile.DIRTYPE
64
        item.name += '/'
65
        item.size = 0
66
        item.mode = 0755
67
        fileobj = None
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
68
    elif entry.kind == "symlink":
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
69
        item.type = tarfile.SYMTYPE
70
        item.size = 0
71
        item.mode = 0755
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
72
        item.linkname = tree.get_symlink_target(entry.file_id, tree_path)
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
73
        fileobj = None
74
    else:
5952.1.26 by Vincent Ladeuil
Fix the test failure, streams should be closed. In the right order.
75
        raise errors.BzrError("don't know how to export {%s} of kind %r"
5952.1.18 by geoffreyfishing at gmail
Fixed line ending problems.
76
                              % (entry.file_id, entry.kind))
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
77
    return (item, fileobj)
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
78
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
79
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
80
def export_tarball_generator(tree, ball, root, subdir=None, force_mtime=None):
5967.6.3 by Martin Pool
Further shrink export code
81
    """Export tree contents to a tarball.
82
83
    :returns: A generator that will repeatedly produce None as each file is
84
        emitted.  The entire generator must be consumed to complete writing
85
        the file.
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
86
87
    :param tree: Tree to export
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
88
5967.6.3 by Martin Pool
Further shrink export code
89
    :param ball: Tarball to export to; it will be closed when writing is
90
        complete.
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
91
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
92
    :param subdir: Sub directory to export
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
93
94
    :param force_mtime: Option mtime to force, instead of using tree
95
        timestamps.
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
96
    """
5967.6.4 by Martin Pool
Close tarball from finally block (thanks jam)
97
    try:
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
98
        for final_path, tree_path, entry in _export_iter_entries(tree, subdir):
5967.6.4 by Martin Pool
Close tarball from finally block (thanks jam)
99
            (item, fileobj) = prepare_tarball_item(
6331.2.1 by Jelmer Vernooij
Consistently pass tree path when exporting.
100
                tree, root, final_path, tree_path, entry, force_mtime)
5967.6.4 by Martin Pool
Close tarball from finally block (thanks jam)
101
            ball.addfile(item, fileobj)
102
            yield
103
    finally:
104
        ball.close()
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
105
106
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
107
def tgz_exporter_generator(tree, dest, root, subdir, force_mtime=None,
108
    fileobj=None):
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
109
    """Export this tree to a new tar file.
110
111
    `dest` will be created holding the contents of this tree; if it
112
    already exists, it will be clobbered, like with "tar -c".
113
    """
114
    import gzip
5718.5.16 by Jelmer Vernooij
Use revision tree timestamp if possible.
115
    if force_mtime is not None:
116
        root_mtime = force_mtime
117
    elif (getattr(tree, "repository", None) and
118
          getattr(tree, "get_revision_id", None)):
119
        # If this is a revision tree, use the revisions' timestamp
120
        rev = tree.repository.get_revision(tree.get_revision_id())
121
        root_mtime = rev.timestamp
122
    elif tree.get_root_id() is not None:
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
123
        root_mtime = tree.get_file_mtime(tree.get_root_id())
5718.5.9 by Jelmer Vernooij
Add test for export zip to stdout.
124
    else:
5718.5.23 by Jelmer Vernooij
Leave default timestamp.
125
        root_mtime = None
5861.2.2 by Wouter van Heyst
Heavy handed approach to ensuring all streams are closed
126
127
    is_stdout = False
6018.1.1 by Martin Pool
Avoid unset local variable
128
    basename = None
5952.1.11 by geoffreyfishing at gmail
Implemented fileobj on tgz_exporter.
129
    if fileobj is not None:
130
        stream = fileobj
131
    elif dest == '-':
5718.5.22 by Jelmer Vernooij
Cope with mtime not always being available.
132
        stream = sys.stdout
5861.2.2 by Wouter van Heyst
Heavy handed approach to ensuring all streams are closed
133
        is_stdout = True
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
134
    else:
5724.1.4 by John Arbash Meinel
actually make the plain_tar export work again.
135
        stream = open(dest, 'wb')
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
136
        # gzip file is used with an explicit fileobj so that
137
        # the basename can be stored in the gzip file rather than
138
        # dest. (bug 102234)
5718.5.22 by Jelmer Vernooij
Cope with mtime not always being available.
139
        basename = os.path.basename(dest)
140
    try:
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
141
        zipstream = gzip.GzipFile(basename, 'w', fileobj=stream,
5952.1.18 by geoffreyfishing at gmail
Fixed line ending problems.
142
                                  mtime=root_mtime)
5718.5.22 by Jelmer Vernooij
Cope with mtime not always being available.
143
    except TypeError:
144
        # Python < 2.7 doesn't support the mtime argument
5861.2.2 by Wouter van Heyst
Heavy handed approach to ensuring all streams are closed
145
        zipstream = gzip.GzipFile(basename, 'w', fileobj=stream)
146
    ball = tarfile.open(None, 'w|', fileobj=zipstream)
5967.6.3 by Martin Pool
Further shrink export code
147
    for _ in export_tarball_generator(
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
148
        tree, ball, root, subdir, force_mtime):
5952.1.15 by geoffreyfishing at gmail
Major code cleanup.
149
        yield
5952.1.26 by Vincent Ladeuil
Fix the test failure, streams should be closed. In the right order.
150
    # Closing zipstream may trigger writes to stream
5952.1.15 by geoffreyfishing at gmail
Major code cleanup.
151
    zipstream.close()
152
    if not is_stdout:
5952.1.26 by Vincent Ladeuil
Fix the test failure, streams should be closed. In the right order.
153
        # Now we can safely close the stream
5952.1.15 by geoffreyfishing at gmail
Major code cleanup.
154
        stream.close()
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
155
156
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
157
def tbz_exporter_generator(tree, dest, root, subdir,
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
158
                           force_mtime=None, fileobj=None):
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
159
    """Export this tree to a new tar file.
160
161
    `dest` will be created holding the contents of this tree; if it
162
    already exists, it will be clobbered, like with "tar -c".
163
    """
5952.1.12 by geoffreyfishing at gmail
Implemented fileobj in tbz_exporter.
164
    if fileobj is not None:
165
        ball = tarfile.open(None, 'w|bz2', fileobj)
166
    elif dest == '-':
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
167
        ball = tarfile.open(None, 'w|bz2', sys.stdout)
168
    else:
5967.6.3 by Martin Pool
Further shrink export code
169
        # tarfile.open goes on to do 'os.getcwd() + dest' for opening the
170
        # tar file. With dest being unicode, this throws UnicodeDecodeError
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
171
        # unless we encode dest before passing it on. This works around
5967.6.3 by Martin Pool
Further shrink export code
172
        # upstream python bug http://bugs.python.org/issue8396 (fixed in
173
        # Python 2.6.5 and 2.7b1)
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
174
        ball = tarfile.open(dest.encode(osutils._fs_enc), 'w:bz2')
5967.6.3 by Martin Pool
Further shrink export code
175
    return export_tarball_generator(
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
176
        tree, ball, root, subdir, force_mtime)
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
177
178
179
def plain_tar_exporter_generator(tree, dest, root, subdir, compression=None,
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
180
    force_mtime=None, fileobj=None):
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
181
    """Export this tree to a new tar file.
182
183
    `dest` will be created holding the contents of this tree; if it
184
    already exists, it will be clobbered, like with "tar -c".
185
    """
5952.1.13 by geoffreyfishing at gmail
Adjusted .tar.lzma
186
    if fileobj is not None:
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
187
        stream = fileobj
5952.1.13 by geoffreyfishing at gmail
Adjusted .tar.lzma
188
    elif dest == '-':
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
189
        stream = sys.stdout
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
190
    else:
5724.1.3 by John Arbash Meinel
Change the exporters to ensure that we are writing the data out in binary mode.
191
        stream = open(dest, 'wb')
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
192
    ball = tarfile.open(None, 'w|', stream)
5967.6.3 by Martin Pool
Further shrink export code
193
    return export_tarball_generator(
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
194
        tree, ball, root, subdir, force_mtime)
195
196
197
def tar_xz_exporter_generator(tree, dest, root, subdir,
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
198
                              force_mtime=None, fileobj=None):
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
199
    return tar_lzma_exporter_generator(tree, dest, root, subdir,
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
200
                                       force_mtime, fileobj, "xz")
201
202
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
203
def tar_lzma_exporter_generator(tree, dest, root, subdir,
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
204
                      force_mtime=None, fileobj=None,
205
                                compression_format="alone"):
5718.5.17 by Jelmer Vernooij
Support tar.lzma.
206
    """Export this tree to a new .tar.lzma file.
5718.5.10 by Jelmer Vernooij
Support creating .tar.xz files.
207
208
    `dest` will be created holding the contents of this tree; if it
209
    already exists, it will be clobbered, like with "tar -c".
210
    """
5718.5.11 by Jelmer Vernooij
Tests, tests, tests.
211
    if dest == '-':
5718.5.17 by Jelmer Vernooij
Support tar.lzma.
212
        raise errors.BzrError("Writing to stdout not supported for .tar.lzma")
5718.5.11 by Jelmer Vernooij
Tests, tests, tests.
213
5952.1.13 by geoffreyfishing at gmail
Adjusted .tar.lzma
214
    if fileobj is not None:
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
215
        raise errors.BzrError(
216
            "Writing to fileobject not supported for .tar.lzma")
5718.5.10 by Jelmer Vernooij
Support creating .tar.xz files.
217
    try:
218
        import lzma
219
    except ImportError, e:
220
        raise errors.DependencyNotPresent('lzma', e)
221
5718.5.17 by Jelmer Vernooij
Support tar.lzma.
222
    stream = lzma.LZMAFile(dest.encode(osutils._fs_enc), 'w',
5967.6.3 by Martin Pool
Further shrink export code
223
        options={"format": compression_format})
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
224
    ball = tarfile.open(None, 'w:', fileobj=stream)
5967.6.3 by Martin Pool
Further shrink export code
225
    return export_tarball_generator(
6006.3.7 by Martin Pool
Remove duplicated content-filtering code from exporters
226
        tree, ball, root, subdir, force_mtime=force_mtime)