/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
1
# Copyright (C) 2005 by Canonical Ltd
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
1442.1.20 by Robert Collins
add some documentation on options
18
"""Configuration that affects the behaviour of Bazaar.
19
20
Currently this configuration resides in ~/.bazaar/bazaar.conf
21
and ~/.bazaar/branches.conf, which is written to by bzr.
22
23
In bazaar.config the following options may be set:
24
[DEFAULT]
25
editor=name-of-program
26
email=Your Name <your@email.address>
27
check_signatures=require|ignore|check-available(default)
28
create_signatures=always|never|when-required(default)
29
30
in branches.conf, you specify the url of a branch and options for it.
31
Wildcards may be used - * and ? as normal in shell completion. Options
32
set in both bazaar.conf and branches.conf are overriden by the branches.conf
33
setting.
34
[/home/robertc/source]
35
recurse=False|True(default)
36
email= as above
37
check_signatures= as abive 
38
create_signatures= as above.
39
40
explanation of options
41
----------------------
42
editor - this option sets the pop up editor to use during commits.
43
email - this option sets the user id bzr will use when committing.
44
check_signatures - this option controls whether bzr will require good gpg
45
                   signatures, ignore them, or check them if they are 
46
                   present.
47
create_signatures - this option controls whether bzr will always create 
48
                    gpg signatures, never create them, or create them if the
49
                    branch is configured to require them.
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
50
                    NB: This option is planned, but not implemented yet.
1442.1.20 by Robert Collins
add some documentation on options
51
"""
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
52
1185.12.49 by Aaron Bentley
Switched to ConfigObj
53
from util.configobj.configobj import ConfigObj, ConfigObjError
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
54
import os
1442.1.12 by Robert Collins
LocationConfig section retrieval falls into my lap
55
from fnmatch import fnmatch
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
56
import errno
57
import re
58
59
import bzrlib
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
60
import bzrlib.errors as errors
61
62
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
63
CHECK_IF_POSSIBLE=0
64
CHECK_ALWAYS=1
65
CHECK_NEVER=2
66
67
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
68
class Config(object):
69
    """A configuration policy - what username, editor, gpg needs etc."""
70
71
    def get_editor(self):
72
        """Get the users pop up editor."""
73
        raise NotImplementedError
74
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
75
    def _get_signature_checking(self):
76
        """Template method to override signature checking policy."""
77
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
78
    def __init__(self):
79
        super(Config, self).__init__()
80
81
    def user_email(self):
82
        """Return just the email component of a username."""
83
        e = self.username()
84
        m = re.search(r'[\w+.-]+@[\w+.-]+', e)
85
        if not m:
86
            raise BzrError("%r doesn't seem to contain "
87
                           "a reasonable email address" % e)
88
        return m.group(0)
89
90
    def username(self):
91
        """Return email-style username.
92
    
93
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
94
        
95
        $BZREMAIL can be set to override this, then
96
        the concrete policy type is checked, and finally
97
        $EMAIL is examinged.
98
        but if none is found, a reasonable default is (hopefully)
99
        created.
100
    
101
        TODO: Check it's reasonably well-formed.
102
        """
103
        v = os.environ.get('BZREMAIL')
104
        if v:
105
            return v.decode(bzrlib.user_encoding)
106
    
107
        v = self._get_user_id()
108
        if v:
109
            return v
110
        
111
        v = os.environ.get('EMAIL')
112
        if v:
113
            return v.decode(bzrlib.user_encoding)
114
115
        name, email = _auto_user_id()
116
        if name:
117
            return '%s <%s>' % (name, email)
118
        else:
119
            return email
120
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
121
    def signature_checking(self):
122
        """What is the current policy for signature checking?."""
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
123
        policy = self._get_signature_checking()
124
        if policy is not None:
125
            return policy
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
126
        return CHECK_IF_POSSIBLE
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
127
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
128
    def signature_needed(self):
129
        """Is a signature needed when committing ?."""
130
        policy = self._get_signature_checking()
131
        if policy == CHECK_ALWAYS:
132
            return True
133
        return False
134
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
135
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
136
class IniBasedConfig(Config):
137
    """A configuration policy that draws from ini files."""
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
138
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
139
    def _get_parser(self, file=None):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
140
        if file is None:
141
            input = self._get_filename()
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
142
        else:
1185.12.49 by Aaron Bentley
Switched to ConfigObj
143
            input = file
144
        if self._parser is None:
145
            try:
146
                self._parser = ConfigObj(input)
