/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 bzrlib/export/dir_exporter.py

Merge bzr.dev, update to use new hooks.

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-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
18
18
 
19
19
import errno
20
20
import os
21
 
import time
22
21
 
23
22
from bzrlib import errors, osutils
24
23
from bzrlib.export import _export_iter_entries
25
 
from bzrlib.filters import (
26
 
    ContentFilterContext,
27
 
    filtered_output_bytes,
28
 
    )
29
 
from bzrlib.trace import mutter
30
 
 
31
 
 
32
 
def dir_exporter(tree, dest, root, subdir, filtered=False,
33
 
                 per_file_timestamps=False):
34
 
    """Export this tree to a new directory.
 
24
 
 
25
 
 
26
def dir_exporter_generator(tree, dest, root, subdir=None,
 
27
                           force_mtime=None, fileobj=None):
 
28
    """Return a generator that exports this tree to a new directory.
35
29
 
36
30
    `dest` should either not exist or should be empty. If it does not exist it
37
31
    will be created holding the contents of this tree.
38
32
 
 
33
    :param fileobj: Is not used in this exporter
 
34
 
39
35
    :note: If the export fails, the destination directory will be
40
36
           left in an incompletely exported state: export is not transactional.
41
37
    """
42
 
    mutter('export version %r', tree)
43
38
    try:
44
39
        os.mkdir(dest)
45
40
    except OSError, e:
46
41
        if e.errno == errno.EEXIST:
47
42
            # check if directory empty
48
43
            if os.listdir(dest) != []:
49
 
                raise errors.BzrError("Can't export tree to non-empty directory.")
 
44
                raise errors.BzrError(
 
45
                    "Can't export tree to non-empty directory.")
50
46
        else:
51
47
            raise
52
48
    # Iterate everything, building up the files we will want to export, and
56
52
    # Note in the case of revision trees, this does trigger a double inventory
57
53
    # lookup, hopefully it isn't too expensive.
58
54
    to_fetch = []
59
 
    for dp, ie in _export_iter_entries(tree, subdir):
 
55
    for dp, tp, ie in _export_iter_entries(tree, subdir):
60
56
        fullpath = osutils.pathjoin(dest, dp)
61
57
        if ie.kind == "file":
62
 
            to_fetch.append((ie.file_id, (dp, tree.is_executable(ie.file_id))))
 
58
            to_fetch.append((ie.file_id, (dp, tp, ie.file_id)))
63
59
        elif ie.kind == "directory":
64
60
            os.mkdir(fullpath)
65
61
        elif ie.kind == "symlink":
66
62
            try:
67
 
                symlink_target = tree.get_symlink_target(ie.file_id)
 
63
                symlink_target = tree.get_symlink_target(ie.file_id, tp)
68
64
                os.symlink(symlink_target, fullpath)
69
 
            except OSError,e:
 
65
            except OSError, e:
70
66
                raise errors.BzrError(
71
67
                    "Failed to create symlink %r -> %r, error: %s"
72
68
                    % (fullpath, symlink_target, e))
73
69
        else:
74
70
            raise errors.BzrError("don't know how to export {%s} of kind %r" %
75
71
               (ie.file_id, ie.kind))
 
72
 
 
73
        yield
76
74
    # The data returned here can be in any order, but we've already created all
77
75
    # the directories
78
76
    flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | getattr(os, 'O_BINARY', 0)
79
 
    now = time.time()
80
 
    for (relpath, executable), chunks in tree.iter_files_bytes(to_fetch):
81
 
        if filtered:
82
 
            filters = tree._content_filter_stack(relpath)
83
 
            context = ContentFilterContext(relpath, tree, ie)
84
 
            chunks = filtered_output_bytes(chunks, filters, context)
 
77
    for (relpath, treepath, file_id), chunks in tree.iter_files_bytes(to_fetch):
85
78
        fullpath = osutils.pathjoin(dest, relpath)
86
79
        # We set the mode and let the umask sort out the file info
87
80
        mode = 0666
88
 
        if executable:
 
81
        if tree.is_executable(file_id, treepath):
89
82
            mode = 0777
90
83
        out = os.fdopen(os.open(fullpath, flags, mode), 'wb')
91
84
        try:
92
85
            out.writelines(chunks)
93
86
        finally:
94
87
            out.close()
95
 
        if per_file_timestamps:
96
 
            mtime = tree.get_file_mtime(tree.path2id(relpath), relpath)
 
88
        if force_mtime is not None:
 
89
            mtime = force_mtime
97
90
        else:
98
 
            mtime = now
 
91
            mtime = tree.get_file_mtime(file_id, treepath)
99
92
        os.utime(fullpath, (mtime, mtime))
 
93
 
 
94
        yield