bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
3398.1.3
by Ian Clatworthy
 first cut at PropertiesProvider class  | 
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, 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  | 
|
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
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  | 
||
22  | 
from bzrlib import (  | 
|
23  | 
config,  | 
|
| 
3943.3.2
by Marius Kruger
 actually support quoting the patterns as the docs suggest  | 
24  | 
commands,  | 
| 
3398.1.30
by Ian Clatworthy
 test unknown rules detection  | 
25  | 
errors,  | 
| 
3398.1.3
by Ian Clatworthy
 first cut at PropertiesProvider class  | 
26  | 
globbing,  | 
27  | 
osutils,  | 
|
28  | 
    )
 | 
|
| 
3398.1.6
by Ian Clatworthy
 get properties_filename() test passing  | 
29  | 
from bzrlib.util.configobj import configobj  | 
| 
3398.1.3
by Ian Clatworthy
 first cut at PropertiesProvider class  | 
30  | 
|
31  | 
||
| 
3398.1.24
by Ian Clatworthy
 make iter_search_rules a tree method  | 
32  | 
# Name of the file holding rules in a tree
 | 
33  | 
RULES_TREE_FILENAME = ".bzrrules"  | 
|
34  | 
||
| 
3398.1.28
by Ian Clatworthy
 add namespace for rules  | 
35  | 
# Namespace prefix for per file preferences
 | 
| 
3398.1.32
by Ian Clatworthy
 namespace keyword changed to name  | 
36  | 
FILE_PREFS_PREFIX = 'name '  | 
| 
3398.1.28
by Ian Clatworthy
 add namespace for rules  | 
37  | 
FILE_PREFS_PREFIX_LEN = len(FILE_PREFS_PREFIX)  | 
38  | 
||
| 
4324.4.1
by Marius Kruger
 Make it possible to blackboxtest rules  | 
39  | 
# The object providing default rules
 | 
40  | 
_per_user_searcher = None  | 
|
41  | 
||
| 
3398.1.24
by Ian Clatworthy
 make iter_search_rules a tree method  | 
42  | 
|
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
43  | 
class _RulesSearcher(object):  | 
44  | 
"""An object that provides rule-based preferences."""  | 
|
| 
3398.1.13
by Ian Clatworthy
 rename properties to attributes  | 
45  | 
|
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
46  | 
def get_items(self, path):  | 
47  | 
"""Return the preferences for a path as name,value tuples.  | 
|
| 
3398.1.13
by Ian Clatworthy
 rename properties to attributes  | 
48  | 
|
49  | 
        :param path: tree relative path
 | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
50  | 
        :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  | 
51  | 
          tuples.
 | 
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
52  | 
        """
 | 
53  | 
raise NotImplementedError(self.get_items)  | 
|
54  | 
||
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
55  | 
def get_selected_items(self, path, names):  | 
56  | 
"""Return selected preferences for a path as name,value tuples.  | 
|
57  | 
||
58  | 
        :param path: tree relative path
 | 
|
59  | 
        :param names: the list of preferences to lookup
 | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
60  | 
        :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  | 
61  | 
          tuples. The sequence is the same length as names,
 | 
62  | 
          tuple order matches the order in names, and
 | 
|
63  | 
          undefined preferences are given the value None.
 | 
|
64  | 
        """
 | 
|
65  | 
raise NotImplementedError(self.get_selected_items)  | 
|
66  | 
||
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
67  | 
|
68  | 
class _IniBasedRulesSearcher(_RulesSearcher):  | 
|
69  | 
||
70  | 
def __init__(self, inifile):  | 
|
71  | 
"""Construct a _RulesSearcher based on an ini file.  | 
|
72  | 
||
| 
3398.1.24
by Ian Clatworthy
 make iter_search_rules a tree method  | 
73  | 
        The content will be decoded as utf-8.
 | 
74  | 
||
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
75  | 
        :param inifile: the name of the file or a sequence of lines.
 | 
76  | 
        """
 | 
|
| 
3398.1.24
by Ian Clatworthy
 make iter_search_rules a tree method  | 
77  | 
options = {'encoding': 'utf-8'}  | 
78  | 
self._cfg = configobj.ConfigObj(inifile, options=options)  | 
|
| 
3398.1.28
by Ian Clatworthy
 add namespace for rules  | 
79  | 
sections = self._cfg.keys()  | 
| 
3946.1.1
by Ian Clatworthy
 Multi-glob rules (Marius Kruger)  | 
80  | 
patterns = []  | 
| 
3943.3.1
by Marius Kruger
 add test and support for multi-glob rules  | 
81  | 
self.pattern_to_section = {}  | 
82  | 
for s in sections:  | 
|
83  | 
if s.startswith(FILE_PREFS_PREFIX):  | 
|
| 
3943.3.2
by Marius Kruger
 actually support quoting the patterns as the docs suggest  | 
