/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
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
17
"""Export a Tree to a non-versioned directory."""
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
3368.2.32 by Ian Clatworthy
add --filters to export command
29
from bzrlib.filters import (
30
    ContentFilterContext,
31
    filtered_output_bytes,
32
    )
5718.5.2 by Jelmer Vernooij
Factor out export_tarball.
33
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
34
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
35
def prepare_tarball_item(tree, root, final_path, entry, filtered=False,
5952.1.18 by geoffreyfishing at gmail
Fixed line ending problems.
36
                         force_mtime=None):
5952.1.17 by geoffreyfishing at gmail
Renamed export item function in tar exporter.
37
    """Prepare a tarball item for exporting
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
38
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
39
    :param tree: Tree to export
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
40
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
41
    :param final_path: Final path to place item
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
42
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
43
    :param entry: Entry to export
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
44
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
45
    :param filtered: Whether to apply filters
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
46
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
47
    :param force_mtime: Option mtime to force, instead of using tree
48
        timestamps.
49
5952.1.17 by geoffreyfishing at gmail
Renamed export item function in tar exporter.
50
    Returns a (tarinfo, fileobj) tuple
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
51
    """
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
52
    filename = osutils.pathjoin(root, final_path).encode('utf8')
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
53
    item = tarfile.TarInfo(filename)
54
    if force_mtime is not None:
55
        item.mtime = force_mtime
56
    else:
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
57
        item.mtime = tree.get_file_mtime(entry.file_id, final_path)
58
    if entry.kind == "file":
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
59
        item.type = tarfile.REGTYPE
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
60
        if tree.is_executable(entry.file_id):
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
61
            item.mode = 0755
62
        else:
63
            item.mode = 0644
64
        if filtered:
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
65
            chunks = tree.get_file_lines(entry.file_id)
66
            filters = tree._content_filter_stack(final_path)
67
            context = ContentFilterContext(final_path, tree, entry)
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
68
            contents = filtered_output_bytes(chunks, filters, context)
69
            content = ''.join(contents)
70
            item.size = len(content)
71
            fileobj = StringIO.StringIO(content)
72
        else:
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
73
            item.size = tree.get_file_size(entry.file_id)
74
            fileobj = tree.get_file(entry.file_id)
75
    elif entry.kind == "directory":
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
76
        item.type = tarfile.DIRTYPE
77
        item.name += '/'
78
        item.size = 0
79
        item.mode = 0755
80
        fileobj = None
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
81
    elif entry.kind == "symlink":
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
82
        item.type = tarfile.SYMTYPE
83
        item.size = 0
84
        item.mode = 0755
5952.1.14 by geoffreyfishing at gmail
Cleaned up code and removed unnecessary arguments.
85
        item.linkname = tree.get_symlink_target(entry.file_id)
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
86
        fileobj = None
87
    else:
5952.1.26 by Vincent Ladeuil
Fix the test failure, streams should be closed. In the right order.
88
        raise errors.BzrError("don't know how to export {%s} of kind %r"
5952.1.18 by geoffreyfishing at gmail
Fixed line ending problems.
89
                              % (entry.file_id, entry.kind))
5952.1.4 by geoffreyfishing at gmail
Cleaned up export_tarball_item.
90
    return (item, fileobj)
1185.31.12 by John Arbash Meinel
Refactored the export code to make it easier to add new export formats.
91
5967.6.2 by Martin Pool
Delete fairly useless and repetitive per-format export single-call functions.
92
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
93
def export_tarball_generator(tree, ball, root, subdir=None, filtered=False,
5952.1.18 by geoffreyfishing at gmail
Fixed line ending problems.
94
                   force_mtime=None):
5967.6.3 by Martin Pool
Further shrink export code
95
    """Export tree contents to a tarball.
96
97
    :returns: A generator that will repeatedly produce None as each file is
98
        emitted.  The entire generator must be consumed to complete writing
99
        the file.
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
100
101
    :param tree: Tree to export
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
102
5967.6.3 by Martin Pool
Further shrink export code
103
    :param ball: Tarball to export to; it will be closed when writing is
104
        complete.
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
105
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
106
    :param filtered: Whether to apply filters
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
107
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
108
    :param subdir: Sub directory to export
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
109
110
    :param force_mtime: Option mtime to force, instead of using tree
111
        timestamps.
5952.1.3 by geoffreyfishing at gmail
Updated code to requested format.
112
    """
