1
# Copyright (C) 2005 by Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
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.
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.
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
18
"""Configuration that affects the behaviour of Bazaar.
20
Currently this configuration resides in ~/.bazaar/bazaar.conf
21
and ~/.bazaar/branches.conf, which is written to by bzr.
23
In bazaar.config the following options may be set:
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)
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
34
[/home/robertc/source]
35
recurse=False|True(default)
37
check_signatures= as abive
38
create_signatures= as above.
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
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.
50
NB: This option is planned, but not implemented yet.
53
from ConfigParser import ConfigParser
55
from fnmatch import fnmatch
60
import bzrlib.errors as errors
69
"""A configuration policy - what username, editor, gpg needs etc."""
72
"""Get the users pop up editor."""
73
raise NotImplementedError
75
def _get_signature_checking(self):
76
"""Template method to override signature checking policy."""
79
super(Config, self).__init__()
82
"""Return just the email component of a username."""
84
m = re.search(r'[\w+.-]+@[\w+.-]+', e)
86
raise BzrError("%r doesn't seem to contain "
87
"a reasonable email address" % e)
91
"""Return email-style username.
93
Something similar to 'Martin Pool <mbp@sourcefrog.net>'
95
$BZREMAIL can be set to override this, then
96
the concrete policy type is checked, and finally
98
but if none is found, a reasonable default is (hopefully)
101
TODO: Check it's reasonably well-formed.
103
v = os.environ.get('BZREMAIL')
105
return v.decode(bzrlib.user_encoding)
107
v = self._get_user_id()
111
v = os.environ.get('EMAIL')
113
return v.decode(bzrlib.user_encoding)
115
name, email = _auto_user_id()
117
return '%s <%s>' % (name, email)
121
def signature_checking(self):
122
"""What is the current policy for signature checking?."""
123
policy = self._get_signature_checking()
124
if policy is not None:
126
return CHECK_IF_POSSIBLE
128
def signature_needed(self):
129
"""Is a signature needed when committing ?."""
130
policy = self._get_signature_checking()
131
if policy == CHECK_ALWAYS:
136
class IniBasedConfig(Config):
137
"""A configuration policy that draws from ini files."""
139
def _get_parser(self, file=None):
140
if self._parser is not None:
142
parser = ConfigParser()
146
parser.read([self._get_filename()])
147
self._parser = parser
150
def _get_section(self):
151
"""Override this to define the section used by the config."""
154
def _get_signature_checking(self):
155
"""See Config._get_signature_checking."""
156
section = self._get_section()
159
if self._get_parser().has_option(section, 'check_signatures'):
160
return self._string_to_signature_policy(
161
self._get_parser().get(section, 'check_signatures'))
163
def _get_user_id(self):
164
"""Get the user id from the 'email' key in the current section."""
165
section = self._get_section()
166
if section is not None:
167
if self._get_parser().has_option(section, 'email'):
168
return self._get_parser().get(section, 'email')
170
def __init__(self, get_filename):
171
super(IniBasedConfig, self).__init__()
172
self._get_filename = get_filename
175
def _string_to_signature_policy(self, signature_string):
176
"""Convert a string to a signing policy."""
177
if signature_string.lower() == 'check-available':
178
return CHECK_IF_POSSIBLE
179
if signature_string.lower() == 'ignore':
181
if signature_string.lower() == 'require':
183
raise errors.BzrError("Invalid signatures policy '%s'"
187
class GlobalConfig(IniBasedConfig):
188
"""The configuration that should be used for a specific location."""
190
def get_editor(self):
191
if self._get_parser().has_option(self._get_section(), 'editor'):
192
return self._get_parser().get(self._get_section(), 'editor')
195
super(GlobalConfig, self).__init__(config_filename)
198
class LocationConfig(IniBasedConfig):
199
"""A configuration object that gives the policy for a location."""
201
def __init__(self, location):
202
super(LocationConfig, self).__init__(branches_config_filename)
203
self._global_config = None
204
self.location = location
206
def _get_global_config(self):
207
if self._global_config is None:
208
self._global_config = GlobalConfig()
209
return self._global_config
211
def _get_section(self):
212
"""Get the section we should look in for config items.
214
Returns None if none exists.
215
TODO: perhaps return a NullSection that thunks through to the
218
sections = self._get_parser().sections()
219
location_names = self.location.split('/')
220
if self.location.endswith('/'):
221
del location_names[-1]
223
for section in sections:
224
section_names = section.split('/')
225
if section.endswith('/'):
226
del section_names[-1]
227
names = zip(location_names, section_names)
230
if not fnmatch(name[0], name[1]):
235
# so, for the common prefix they matched.
236
# if section is longer, no match.
237
if len(section_names) > len(location_names):
239
# if path is longer, and recurse is not true, no match
240
if len(section_names) < len(location_names):
241
if (self._get_parser().has_option(section, 'recurse')
242
and not self._get_parser().getboolean(section, 'recurse')):
244
matches.append((len(section_names), section))
247
matches.sort(reverse=True)
250
def _get_user_id(self):
251
user_id = super(LocationConfig, self)._get_user_id()
252
if user_id is not None:
254
return self._get_global_config()._get_user_id()
256
def _get_signature_checking(self):
257
"""See Config._get_signature_checking."""
258
check = super(LocationConfig, self)._get_signature_checking()
259
if check is not None:
261
return self._get_global_config()._get_signature_checking()
264
class BranchConfig(Config):
265
"""A configuration object giving the policy for a branch."""
267
def _get_location_config(self):
268
if self._location_config is None:
269
self._location_config = LocationConfig(self.branch.base)
270
return self._location_config
272
def _get_user_id(self):
273
"""Return the full user id for the branch.
275
e.g. "John Hacker <jhacker@foo.org>"
276
This is looked up in the email controlfile for the branch.
279
return (self.branch.controlfile("email", "r")
281
.decode(bzrlib.user_encoding)
283
except errors.NoSuchFile, e:
286
return self._get_location_config()._get_user_id()
288
def _get_signature_checking(self):
289
"""See Config._get_signature_checking."""
290
return self._get_location_config()._get_signature_checking()
292
def __init__(self, branch):
293
super(BranchConfig, self).__init__()
294
self._location_config = None
299
"""Return per-user configuration directory.
301
By default this is ~/.bazaar/
303
TODO: Global option --config-dir to override this.
305
return os.path.join(os.path.expanduser("~"), ".bazaar")
308
def config_filename():
309
"""Return per-user configuration ini file filename."""
310
return os.path.join(config_dir(), 'bazaar.conf')
313
def branches_config_filename():
314
"""Return per-user configuration ini file filename."""
315
return os.path.join(config_dir(), 'branches.conf')
319
"""Calculate automatic user identification.
321
Returns (realname, email).
323
Only used when none is set in the environment or the id file.
325
This previously used the FQDN as the default domain, but that can
326
be very slow on machines where DNS is broken. So now we simply
331
# XXX: Any good way to get real user name on win32?
336
w = pwd.getpwuid(uid)
337
gecos = w.pw_gecos.decode(bzrlib.user_encoding)
338
username = w.pw_name.decode(bzrlib.user_encoding)
339
comma = gecos.find(',')
343
realname = gecos[:comma]
349
realname = username = getpass.getuser().decode(bzrlib.user_encoding)
351
return realname, (username + '@' + socket.gethostname())