/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5452.4.3 by John Arbash Meinel
Merge bzr.dev to resolve bzr-2.3.txt (aka NEWS)
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
3398.1.3 by Ian Clatworthy
first cut at PropertiesProvider class
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, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3398.1.3 by Ian Clatworthy
first cut at PropertiesProvider class
16
7143.11.1 by Jelmer Vernooij
Remove some unused imports.
17
"""Rule-based definition of preferences for selected files in selected branches
3398.1.3 by Ian Clatworthy
first cut at PropertiesProvider class
18
3398.1.22 by Ian Clatworthy
minor tweaks
19
See ``bzr help rules`` for details.
3398.1.3 by Ian Clatworthy
first cut at PropertiesProvider class
20
"""
21
6621.5.2 by Martin
Fix bzrlib.rules to refer to external configobj
22
import configobj
23
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
24
from . import (
7336.2.1 by Martin
Split non-ini config methods to bedding
25
    bedding,
4913.5.24 by Gordon Tyler
Added cmdline.split function, which replaces commands.shlex_split_unicode.
26
    cmdline,
3398.1.30 by Ian Clatworthy
test unknown rules detection
27
    errors,
3398.1.3 by Ian Clatworthy
first cut at PropertiesProvider class
28
    globbing,
29
    osutils,
30
    )
31
32
3398.1.24 by Ian Clatworthy
make iter_search_rules a tree method
33
# Name of the file holding rules in a tree
34
RULES_TREE_FILENAME = ".bzrrules"
35
3398.1.28 by Ian Clatworthy
add namespace for rules
36
# Namespace prefix for per file preferences
3398.1.32 by Ian Clatworthy
namespace keyword changed to name
37
FILE_PREFS_PREFIX = 'name '
3398.1.28 by Ian Clatworthy
add namespace for rules
38
FILE_PREFS_PREFIX_LEN = len(FILE_PREFS_PREFIX)
39
4324.4.1 by Marius Kruger
Make it possible to blackboxtest rules
40
# The object providing default rules
41
_per_user_searcher = None
42
3398.1.24 by Ian Clatworthy
make iter_search_rules a tree method
43
6734.1.10 by Jelmer Vernooij
Move UnknownRules.
44
class UnknownRules(errors.BzrError):
45
46
    _fmt = ('Unknown rules detected: %(unknowns_str)s.')
47
48
    def __init__(self, unknowns):
49
        errors.BzrError.__init__(self, unknowns_str=", ".join(unknowns))
50
51
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
52
class _RulesSearcher(object):
53
    """An object that provides rule-based preferences."""
3398.1.13 by Ian Clatworthy
rename properties to attributes
54
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
55
    def get_items(self, path):
56
        """Return the preferences for a path as name,value tuples.
3398.1.13 by Ian Clatworthy
rename properties to attributes
57
58
        :param path: tree relative path
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
59
        :return: () if no rule matched, otherwise a sequence of name,value
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
60
          tuples.
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
61
        """
62
        raise NotImplementedError(self.get_items)
63
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
64
    def get_selected_items(self, path, names):
65
        """Return selected preferences for a path as name,value tuples.
66
67
        :param path: tree relative path
68
        :param names: the list of preferences to lookup
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
69
        :return: () if no rule matched, otherwise a sequence of name,value
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
70
          tuples. The sequence is the same length as names,
71
          tuple order matches the order in names, and
72
          undefined preferences are given the value None.
73
        """
74
        raise NotImplementedError(self.get_selected_items)
75
5802.4.1 by Martin Pool
Add and test _RulesSearcher.get_single_value
76
    def get_single_value(self, path, preference_name):
77
        """Get a single preference for a single file.
6744 by Jelmer Vernooij
Merge lp:~jelmer/brz/move-errors-knit.
78
5802.4.1 by Martin Pool
Add and test _RulesSearcher.get_single_value
79
        :returns: The string preference value, or None.
80
        """
81
        for key, value in self.get_selected_items(path, [preference_name]):
82
            return value
83
        return None
84
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
85
86
class _IniBasedRulesSearcher(_RulesSearcher):
87
88
    def __init__(self, inifile):
89
        """Construct a _RulesSearcher based on an ini file.
90
3398.1.24 by Ian Clatworthy
make iter_search_rules a tree method
91
        The content will be decoded as utf-8.
92
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
93
        :param inifile: the name of the file or a sequence of lines.
94
        """
5519.2.1 by Max Bowsher
Fix a slightly odd style of ConfigObj construction to match the prevailing style in bzrlib.
95
        self._cfg = configobj.ConfigObj(inifile, encoding='utf-8')
