/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/rules.py

  • Committer: Robert Collins
  • Date: 2007-04-19 02:27:44 UTC
  • mto: This revision was merged to the branch mainline in revision 2426.
  • Revision ID: robertc@robertcollins.net-20070419022744-pfdqz42kp1wizh43
``make docs`` now creates a man page at ``man1/bzr.1`` fixing bug 107388.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009, 2010 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
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
"""Rule-based definition of preferences for selected files in selected branches
18
 
 
19
 
See ``bzr help rules`` for details.
20
 
"""
21
 
 
22
 
import configobj
23
 
 
24
 
from . import (
25
 
    bedding,
26
 
    cmdline,
27
 
    errors,
28
 
    globbing,
29
 
    osutils,
30
 
    )
31
 
 
32
 
 
33
 
# Name of the file holding rules in a tree
34
 
RULES_TREE_FILENAME = ".bzrrules"
35
 
 
36
 
# Namespace prefix for per file preferences
37
 
FILE_PREFS_PREFIX = 'name '
38
 
FILE_PREFS_PREFIX_LEN = len(FILE_PREFS_PREFIX)
39
 
 
40
 
# The object providing default rules
41
 
_per_user_searcher = None
42
 
 
43
 
 
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
 
 
52
 
class _RulesSearcher(object):
53
 
    """An object that provides rule-based preferences."""
54
 
 
55
 
    def get_items(self, path):
56
 
        """Return the preferences for a path as name,value tuples.
57
 
 
58
 
        :param path: tree relative path
59
 
        :return: () if no rule matched, otherwise a sequence of name,value
60
 
          tuples.
61
 
        """
62
 
        raise NotImplementedError(self.get_items)
63
 
 
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
69
 
        :return: () if no rule matched, otherwise a sequence of name,value
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
 
 
76
 
    def get_single_value(self, path, preference_name):
77
 
        """Get a single preference for a single file.
78
 
 
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
 
 
85
 
 
86
 
class _IniBasedRulesSearcher(_RulesSearcher):
87
 
 
88
 
    def __init__(self, inifile):
89
 
        """Construct a _RulesSearcher based on an ini file.
90
 
 
91
 
        The content will be decoded as utf-8.
92
 
 
93
 
        :param inifile: the name of the file or a sequence of lines.
94
 
        """
95
 
        self._cfg = configobj.ConfigObj(inifile, encoding='utf-8')
96
 
        sections = self._cfg.keys()
97
 
        patterns = []
98
 
        self.pattern_to_section = {}
99
 
        for s in sections:
100
 
            if s.startswith(FILE_PREFS_PREFIX):
101
 
                file_patterns = cmdline.split(s[FILE_PREFS_PREFIX_LEN:])
102
 
                patterns.extend(file_patterns)
103
 
                for fp in file_patterns:
104
 
                    self.pattern_to_section[fp] = s
105
 
        if len(patterns) < len(sections):
106
 
            unknowns = [s for s in sections
107
 
                        if not s.startswith(FILE_PREFS_PREFIX)]
108
 
            raise UnknownRules(unknowns)
109
 
        elif patterns:
110
 
            self._globster = globbing._OrderedGlobster(patterns)
111
 
        else:
112
 
            self._globster = None
113
 
 
114
 
    def get_items(self, path):
115
 
        """See _RulesSearcher.get_items."""
116
 
        if self._globster is None:
117
 
            return ()
118
 
        pat = self._globster.match(path)
119
 
        if pat is None:
120
 
            return ()
121
 
        else:
122
 
            all = self._cfg[self.pattern_to_section[pat]]
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:
128
 
            return ()
129
 
        pat = self._globster.match(path)
130
 
        if pat is None:
131
 
            return ()
132
 
        else:
133
 
            all = self._cfg[self.pattern_to_section[pat]]
134
 
            return tuple((k, all.get(k)) for k in names)
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
 
 
146
 
    def get_items(self, path):
147
 
        """See _RulesSearcher.get_items."""
148
 
        for searcher in self.searchers:
149
 
            result = searcher.get_items(path)
150
 
            if result:
151
 
                return result
152
 
        return ()
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
160
 
        return ()
161
 
 
162
 
 
163
 
def rules_path():
164
 
    """Return the default rules file path."""
165
 
    return osutils.pathjoin(bedding.config_dir(), 'rules')
166
 
 
167
 
 
168
 
def reset_rules():
169
 
    global _per_user_searcher
170
 
    _per_user_searcher = _IniBasedRulesSearcher(rules_path())
171
 
 
172
 
 
173
 
reset_rules()