147
            except ConfigObjError, e:
148
                raise errors.ParseConfigError(e.errors, e.config.filename)
149
        return self._parser
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
150
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
151
    def _get_section(self):
152
        """Override this to define the section used by the config."""
153
        return "DEFAULT"
154
1185.12.49 by Aaron Bentley
Switched to ConfigObj
155
    def _config_val(self, name, section=None):
156
        if section is None:
157
            section = self._get_section()
158
        if section is None:
159
            raise KeyError(name)
160
        # Throw KeyError if name or section not present
161
        if section == "DEFAULT":
162
            try:
163
                return self._get_parser()[name]
164
            except KeyError:
165
                pass
166
        return self._get_parser()[section][name]
167
168
    def _config_bool(self, name, section=None):
169
        val = self._config_val(name, section).lower()
170
        if val in ('1', 'yes', 'true', 'on'):
171
            return True
172
        elif val in ('0', 'no', 'false', 'off'):
173
            return False
174
        else:
175
            raise ValueError("Value %r is not boolean" % val)
176
177
        
178
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
179
    def _get_signature_checking(self):
180
        """See Config._get_signature_checking."""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
181
        try:
182
            policy = self._config_val('check_signatures')
183
        except KeyError:
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
184
            return None
1185.12.49 by Aaron Bentley
Switched to ConfigObj
185
        return self._string_to_signature_policy(policy)
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
186
187
    def _get_user_id(self):
188
        """Get the user id from the 'email' key in the current section."""
1185.12.49 by Aaron Bentley
Switched to ConfigObj
189
        try:
190
            return self._config_val('email')
191
        except KeyError:
192
            pass
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
193
194
    def __init__(self, get_filename):
195
        super(IniBasedConfig, self).__init__()
196
        self._get_filename = get_filename
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
197
        self._parser = None
198
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
199
    def _string_to_signature_policy(self, signature_string):
200
        """Convert a string to a signing policy."""
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
201
        if signature_string.lower() == 'check-available':
202
            return CHECK_IF_POSSIBLE
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
203
        if signature_string.lower() == 'ignore':
204
            return CHECK_NEVER
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
205
        if signature_string.lower() == 'require':
206
            return CHECK_ALWAYS
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
207
        raise errors.BzrError("Invalid signatures policy '%s'"
208
                              % signature_string)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
209
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
210
211
class GlobalConfig(IniBasedConfig):
212
    """The configuration that should be used for a specific location."""
213
214
    def get_editor(self):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
215
        try:
216
            return self._config_val('editor')
217
        except KeyError:
218
            pass
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
219
220
    def __init__(self):
221
        super(GlobalConfig, self).__init__(config_filename)
222
223
224
class LocationConfig(IniBasedConfig):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
225
    """A configuration object that gives the policy for a location."""
226
227
    def __init__(self, location):
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
228
        super(LocationConfig, self).__init__(branches_config_filename)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
229
        self._global_config = None
230
        self.location = location
231
232
    def _get_global_config(self):
233
        if self._global_config is None:
234
            self._global_config = GlobalConfig()
235
        return self._global_config
236
1442.1.9 by Robert Collins
exact section test passes
237
    def _get_section(self):
238
        """Get the section we should look in for config items.
239
240
        Returns None if none exists. 
241
        TODO: perhaps return a NullSection that thunks through to the 
242
              global config.
243
        """
1185.12.49 by Aaron Bentley
Switched to ConfigObj
244
        sections = self._get_parser()
1442.1.12 by Robert Collins
LocationConfig section retrieval falls into my lap
245
        location_names = self.location.split('/')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
246
        if self.location.endswith('/'):
247
            del location_names[-1]
1442.1.12 by Robert Collins
LocationConfig section retrieval falls into my lap
248
        matches=[]
1442.1.10 by Robert Collins
explicit over glob test passes
249
        for section in sections:
1442.1.12 by Robert Collins
LocationConfig section retrieval falls into my lap
250
            section_names = section.split('/')
251
            if section.endswith('/'):
252
                del section_names[-1]
253
            names = zip(location_names, section_names)
254
            matched = True
255
            for name in names:
256
                if not fnmatch(name[0], name[1]):
257
                    matched = False
258
                    break
259
            if not matched:
260
                continue
261
            # so, for the common prefix they matched.
262
            # if section is longer, no match.
263
            if len(section_names) > len(location_names):
264
                continue
265
            # if path is longer, and recurse is not true, no match
266
            if len(section_names) < len(location_names):
