~ubuntu-branches/ubuntu/natty/bzr-fastimport/natty

« back to all changes in this revision

Viewing changes to helpers.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2010-11-06 18:40:27 UTC
  • mfrom: (0.2.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20101106184027-20a7pc5543wks4fi
Tags: upstream-0.9.0+bzr279
ImportĀ upstreamĀ versionĀ 0.9.0+bzr279

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Miscellaneous useful stuff."""
18
18
 
19
 
 
20
 
def single_plural(n, single, plural):
21
 
    """Return a single or plural form of a noun based on number."""
22
 
    if n == 1:
23
 
        return single
24
 
    else:
25
 
        return plural
26
 
 
27
 
 
28
 
def defines_to_dict(defines):
29
 
    """Convert a list of definition strings to a dictionary."""
30
 
    if defines is None:
31
 
        return None
32
 
    result = {}
33
 
    for define in defines:
34
 
        kv = define.split('=', 1)
35
 
        if len(kv) == 1:
36
 
            result[define.strip()] = 1
37
 
        else:
38
 
            result[kv[0].strip()] = kv[1].strip()
39
 
    return result
40
 
 
41
 
 
42
 
def invert_dict(d):
43
 
    """Invert a dictionary with keys matching each value turned into a list."""
44
 
    # Based on recipe from ASPN
45
 
    result = {}
46
 
    for k, v in d.iteritems():
47
 
        keys = result.setdefault(v, [])
48
 
        keys.append(k)
49
 
    return result
50
 
 
51
 
 
52
 
def invert_dictset(d):
53
 
    """Invert a dictionary with keys matching a set of values, turned into lists."""
54
 
    # Based on recipe from ASPN
55
 
    result = {}
56
 
    for k, c in d.iteritems():
57
 
        for v in c:
58
 
            keys = result.setdefault(v, [])
59
 
            keys.append(k)
60
 
    return result
61
 
 
62
 
 
63
 
def _common_path_and_rest(l1, l2, common=[]):
64
 
    # From http://code.activestate.com/recipes/208993/
65
 
    if len(l1) < 1: return (common, l1, l2)
66
 
    if len(l2) < 1: return (common, l1, l2)
67
 
    if l1[0] != l2[0]: return (common, l1, l2)
68
 
    return _common_path_and_rest(l1[1:], l2[1:], common+[l1[0]])
69
 
 
70
 
 
71
 
def common_path(path1, path2):
72
 
    """Find the common bit of 2 paths."""
73
 
    return ''.join(_common_path_and_rest(path1, path2)[0])
74
 
 
75
 
 
76
 
def common_directory(paths):
77
 
    """Find the deepest common directory of a list of paths.
78
 
    
79
 
    :return: if no paths are provided, None is returned;
80
 
      if there is no common directory, '' is returned;
81
 
      otherwise the common directory with a trailing / is returned.
82
 
    """
83
 
    from bzrlib import osutils
84
 
    def get_dir_with_slash(path):
85
 
        if path == '' or path.endswith('/'):
86
 
            return path
87
 
        else:
88
 
            dirname, basename = osutils.split(path)
89
 
            if dirname == '':
90
 
                return dirname
91
 
            else:
92
 
                return dirname + '/'
93
 
 
94
 
    if not paths:
95
 
        return None
96
 
    elif len(paths) == 1:
97
 
        return get_dir_with_slash(paths[0])
98
 
    else:
99
 
        common = common_path(paths[0], paths[1])
100
 
        for path in paths[2:]:
101
 
            common = common_path(common, path)
102
 
        return get_dir_with_slash(common)
 
19
import stat
103
20
 
104
21
 
105
22
def escape_commit_message(message):
106
23
    """Replace xml-incompatible control characters."""
107
24
    # This really ought to be provided by bzrlib.
108
25
    # Code copied from bzrlib.commit.
109
 
    
 
26
 
110
27
    # Python strings can include characters that can't be
111
28
    # represented in well-formed XML; escape characters that
112
29
    # aren't listed in the XML specification
119
36
    return message
120
37
 
121
38
 
122
 
def binary_stream(stream):
123
 
    """Ensure a stream is binary on Windows.
124
 
 
125
 
    :return: the stream
126
 
    """
127
 
    try:
128
 
        import os
129
 
        if os.name == 'nt':
130
 
            fileno = getattr(stream, 'fileno', None)
131
 
            if fileno:
132
 
                no = fileno()
133
 
                if no >= 0:     # -1 means we're working as subprocess
134
 
                    import msvcrt
135
 
                    msvcrt.setmode(no, os.O_BINARY)
136
 
    except ImportError:
137
 
        pass
138
 
    return stream
139
 
 
140
 
 
141
39
def best_format_for_objects_in_a_repository(repo):
142
40
    """Find the high-level format for branches and trees given a repository.
143
41
 
215
113
        from bzrlib.info import show_bzrdir_info
216
114
        show_bzrdir_info(repo.bzrdir, verbose=0)
217
115
    return control
 
116
 
 
117
 
 
118
def kind_to_mode(kind, executable):
 
119
    if kind == "file":
 
120
        if executable == True:
 
121
            return stat.S_IFREG | 0755
 
122
        elif executable == False:
 
123
            return stat.S_IFREG | 0644
 
124
        else:
 
125
            raise AssertionError("Executable %r invalid" % executable)
 
126
    elif kind == "symlink":
 
127
        return stat.S_IFLNK
 
128
    elif kind == "directory":
 
129
        return stat.S_IFDIR
 
130
    elif kind == "tree-reference":
 
131
        return 0160000
 
132
    else:
 
133
        raise AssertionError("Unknown file kind '%s'" % kind)
 
134
 
 
135
 
 
136
def mode_to_kind(mode):
 
137
    # Note: Output from git-fast-export slightly different to spec
 
138
    if mode in (0644, 0100644):
 
139
        return 'file', False
 
140
    elif mode in (0755, 0100755):
 
141
        return 'file', True
 
142
    elif mode == 0040000:
 
143
        return 'directory', False
 
144
    elif mode == 0120000:
 
145
        return 'symlink', False
 
146
    elif mode == 0160000:
 
147
        return 'tree-reference', False
 
148
    else:
 
149
        raise AssertionError("invalid mode %o" % mode)