5967.6.4 by Martin Pool
Close tarball from finally block (thanks jam)
113
    try:
114
        for final_path, entry in _export_iter_entries(tree, subdir):
115
            (item, fileobj) = prepare_tarball_item(
116
                tree, root, final_path, entry, filtered, force_mtime)
117
            ball.addfile(item, fileobj)
118
            yield
119
    finally:
120
        ball.close()
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
121
122
123
def tgz_exporter_generator(tree, dest, root, subdir, filtered=False,
124
                           force_mtime=None, fileobj=None):
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
125
    """Export this tree to a new tar file.
126
127
    `dest` will be created holding the contents of this tree; if it
128
    already exists, it will be clobbered, like with "tar -c".
129
    """
130
    import gzip
5718.5.16 by Jelmer Vernooij
Use revision tree timestamp if possible.
131
    if force_mtime is not None:
132
        root_mtime = force_mtime
133
    elif (getattr(tree, "repository", None) and
134
          getattr(tree, "get_revision_id", None)):
135
        # If this is a revision tree, use the revisions' timestamp
136
        rev = tree.repository.get_revision(tree.get_revision_id())
137
        root_mtime = rev.timestamp
138
    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.
139
        root_mtime = tree.get_file_mtime(tree.get_root_id())
5718.5.9 by Jelmer Vernooij
Add test for export zip to stdout.
140
    else:
5718.5.23 by Jelmer Vernooij
Leave default timestamp.
141
        root_mtime = None
5861.2.2 by Wouter van Heyst
Heavy handed approach to ensuring all streams are closed
142
143
    is_stdout = False
5952.1.11 by geoffreyfishing at gmail
Implemented fileobj on tgz_exporter.
144
    if fileobj is not None:
145
        stream = fileobj
146
    elif dest == '-':
5718.5.22 by Jelmer Vernooij
Cope with mtime not always being available.
147
        basename = None
148
        stream = sys.stdout
5861.2.2 by Wouter van Heyst
Heavy handed approach to ensuring all streams are closed
149
        is_stdout = True
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
150
    else:
5724.1.4 by John Arbash Meinel
actually make the plain_tar export work again.
151
        stream = open(dest, 'wb')
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
152
        # gzip file is used with an explicit fileobj so that
153
        # the basename can be stored in the gzip file rather than
154
        # dest. (bug 102234)
5718.5.22 by Jelmer Vernooij
Cope with mtime not always being available.
155
        basename = os.path.basename(dest)
156
    try:
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
157
        zipstream = gzip.GzipFile(basename, 'w', fileobj=stream,
5952.1.18 by geoffreyfishing at gmail
Fixed line ending problems.
158
                                  mtime=root_mtime)
5718.5.22 by Jelmer Vernooij
Cope with mtime not always being available.
159
    except TypeError:
160
        # 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
161
        zipstream = gzip.GzipFile(basename, 'w', fileobj=stream)
162
    ball = tarfile.open(None, 'w|', fileobj=zipstream)
5967.6.3 by Martin Pool
Further shrink export code
163
    for _ in export_tarball_generator(
164
        tree, ball, root, subdir, filtered, force_mtime):
5952.1.15 by geoffreyfishing at gmail
Major code cleanup.
165
        yield
5952.1.26 by Vincent Ladeuil
Fix the test failure, streams should be closed. In the right order.
166
    # Closing zipstream may trigger writes to stream
5952.1.15 by geoffreyfishing at gmail
Major code cleanup.
167
    zipstream.close()
168
    if not is_stdout:
5952.1.26 by Vincent Ladeuil
Fix the test failure, streams should be closed. In the right order.
169
        # Now we can safely close the stream
5952.1.15 by geoffreyfishing at gmail
Major code cleanup.
170
        stream.close()
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
171
172
173
def tbz_exporter_generator(tree, dest, root, subdir, filtered=False,
174
                           force_mtime=None, fileobj=None):
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
175
    """Export this tree to a new tar file.
176
177
    `dest` will be created holding the contents of this tree; if it
178
    already exists, it will be clobbered, like with "tar -c".
179
    """
5952.1.12 by geoffreyfishing at gmail
Implemented fileobj in tbz_exporter.
180
    if fileobj is not None:
181
        ball = tarfile.open(None, 'w|bz2', fileobj)