1185.12.49 by Aaron Bentley
Switched to ConfigObj
267
                try:
268
                    if not self._config_bool('recurse', section=section):
269
                        continue
270
                except KeyError:
271
                    pass
1442.1.12 by Robert Collins
LocationConfig section retrieval falls into my lap
272
            matches.append((len(section_names), section))
273
        if not len(matches):
274
            return None
275
        matches.sort(reverse=True)
276
        return matches[0][1]
1442.1.9 by Robert Collins
exact section test passes
277
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
278
    def _get_user_id(self):
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
279
        user_id = super(LocationConfig, self)._get_user_id()
280
        if user_id is not None:
281
            return user_id
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
282
        return self._get_global_config()._get_user_id()
283
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
284
    def _get_signature_checking(self):
285
        """See Config._get_signature_checking."""
286
        check = super(LocationConfig, self)._get_signature_checking()
287
        if check is not None:
288
            return check
289
        return self._get_global_config()._get_signature_checking()
290
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
291
292
class BranchConfig(Config):
293
    """A configuration object giving the policy for a branch."""
294
295
    def _get_location_config(self):
296
        if self._location_config is None:
297
            self._location_config = LocationConfig(self.branch.base)
298
        return self._location_config
299
300
    def _get_user_id(self):
301
        """Return the full user id for the branch.
302
    
303
        e.g. "John Hacker <jhacker@foo.org>"
304
        This is looked up in the email controlfile for the branch.
305
        """
306
        try:
307
            return (self.branch.controlfile("email", "r") 
308
                    .read()
309
                    .decode(bzrlib.user_encoding)
310
                    .rstrip("\r\n"))
311
        except errors.NoSuchFile, e:
312
            pass
313
        
314
        return self._get_location_config()._get_user_id()
315
1442.1.19 by Robert Collins
BranchConfigs inherit signature_checking policy from their LocationConfig.
316
    def _get_signature_checking(self):
317
        """See Config._get_signature_checking."""
318
        return self._get_location_config()._get_signature_checking()
319
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
320
    def __init__(self, branch):
321
        super(BranchConfig, self).__init__()
322
        self._location_config = None
323
        self.branch = branch
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
324
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
325
326
def config_dir():
327
    """Return per-user configuration directory.
328
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
329
    By default this is ~/.bazaar/
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
330
    
331
    TODO: Global option --config-dir to override this.
332
    """
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
333
    return os.path.join(os.path.expanduser("~"), ".bazaar")
334
335
336
def config_filename():
337
    """Return per-user configuration ini file filename."""
338
    return os.path.join(config_dir(), 'bazaar.conf')
339
340
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
341
def branches_config_filename():
342
    """Return per-user configuration ini file filename."""
343
    return os.path.join(config_dir(), 'branches.conf')
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
344
345
346
def _auto_user_id():
347
    """Calculate automatic user identification.
348
349
    Returns (realname, email).
350
351
    Only used when none is set in the environment or the id file.
352
353
    This previously used the FQDN as the default domain, but that can
354
    be very slow on machines where DNS is broken.  So now we simply
355
    use the hostname.
356
    """
357
    import socket
358
359
    # XXX: Any good way to get real user name on win32?
360
361
    try:
362
        import pwd
363
        uid = os.getuid()
364
        w = pwd.getpwuid(uid)
365
        gecos = w.pw_gecos.decode(bzrlib.user_encoding)
366
        username = w.pw_name.decode(bzrlib.user_encoding)
367
        comma = gecos.find(',')
368
        if comma == -1:
369
            realname = gecos
370
        else:
371
            realname = gecos[:comma]
372
        if not realname:
373
            realname = username
374
375
    except ImportError:
376
        import getpass
377
        realname = username = getpass.getuser().decode(bzrlib.user_encoding)
378
379
    return realname, (username + '@' + socket.gethostname())
380
381
1185.16.52 by Martin Pool
- add extract_email_address
382
def extract_email_address(e):
383
    """Return just the address part of an email string.
384
    
385
    That is just the user@domain part, nothing else. 
386
    This part is required to contain only ascii characters.
387
    If it can't be extracted, raises an error.
388
    
389
    >>> extract_email_address('Jane Tester <jane@test.com>')
390
    "jane@test.com"
391
    """
392
    m = re.search(r'[\w+.-]+@[\w+.-]+', e)
393
    if not m:
394
        raise BzrError("%r doesn't seem to contain "
395
                       "a reasonable email address" % e)
396
    return m.group(0)