/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/plugins/fastimport/helpers.py

  • Committer: Breezy landing bot
  • Author(s): Colin Watson
  • Date: 2020-11-16 21:47:08 UTC
  • mfrom: (7521.1.1 remove-lp-workaround)
  • Revision ID: breezy.the.bot@gmail.com-20201116214708-jos209mgxi41oy15
Remove breezy.git workaround for bazaar.launchpad.net.

Merged from https://code.launchpad.net/~cjwatson/brz/remove-lp-workaround/+merge/393710

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008 Canonical Ltd
 
2
#
 
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.
 
7
#
 
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.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 
 
16
"""Miscellaneous useful stuff."""
 
17
 
 
18
import stat
 
19
 
 
20
from ... import (
 
21
    controldir,
 
22
    )
 
23
 
 
24
 
 
25
def escape_commit_message(message):
 
26
    """Replace xml-incompatible control characters."""
 
27
    # This really ought to be provided by breezy.
 
28
    # Code copied from breezy.commit.
 
29
 
 
30
    # Python strings can include characters that can't be
 
31
    # represented in well-formed XML; escape characters that
 
32
    # aren't listed in the XML specification
 
33
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
 
34
    import re
 
35
    message, _ = re.subn(
 
36
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
 
37
        lambda match: match.group(0).encode('unicode_escape'),
 
38
        message)
 
39
    return message
 
40
 
 
41
 
 
42
def best_format_for_objects_in_a_repository(repo):
 
43
    """Find the high-level format for branches and trees given a repository.
 
44
 
 
45
    When creating branches and working trees within a repository, Bazaar
 
46
    defaults to using the default format which may not be the best choice.
 
47
    This routine does a reverse lookup of the high-level format registry
 
48
    to find the high-level format that a shared repository was most likely
 
49
    created via.
 
50
 
 
51
    :return: the BzrDirFormat or None if no matches were found.
 
52
    """
 
53
    # Based on code from breezy/info.py ...
 
54
    repo_format = repo._format
 
55
    candidates = []
 
56
    non_aliases = set(controldir.format_registry.keys())
 
57
    non_aliases.difference_update(controldir.format_registry.aliases())
 
58
    for key in non_aliases:
 
59
        format = controldir.format_registry.make_controldir(key)
 
60
        # LocalGitBzrDirFormat has no repository_format
 
61
        if hasattr(format, "repository_format"):
 
62
            if format.repository_format == repo_format:
 
63
                candidates.append((key, format))
 
64
    if len(candidates):
 
65
        # Assume the first one. Is there any reason not to do that?
 
66
        name, format = candidates[0]
 
67
        return format
 
68
    else:
 
69
        return None
 
70
 
 
71
 
 
72
def open_destination_directory(location, format=None, verbose=True):
 
73
    """Open a destination directory and return the BzrDir.
 
74
 
 
75
    If destination has a control directory, it will be returned.
 
76
    Otherwise, the destination should be empty or non-existent and
 
77
    a shared repository will be created there.
 
78
 
 
79
    :param location: the destination directory
 
80
    :param format: the format to use or None for the default
 
81
    :param verbose: display the format used if a repository is created.
 
82
    :return: BzrDir for the destination
 
83
    """
 
84
    import os
 
85
    from ... import controldir, errors, trace, transport
 
86
    try:
 
87
        control, relpath = controldir.ControlDir.open_containing(location)
 
88
        # XXX: Check the relpath is None here?
 
89
        return control
 
90
    except errors.NotBranchError:
 
91
        pass
 
92
 
 
93
    # If the directory exists, check it is empty. Otherwise create it.
 
94
    if os.path.exists(location):
 
95
        contents = os.listdir(location)
 
96
        if contents:
 
97
            errors.CommandError("Destination must have a .bzr directory, "
 
98
                                   " not yet exist or be empty - files found in %s" % (location,))
 
99
    else:
 
100
        try:
 
101
            os.mkdir(location)
 
102
        except IOError as ex:
 
103
            raise errors.CommandError(
 
104
                "Unable to create %s: %s" % (location, ex))
 
105
 
 
106
    # Create a repository for the nominated format.
 
107
    trace.note("Creating destination repository ...")
 
108
    if format is None:
 
109
        format = controldir.format_registry.make_controldir('default')
 
110
    to_transport = transport.get_transport(location)
 
111
    to_transport.ensure_base()
 
112
    control = format.initialize_on_transport(to_transport)
 
113
    repo = control.create_repository(shared=True)
 
114
    if verbose:
 
115
        from ...info import show_bzrdir_info
 
116
        show_bzrdir_info(repo.controldir, verbose=0)
 
117
    return control
 
118
 
 
119
 
 
120
def kind_to_mode(kind, executable):
 
121
    if kind == "file":
 
122
        if executable is True:
 
123
            return stat.S_IFREG | 0o755
 
124
        elif executable is False:
 
125
            return stat.S_IFREG | 0o644
 
126
        else:
 
127
            raise AssertionError("Executable %r invalid" % executable)
 
128
    elif kind == "symlink":
 
129
        return stat.S_IFLNK
 
130
    elif kind == "directory":
 
131
        return stat.S_IFDIR
 
132
    elif kind == "tree-reference":
 
133
        return 0o160000
 
134
    else:
 
135
        raise AssertionError("Unknown file kind '%s'" % kind)
 
136
 
 
137
 
 
138
def mode_to_kind(mode):
 
139
    # Note: Output from git-fast-export slightly different to spec
 
140
    if mode in (0o644, 0o100644):
 
141
        return 'file', False
 
142
    elif mode in (0o755, 0o100755):
 
143
        return 'file', True
 
144
    elif mode == 0o040000:
 
145
        return 'directory', False
 
146
    elif mode == 0o120000:
 
147
        return 'symlink', False
 
148
    elif mode == 0o160000:
 
149
        return 'tree-reference', False
 
150
    else:
 
151
        raise AssertionError("invalid mode %o" % mode)
 
152
 
 
153
 
 
154
def binary_stream(stream):
 
155
    """Ensure a stream is binary on Windows.
 
156
 
 
157
    :return: the stream
 
158
    """
 
159
    try:
 
160
        import os
 
161
        if os.name == 'nt':
 
162
            fileno = getattr(stream, 'fileno', None)
 
163
            if fileno:
 
164
                no = fileno()
 
165
                if no >= 0:     # -1 means we're working as subprocess
 
166
                    import msvcrt
 
167
                    msvcrt.setmode(no, os.O_BINARY)
 
168
    except ImportError:
 
169
        pass
 
170
    return stream
 
171
 
 
172
 
 
173
def single_plural(n, single, plural):
 
174
    """Return a single or plural form of a noun based on number."""
 
175
    if n == 1:
 
176
        return single
 
177
    else:
 
178
        return plural