~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/export/dir_exporter.py

  • Committer: Andrew Bennetts
  • Date: 2010-01-12 03:53:21 UTC
  • mfrom: (4948 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4964.
  • Revision ID: andrew.bennetts@canonical.com-20100112035321-hofpz5p10224ryj3
Merge lp:bzr, resolving conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005, 2009 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Export a Tree to a non-versioned directory.
18
18
"""
19
19
 
20
 
 
 
20
import errno
21
21
import os
 
22
import StringIO
22
23
 
23
24
from bzrlib import errors, osutils
24
25
from bzrlib.export import _export_iter_entries
 
26
from bzrlib.filters import (
 
27
    ContentFilterContext,
 
28
    filtered_output_bytes,
 
29
    )
25
30
from bzrlib.trace import mutter
26
31
 
27
32
 
28
 
def dir_exporter(tree, dest, root, subdir):
 
33
def dir_exporter(tree, dest, root, subdir, filtered=False):
29
34
    """Export this tree to a new directory.
30
35
 
31
36
    `dest` should not exist, and will be created holding the
38
43
           left in a half-assed state.
39
44
    """
40
45
    mutter('export version %r', tree)
41
 
    os.mkdir(dest)
 
46
    try:
 
47
        os.mkdir(dest)
 
48
    except OSError, e:
 
49
        if e.errno == errno.EEXIST:
 
50
            # check if directory empty
 
51
            if os.listdir(dest) != []:
 
52
                raise errors.BzrError("Can't export tree to non-empty directory.")
 
53
        else:
 
54
            raise
 
55
    # Iterate everything, building up the files we will want to export, and
 
56
    # creating the directories and symlinks that we need.
 
57
    # This tracks (file_id, (destination_path, executable))
 
58
    # This matches the api that tree.iter_files_bytes() wants
 
59
    # Note in the case of revision trees, this does trigger a double inventory
 
60
    # lookup, hopefully it isn't too expensive.
 
61
    to_fetch = []
42
62
    for dp, ie in _export_iter_entries(tree, subdir):
43
63
        fullpath = osutils.pathjoin(dest, dp)
44
64
        if ie.kind == "file":
45
 
            fileobj = tree.get_file(ie.file_id)
46
 
            osutils.pumpfile(fileobj, file(fullpath, 'wb'))
47
 
            if tree.is_executable(ie.file_id):
48
 
                os.chmod(fullpath, 0755)
 
65
            to_fetch.append((ie.file_id, (dp, tree.is_executable(ie.file_id))))
49
66
        elif ie.kind == "directory":
50
67
            os.mkdir(fullpath)
51
68
        elif ie.kind == "symlink":
52
69
            try:
53
 
                os.symlink(ie.symlink_target, fullpath)
 
70
                symlink_target = tree.get_symlink_target(ie.file_id)
 
71
                os.symlink(symlink_target, fullpath)
54
72
            except OSError,e:
55
73
                raise errors.BzrError(
56
74
                    "Failed to create symlink %r -> %r, error: %s"
57
 
                    % (fullpath, self.symlink_target, e))
 
75
                    % (fullpath, symlink_target, e))
58
76
        else:
59
77
            raise errors.BzrError("don't know how to export {%s} of kind %r" %
60
78
               (ie.file_id, ie.kind))
 
79
    # The data returned here can be in any order, but we've already created all
 
80
    # the directories
 
81
    flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | getattr(os, 'O_BINARY', 0)
 
82
    for (relpath, executable), chunks in tree.iter_files_bytes(to_fetch):
 
83
        if filtered:
 
84
            filters = tree._content_filter_stack(relpath)
 
85
            context = ContentFilterContext(relpath, tree, ie)
 
86
            chunks = filtered_output_bytes(chunks, filters, context)
 
87
        fullpath = osutils.pathjoin(dest, relpath)
 
88
        # We set the mode and let the umask sort out the file info
 
89
        mode = 0666
 
90
        if executable:
 
91
            mode = 0777
 
92
        out = os.fdopen(os.open(fullpath, flags, mode), 'wb')
 
93
        try:
 
94
            out.writelines(chunks)
 
95
        finally:
 
96
            out.close()