3398.1.28 by Ian Clatworthy
add namespace for rules
96
        sections = self._cfg.keys()
3946.1.1 by Ian Clatworthy
Multi-glob rules (Marius Kruger)
97
        patterns = []
3943.3.1 by Marius Kruger
add test and support for multi-glob rules
98
        self.pattern_to_section = {}
99
        for s in sections:
100
            if s.startswith(FILE_PREFS_PREFIX):
4913.5.24 by Gordon Tyler
Added cmdline.split function, which replaces commands.shlex_split_unicode.
101
                file_patterns = cmdline.split(s[FILE_PREFS_PREFIX_LEN:])
3943.3.1 by Marius Kruger
add test and support for multi-glob rules
102
                patterns.extend(file_patterns)
103
                for fp in file_patterns:
104
                    self.pattern_to_section[fp] = s
3398.1.28 by Ian Clatworthy
add namespace for rules
105
        if len(patterns) < len(sections):
106
            unknowns = [s for s in sections
7143.15.2 by Jelmer Vernooij
Run autopep8.
107
                        if not s.startswith(FILE_PREFS_PREFIX)]
6744 by Jelmer Vernooij
Merge lp:~jelmer/brz/move-errors-knit.
108
            raise UnknownRules(unknowns)
3398.1.28 by Ian Clatworthy
add namespace for rules
109
        elif patterns:
3398.1.17 by Ian Clatworthy
search less when files not present
110
            self._globster = globbing._OrderedGlobster(patterns)
111
        else:
112
            self._globster = None
3398.1.3 by Ian Clatworthy
first cut at PropertiesProvider class
113
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
114
    def get_items(self, path):
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
115
        """See _RulesSearcher.get_items."""
3398.1.17 by Ian Clatworthy
search less when files not present
116
        if self._globster is None:
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
117
            return ()
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
118
        pat = self._globster.match(path)
119
        if pat is None:
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
120
            return ()
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
121
        else:
3943.3.1 by Marius Kruger
add test and support for multi-glob rules
122
            all = self._cfg[self.pattern_to_section[pat]]
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
123
            return tuple(all.items())
124
125
    def get_selected_items(self, path, names):
126
        """See _RulesSearcher.get_selected_items."""
127
        if self._globster is None:
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
128
            return ()
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
129
        pat = self._globster.match(path)
130
        if pat is None:
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
131
            return ()
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
132
        else:
3943.3.1 by Marius Kruger
add test and support for multi-glob rules
133
            all = self._cfg[self.pattern_to_section[pat]]
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
134
            return tuple((k, all.get(k)) for k in names)
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
135
136
137
class _StackedRulesSearcher(_RulesSearcher):
138
139
    def __init__(self, searchers):
140
        """Construct a _RulesSearcher based on a stack of other ones.
141
142
        :param searchers: a sequence of searchers.
143
        """
144
        self.searchers = searchers
145
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
146
    def get_items(self, path):
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
147
        """See _RulesSearcher.get_items."""
3398.1.18 by Ian Clatworthy
add tests for _StackedRulesSearcher
148
        for searcher in self.searchers:
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
149
            result = searcher.get_items(path)
150
            if result:
151
                return result
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
152
        return ()
3398.1.34 by Ian Clatworthy
changed API design as requested by jam during review
153
154
    def get_selected_items(self, path, names):
155
        """See _RulesSearcher.get_selected_items."""
156
        for searcher in self.searchers:
157
            result = searcher.get_selected_items(path, names)
158
            if result:
159
                return result
3564.1.1 by Ian Clatworthy
RuleSearchers need to return () instead of []
160
        return ()
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
161
162
7336.2.1 by Martin
Split non-ini config methods to bedding
163
def rules_path():
164
    """Return the default rules file path."""
165
    return osutils.pathjoin(bedding.config_dir(), 'rules')
3398.1.15 by Ian Clatworthy
search branch.rules and bazaar.rules for preferences
166
167
4324.4.1 by Marius Kruger
Make it possible to blackboxtest rules
168
def reset_rules():
169
    global _per_user_searcher
7336.2.1 by Martin
Split non-ini config methods to bedding
170
    _per_user_searcher = _IniBasedRulesSearcher(rules_path())
4324.4.1 by Marius Kruger
Make it possible to blackboxtest rules
171
7143.15.2 by Jelmer Vernooij
Run autopep8.
172
4324.4.1 by Marius Kruger
Make it possible to blackboxtest rules
173
reset_rules()