~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/export/tar_exporter.py

  • Committer: John Arbash Meinel
  • Date: 2011-05-11 11:35:28 UTC
  • mto: This revision was merged to the branch mainline in revision 5851.
  • Revision ID: john@arbash-meinel.com-20110511113528-qepibuwxicjrbb2h
Break compatibility with python <2.6.

This includes auditing the code for places where we were doing
explicit 'sys.version' checks and removing them as appropriate.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2008-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Export a Tree to a non-versioned directory.
18
18
"""
19
19
 
 
20
import os
20
21
import StringIO
21
22
import sys
22
23
import tarfile
23
 
import time
24
24
 
25
 
from bzrlib import export, osutils
 
25
from bzrlib import (
 
26
    errors,
 
27
    osutils,
 
28
    )
26
29
from bzrlib.export import _export_iter_entries
27
30
from bzrlib.filters import (
28
31
    ContentFilterContext,
29
32
    filtered_output_bytes,
30
33
    )
31
 
from bzrlib.trace import mutter
32
 
 
33
 
 
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.
37
 
 
38
 
    `dest` will be created holding the contents of this tree; if it
39
 
    already exists, it will be clobbered, like with "tar -c".
 
34
 
 
35
 
 
36
def export_tarball(tree, ball, root, subdir=None, filtered=False,
 
37
                   force_mtime=None):
 
38
    """Export tree contents to a tarball.
 
39
 
 
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
 
45
        tree timestamps.
40
46
    """
41
 
    mutter('export version %r', tree)
42
 
    now = time.time()
43
 
    compression = str(compression or '')
44
 
    if dest == '-':
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)
48
 
    else:
49
 
        if root is None:
50
 
            root = export.get_root_name(dest)
51
 
 
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)
58
 
 
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
 
52
        else:
63
53
            item.mtime = tree.get_file_mtime(ie.file_id, dp)
64
 
        else:
65
 
            item.mtime = now
66
54
        if ie.kind == "file":
67
55
            item.type = tarfile.REGTYPE
68
56
            if tree.is_executable(ie.file_id):
78
66
                item.size = len(content)
79
67
                fileobj = StringIO.StringIO(content)
80
68
            else:
81
 
                item.size = ie.text_size
 
69
                item.size = tree.get_file_size(ie.file_id)
82
70
                fileobj = tree.get_file(ie.file_id)
83
71
        elif ie.kind == "directory":
84
72
            item.type = tarfile.DIRTYPE
90
78
            item.type = tarfile.SYMTYPE
91
79
            item.size = 0
92
80
            item.mode = 0755
93
 
            item.linkname = ie.symlink_target
 
81
            item.linkname = tree.get_symlink_target(ie.file_id)
94
82
            fileobj = None
95
83
        else:
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)
99
 
    ball.close()
100
 
 
101
 
 
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)
106
 
 
107
 
 
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)
 
87
 
 
88
 
 
89
def tgz_exporter(tree, dest, root, subdir, filtered=False, force_mtime=None):
 
90
    """Export this tree to a new tar file.
 
91
 
 
92
    `dest` will be created holding the contents of this tree; if it
 
93
    already exists, it will be clobbered, like with "tar -c".
 
94
    """
 
95
    import gzip
 
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())
 
105
    else:
 
106
        root_mtime = None
 
107
    if dest == '-':
 
108
        basename = None
 
109
        stream = sys.stdout
 
110
    else:
 
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
 
114
        # dest. (bug 102234)
 
115
        basename = os.path.basename(dest)
 
116
    try:
 
117
        stream = gzip.GzipFile(basename, 'w', fileobj=stream, mtime=root_mtime)
 
118
    except TypeError:
 
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)
 
124
    ball.close()
 
125
 
 
126
 
 
127
def tbz_exporter(tree, dest, root, subdir, filtered=False, force_mtime=None):
 
128
    """Export this tree to a new tar file.
 
129
 
 
130
    `dest` will be created holding the contents of this tree; if it
 
131
    already exists, it will be clobbered, like with "tar -c".
 
132
    """
 
133
    if dest == '-':
 
134
        ball = tarfile.open(None, 'w|bz2', sys.stdout)
 
135
    else:
 
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)
 
144
    ball.close()
 
145
 
 
146
 
 
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.
 
150
 
 
151
    `dest` will be created holding the contents of this tree; if it
 
152
    already exists, it will be clobbered, like with "tar -c".
 
153
    """
 
154
    if dest == '-':
 
155
        stream = sys.stdout
 
156
    else:
 
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)
 
161
    ball.close()
 
162
 
 
163
 
 
164
def tar_xz_exporter(tree, dest, root, subdir, filtered=False,
 
165
                    force_mtime=None):
 
166
    return tar_lzma_exporter(tree, dest, root, subdir, filtered=filtered,
 
167
        force_mtime=force_mtime, compression_format="xz")
 
168
 
 
169
 
 
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.
 
172
 
 
173
    `dest` will be created holding the contents of this tree; if it
 
174
    already exists, it will be clobbered, like with "tar -c".
 
175
    """
 
176
    if dest == '-':
 
177
        raise errors.BzrError("Writing to stdout not supported for .tar.lzma")
 
178
 
 
179
    try:
 
180
        import lzma
 
181
    except ImportError, e:
 
182
        raise errors.DependencyNotPresent('lzma', e)
 
183
 
 
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)
 
189
    ball.close()
 
190