/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/archive/zip.py

  • Committer: Jelmer Vernooij
  • Date: 2020-04-05 19:11:34 UTC
  • mto: (7490.7.16 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200405191134-0aebh8ikiwygxma5
Populate the .gitignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""Export a Tree to a non-versioned directory.
 
17
"""Export a Tree to a zip file.
18
18
"""
19
19
 
 
20
from __future__ import absolute_import
 
21
 
 
22
from contextlib import closing
20
23
import os
21
24
import stat
 
25
import sys
 
26
import tempfile
22
27
import time
23
28
import zipfile
24
29
 
25
 
from bzrlib import (
 
30
from .. import (
26
31
    osutils,
27
32
    )
28
 
from bzrlib.export import _export_iter_entries
29
 
from bzrlib.filters import (
30
 
    ContentFilterContext,
31
 
    filtered_output_bytes,
32
 
    )
33
 
from bzrlib.trace import mutter
34
 
 
35
 
 
36
 
# Windows expects this bit to be set in the 'external_attr' section
37
 
# Or it won't consider the entry a directory
 
33
from ..export import _export_iter_entries
 
34
from ..trace import mutter
 
35
 
 
36
 
 
37
# Windows expects this bit to be set in the 'external_attr' section,
 
38
# or it won't consider the entry a directory.
38
39
ZIP_DIRECTORY_BIT = (1 << 4)
39
 
FILE_PERMISSIONS = (0644 << 16)
 
40
FILE_PERMISSIONS = (0o644 << 16)
 
41
DIR_PERMISSIONS = (0o755 << 16)
40
42
 
41
43
_FILE_ATTR = stat.S_IFREG | FILE_PERMISSIONS
42
 
_DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT
43
 
 
44
 
 
45
 
def zip_exporter(tree, dest, root, subdir, filtered=False,
46
 
                 per_file_timestamps=False):
 
44
_DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT | DIR_PERMISSIONS
 
45
 
 
46
 
 
47
def zip_archive_generator(tree, dest, root, subdir=None,
 
48
                          force_mtime=None):
47
49
    """ Export this tree to a new zip file.
48
50
 
49
51
    `dest` will be created holding the contents of this tree; if it
50
52
    already exists, it will be overwritten".
51
53
    """
52
 
    mutter('export version %r', tree)
53
 
 
54
 
    now = time.localtime()[:6]
55
 
 
56
54
    compression = zipfile.ZIP_DEFLATED
57
 
    zipf = zipfile.ZipFile(dest, "w", compression)
58
 
 
59
 
    try:
60
 
        for dp, ie in _export_iter_entries(tree, subdir):
61
 
            file_id = ie.file_id
62
 
            mutter("  export {%s} kind %s to %s", file_id, ie.kind, dest)
63
 
 
64
 
            # zipfile.ZipFile switches all paths to forward
65
 
            # slashes anyway, so just stick with that.
66
 
            if per_file_timestamps:
67
 
                mtime = tree.get_file_mtime(ie.file_id, dp)
68
 
            else:
69
 
                mtime = now
70
 
            filename = osutils.pathjoin(root, dp).encode('utf8')
71
 
            if ie.kind == "file":
72
 
                zinfo = zipfile.ZipInfo(
73
 
                            filename=filename,
74
 
                            date_time=mtime)
75
 
                zinfo.compress_type = compression
76
 
                zinfo.external_attr = _FILE_ATTR
77
 
                if filtered:
78
 
                    chunks = tree.get_file_lines(file_id)
79
 
                    filters = tree._content_filter_stack(dp)
80
 
                    context = ContentFilterContext(dp, tree, ie)
81
 
                    contents = filtered_output_bytes(chunks, filters, context)
82
 
                    content = ''.join(contents)
 
55
    with tempfile.SpooledTemporaryFile() as buf:
 
56
        with closing(zipfile.ZipFile(buf, "w", compression)) as zipf, \
 
57
                tree.lock_read():
 
58
            for dp, tp, ie in _export_iter_entries(tree, subdir):
 
59
                mutter("  export {%s} kind %s to %s", tp, ie.kind, dest)
 
60
 
 
61
                # zipfile.ZipFile switches all paths to forward
 
62
                # slashes anyway, so just stick with that.
 
63
                if force_mtime is not None:
 
64
                    mtime = force_mtime
83
65
                else:
84
 
                    content = tree.get_file_text(file_id)
85
 
                zipf.writestr(zinfo, content)
86
 
            elif ie.kind == "directory":
87
 
                # Directories must contain a trailing slash, to indicate
88
 
                # to the zip routine that they are really directories and
89
 
                # not just empty files.
90
 
                zinfo = zipfile.ZipInfo(
91
 
                            filename=filename + '/',
92
 
                            date_time=mtime)
93
 
                zinfo.compress_type = compression
94
 
                zinfo.external_attr = _DIR_ATTR
95
 
                zipf.writestr(zinfo,'')
96
 
            elif ie.kind == "symlink":
97
 
                zinfo = zipfile.ZipInfo(
98
 
                            filename=(filename + '.lnk'),
99
 
                            date_time=mtime)
100
 
                zinfo.compress_type = compression
101
 
                zinfo.external_attr = _FILE_ATTR
102
 
                zipf.writestr(zinfo, ie.symlink_target)
103
 
 
104
 
        zipf.close()
105
 
 
106
 
    except UnicodeEncodeError:
107
 
        zipf.close()
108
 
        os.remove(dest)
109
 
        from bzrlib.errors import BzrError
110
 
        raise BzrError("Can't export non-ascii filenames to zip")
 
66
                    mtime = tree.get_file_mtime(tp)
 
67
                date_time = time.localtime(mtime)[:6]
 
68
                filename = osutils.pathjoin(root, dp)
 
69
                if ie.kind == "file":
 
70
                    zinfo = zipfile.ZipInfo(
 
71
                        filename=filename,
 
72
                        date_time=date_time)
 
73
                    zinfo.compress_type = compression
 
74
                    zinfo.external_attr = _FILE_ATTR
 
75
                    content = tree.get_file_text(tp)
 
76
                    zipf.writestr(zinfo, content)
 
77
                elif ie.kind in ("directory", "tree-reference"):
 
78
                    # Directories must contain a trailing slash, to indicate
 
79
                    # to the zip routine that they are really directories and
 
80
                    # not just empty files.
 
81
                    zinfo = zipfile.ZipInfo(
 
82
                        filename=filename + '/',
 
83
                        date_time=date_time)
 
84
                    zinfo.compress_type = compression
 
85
                    zinfo.external_attr = _DIR_ATTR
 
86
                    zipf.writestr(zinfo, '')
 
87
                elif ie.kind == "symlink":
 
88
                    zinfo = zipfile.ZipInfo(
 
89
                        filename=(filename + '.lnk'),
 
90
                        date_time=date_time)
 
91
                    zinfo.compress_type = compression
 
92
                    zinfo.external_attr = _FILE_ATTR
 
93
                    zipf.writestr(zinfo, tree.get_symlink_target(tp))
 
94
        # Urgh, headers are written last since they include e.g. file size.
 
95
        # So we have to buffer it all :(
 
96
        buf.seek(0)
 
97
        for chunk in osutils.file_iterator(buf):
 
98
            yield chunk