84  | 
file_patterns = commands.shlex_split_unicode(  | 
85  | 
s[FILE_PREFS_PREFIX_LEN:])  | 
|
| 
3943.3.1
by Marius Kruger
 add test and support for multi-glob rules  | 
86  | 
patterns.extend(file_patterns)  | 
87  | 
for fp in file_patterns:  | 
|
88  | 
self.pattern_to_section[fp] = s  | 
|
| 
3398.1.28
by Ian Clatworthy
 add namespace for rules  | 
89  | 
if len(patterns) < len(sections):  | 
90  | 
unknowns = [s for s in sections  | 
|
91  | 
if not s.startswith(FILE_PREFS_PREFIX)]  | 
|
| 
3398.1.30
by Ian Clatworthy
 test unknown rules detection  | 
92  | 
raise errors.UnknownRules(unknowns)  | 
| 
3398.1.28
by Ian Clatworthy
 add namespace for rules  | 
93  | 
elif patterns:  | 
| 
3398.1.17
by Ian Clatworthy
 search less when files not present  | 
94  | 
self._globster = globbing._OrderedGlobster(patterns)  | 
95  | 
else:  | 
|
96  | 
self._globster = None  | 
|
| 
3398.1.3
by Ian Clatworthy
 first cut at PropertiesProvider class  | 
97  | 
|
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
98  | 
def get_items(self, path):  | 
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
99  | 
"""See _RulesSearcher.get_items."""  | 
| 
3398.1.17
by Ian Clatworthy
 search less when files not present  | 
100  | 
if self._globster is None:  | 
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
101  | 
return ()  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
102  | 
pat = self._globster.match(path)  | 
103  | 
if pat is None:  | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
104  | 
return ()  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
105  | 
else:  | 
| 
3943.3.1
by Marius Kruger
 add test and support for multi-glob rules  | 
106  | 
all = self._cfg[self.pattern_to_section[pat]]  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
107  | 
return tuple(all.items())  | 
108  | 
||
109  | 
def get_selected_items(self, path, names):  | 
|
110  | 
"""See _RulesSearcher.get_selected_items."""  | 
|
111  | 
if self._globster is None:  | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
112  | 
return ()  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
113  | 
pat = self._globster.match(path)  | 
114  | 
if pat is None:  | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
115  | 
return ()  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
116  | 
else:  | 
| 
3943.3.1
by Marius Kruger
 add test and support for multi-glob rules  | 
117  | 
all = self._cfg[self.pattern_to_section[pat]]  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
118  | 
return tuple((k, all.get(k)) for k in names)  | 
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
119  | 
|
120  | 
||
121  | 
class _StackedRulesSearcher(_RulesSearcher):  | 
|
122  | 
||
123  | 
def __init__(self, searchers):  | 
|
124  | 
"""Construct a _RulesSearcher based on a stack of other ones.  | 
|
125  | 
||
126  | 
        :param searchers: a sequence of searchers.
 | 
|
127  | 
        """
 | 
|
128  | 
self.searchers = searchers  | 
|
129  | 
||
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
130  | 
def get_items(self, path):  | 
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
131  | 
"""See _RulesSearcher.get_items."""  | 
| 
3398.1.18
by Ian Clatworthy
 add tests for _StackedRulesSearcher  | 
132  | 
for searcher in self.searchers:  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
133  | 
result = searcher.get_items(path)  | 
134  | 
if result:  | 
|
135  | 
return result  | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
136  | 
return ()  | 
| 
3398.1.34
by Ian Clatworthy
 changed API design as requested by jam during review  | 
137  | 
|
138  | 
def get_selected_items(self, path, names):  | 
|
139  | 
"""See _RulesSearcher.get_selected_items."""  | 
|
140  | 
for searcher in self.searchers:  | 
|
141  | 
result = searcher.get_selected_items(path, names)  | 
|
142  | 
if result:  | 
|
143  | 
return result  | 
|
| 
3564.1.1
by Ian Clatworthy
 RuleSearchers need to return () instead of []  | 
144  | 
return ()  | 
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
145  | 
|
146  | 
||
147  | 
def rules_filename():  | 
|
148  | 
"""Return the default rules filename."""  | 
|
| 
3398.1.23
by Ian Clatworthy
 update doc to reflect file naming per poolie's review  | 
149  | 
return osutils.pathjoin(config.config_dir(), 'rules')  | 
| 
3398.1.15
by Ian Clatworthy
 search branch.rules and bazaar.rules for preferences  | 
150  | 
|
151  | 
||
| 
4324.4.1
by Marius Kruger
 Make it possible to blackboxtest rules  | 
152  | 
def reset_rules():  | 
153  | 
global _per_user_searcher  | 
|
154  | 
_per_user_searcher = _IniBasedRulesSearcher(rules_filename())  | 
|
155  | 
||
156  | 
reset_rules()  |