182
    elif dest == '-':
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
183
        ball = tarfile.open(None, 'w|bz2', sys.stdout)
184
    else:
5967.6.3 by Martin Pool
Further shrink export code
185
        # tarfile.open goes on to do 'os.getcwd() + dest' for opening the
186
        # tar file. With dest being unicode, this throws UnicodeDecodeError
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
187
        # unless we encode dest before passing it on. This works around
5967.6.3 by Martin Pool
Further shrink export code
188
        # upstream python bug http://bugs.python.org/issue8396 (fixed in
189
        # Python 2.6.5 and 2.7b1)
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
190
        ball = tarfile.open(dest.encode(osutils._fs_enc), 'w:bz2')
5967.6.3 by Martin Pool
Further shrink export code
191
    return export_tarball_generator(
192
        tree, ball, root, subdir, filtered, force_mtime)
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
193
194
195
def plain_tar_exporter_generator(tree, dest, root, subdir, compression=None,
196
                                 filtered=False, force_mtime=None,
197
                                 fileobj=None):
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
198
    """Export this tree to a new tar file.
199
200
    `dest` will be created holding the contents of this tree; if it
201
    already exists, it will be clobbered, like with "tar -c".
202
    """
5952.1.13 by geoffreyfishing at gmail
Adjusted .tar.lzma
203
    if fileobj is not None:
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
204
        stream = fileobj
5952.1.13 by geoffreyfishing at gmail
Adjusted .tar.lzma
205
    elif dest == '-':
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
206
        stream = sys.stdout
5718.5.4 by Jelmer Vernooij
fix timestamp in tgz files.
207
    else:
5724.1.3 by John Arbash Meinel
Change the exporters to ensure that we are writing the data out in binary mode.
208
        stream = open(dest, 'wb')
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
209
    ball = tarfile.open(None, 'w|', stream)
5967.6.3 by Martin Pool
Further shrink export code
210
    return export_tarball_generator(
211
        tree, ball, root, subdir, filtered, force_mtime)
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
212
213
214
def tar_xz_exporter_generator(tree, dest, root, subdir, filtered=False,
215
                              force_mtime=None, fileobj=None):
216
    return tar_lzma_exporter_generator(tree, dest, root, subdir, filtered,
217
                                       force_mtime, fileobj, "xz")
218
219
220
def tar_lzma_exporter_generator(tree, dest, root, subdir, filtered=False,
221
                      force_mtime=None, fileobj=None,
222
                                compression_format="alone"):
5718.5.17 by Jelmer Vernooij
Support tar.lzma.
223
    """Export this tree to a new .tar.lzma file.
5718.5.10 by Jelmer Vernooij
Support creating .tar.xz files.
224
225
    `dest` will be created holding the contents of this tree; if it
226
    already exists, it will be clobbered, like with "tar -c".
227
    """
5718.5.11 by Jelmer Vernooij
Tests, tests, tests.
228
    if dest == '-':
5718.5.17 by Jelmer Vernooij
Support tar.lzma.
229
        raise errors.BzrError("Writing to stdout not supported for .tar.lzma")
5718.5.11 by Jelmer Vernooij
Tests, tests, tests.
230
5952.1.13 by geoffreyfishing at gmail
Adjusted .tar.lzma
231
    if fileobj is not None:
5952.2.1 by Vincent Ladeuil
PEP8 tweaks, lines too long, spaces at end of lines.
232
        raise errors.BzrError(
233
            "Writing to fileobject not supported for .tar.lzma")
5718.5.10 by Jelmer Vernooij
Support creating .tar.xz files.
234
    try:
235
        import lzma
236
    except ImportError, e:
237
        raise errors.DependencyNotPresent('lzma', e)
238
5718.5.17 by Jelmer Vernooij
Support tar.lzma.
239
    stream = lzma.LZMAFile(dest.encode(osutils._fs_enc), 'w',
5967.6.3 by Martin Pool
Further shrink export code
240
        options={"format": compression_format})
5718.5.15 by Jelmer Vernooij
Only write out basename of the tarfile to the gzip file.
241
    ball = tarfile.open(None, 'w:', fileobj=stream)
5967.6.3 by Martin Pool
Further shrink export code
242
    return export_tarball_generator(
243
        tree, ball, root, subdir, filtered=filtered, force_mtime=force_mtime)