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