49
50
create_signatures - this option controls whether bzr will always create
50
51
gpg signatures, never create them, or create them if the
51
52
branch is configured to require them.
52
NB: This option is planned, but not implemented yet.
53
log_format - This options set the default log format. Options are long,
54
short, line, or a plugin can register new formats
53
log_format - this option sets the default log format. Possible values are
54
long, short, line, or a plugin can register new formats.
56
56
In bazaar.conf you can also define aliases in the ALIASES sections, example
68
from bzrlib.lazy_import import lazy_import
69
lazy_import(globals(), """
69
71
from fnmatch import fnmatch
73
from StringIO import StringIO
73
import bzrlib.errors as errors
74
from bzrlib.osutils import pathjoin
75
from bzrlib.trace import mutter
76
85
import bzrlib.util.configobj.configobj as configobj
77
from StringIO import StringIO
88
from bzrlib.trace import mutter, warning
79
91
CHECK_IF_POSSIBLE=0
103
POLICY_APPENDPATH = 2
107
POLICY_NORECURSE: 'norecurse',
108
POLICY_APPENDPATH: 'appendpath',
113
'norecurse': POLICY_NORECURSE,
114
'appendpath': POLICY_APPENDPATH,
118
STORE_LOCATION = POLICY_NONE
119
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
120
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
84
125
class ConfigObj(configobj.ConfigObj):
86
127
def get_bool(self, section, key):
103
144
"""Get the users pop up editor."""
104
145
raise NotImplementedError
147
def get_mail_client(self):
148
"""Get a mail client to use"""
149
selected_client = self.get_user_option('mail_client')
151
mail_client_class = {
152
None: mail_client.DefaultMail,
154
'evolution': mail_client.Evolution,
155
'kmail': mail_client.KMail,
156
'mutt': mail_client.Mutt,
157
'thunderbird': mail_client.Thunderbird,
159
'default': mail_client.DefaultMail,
160
'editor': mail_client.Editor,
161
'mapi': mail_client.MAPIClient,
162
'xdg-email': mail_client.XDGEmail,
165
raise errors.UnknownMailClient(selected_client)
166
return mail_client_class(self)
106
168
def _get_signature_checking(self):
107
169
"""Template method to override signature checking policy."""
171
def _get_signing_policy(self):
172
"""Template method to override signature creation policy."""
109
174
def _get_user_option(self, option_name):
110
175
"""Template method to provide a user option."""
193
263
return CHECK_IF_POSSIBLE
265
def signing_policy(self):
266
"""What is the current policy for signature checking?."""
267
policy = self._get_signing_policy()
268
if policy is not None:
270
return SIGN_WHEN_REQUIRED
195
272
def signature_needed(self):
196
273
"""Is a signature needed when committing ?."""
197
policy = self._get_signature_checking()
198
if policy == CHECK_ALWAYS:
274
policy = self._get_signing_policy()
276
policy = self._get_signature_checking()
277
if policy is not None:
278
warning("Please use create_signatures, not check_signatures "
279
"to set signing policy.")
280
if policy == CHECK_ALWAYS:
282
elif policy == SIGN_ALWAYS:
222
312
raise errors.ParseConfigError(e.errors, e.config.filename)
223
313
return self._parser
315
def _get_matching_sections(self):
316
"""Return an ordered list of (section_name, extra_path) pairs.
318
If the section contains inherited configuration, extra_path is
319
a string containing the additional path components.
321
section = self._get_section()
322
if section is not None:
323
return [(section, '')]
225
327
def _get_section(self):
226
328
"""Override this to define the section used by the config."""
331
def _get_option_policy(self, section, option_name):
332
"""Return the policy for the given (section, option_name) pair."""
229
335
def _get_signature_checking(self):
230
336
"""See Config._get_signature_checking."""
231
337
policy = self._get_user_option('check_signatures')
233
339
return self._string_to_signature_policy(policy)
341
def _get_signing_policy(self):
342
"""See Config._get_signing_policy"""
343
policy = self._get_user_option('create_signatures')
345
return self._string_to_signing_policy(policy)
235
347
def _get_user_id(self):
236
348
"""Get the user id from the 'email' key in the current section."""
237
349
return self._get_user_option('email')
239
351
def _get_user_option(self, option_name):
240
352
"""See Config._get_user_option."""
242
return self._get_parser().get_value(self._get_section(),
353
for (section, extra_path) in self._get_matching_sections():
355
value = self._get_parser().get_value(section, option_name)
358
policy = self._get_option_policy(section, option_name)
359
if policy == POLICY_NONE:
361
elif policy == POLICY_NORECURSE:
362
# norecurse items only apply to the exact path
367
elif policy == POLICY_APPENDPATH:
369
value = urlutils.join(value, extra_path)
372
raise AssertionError('Unexpected config policy %r' % policy)
247
376
def _gpg_signing_command(self):
248
377
"""See Config.gpg_signing_command."""
289
432
def __init__(self):
290
433
super(GlobalConfig, self).__init__(config_filename)
435
def set_user_option(self, option, value):
436
"""Save option and its value in the configuration."""
437
# FIXME: RBC 20051029 This should refresh the parser and also take a
438
# file lock on bazaar.conf.
439
conf_dir = os.path.dirname(self._get_filename())
440
ensure_config_dir_exists(conf_dir)
441
if 'DEFAULT' not in self._get_parser():
442
self._get_parser()['DEFAULT'] = {}
443
self._get_parser()['DEFAULT'][option] = value
444
f = open(self._get_filename(), 'wb')
445
self._get_parser().write(f)
293
449
class LocationConfig(IniBasedConfig):
294
450
"""A configuration object that gives the policy for a location."""
296
452
def __init__(self, location):
297
super(LocationConfig, self).__init__(branches_config_filename)
298
self._global_config = None
453
name_generator = locations_config_filename
454
if (not os.path.exists(name_generator()) and
455
os.path.exists(branches_config_filename())):
456
if sys.platform == 'win32':
457
warning('Please rename %s to %s'
458
% (branches_config_filename(),
459
locations_config_filename()))
461
warning('Please rename ~/.bazaar/branches.conf'
462
' to ~/.bazaar/locations.conf')
463
name_generator = branches_config_filename
464
super(LocationConfig, self).__init__(name_generator)
465
# local file locations are looked up by local path, rather than
466
# by file url. This is because the config file is a user
467
# file, and we would rather not expose the user to file urls.
468
if location.startswith('file://'):
469
location = urlutils.local_path_from_url(location)
299
470
self.location = location
301
def _get_global_config(self):
302
if self._global_config is None:
303
self._global_config = GlobalConfig()
304
return self._global_config
306
def _get_section(self):
307
"""Get the section we should look in for config items.
309
Returns None if none exists.
310
TODO: perhaps return a NullSection that thunks through to the
472
def _get_matching_sections(self):
473
"""Return an ordered list of section names matching this location."""
313
474
sections = self._get_parser()
314
475
location_names = self.location.split('/')
315
476
if self.location.endswith('/'):
316
477
del location_names[-1]
318
479
for section in sections:
319
section_names = section.split('/')
480
# location is a local path if possible, so we need
481
# to convert 'file://' urls to local paths if necessary.
482
# This also avoids having file:///path be a more exact
483
# match than '/path'.
484
if section.startswith('file://'):
485
section_path = urlutils.local_path_from_url(section)
487
section_path = section
488
section_names = section_path.split('/')
320
489
if section.endswith('/'):
321
490
del section_names[-1]
322
491
names = zip(location_names, section_names)
331
500
# if section is longer, no match.
332
501
if len(section_names) > len(location_names):
334
# if path is longer, and recurse is not true, no match
335
if len(section_names) < len(location_names):
337
if not self._get_parser()[section].as_bool('recurse'):
341
matches.append((len(section_names), section))
503
matches.append((len(section_names), section,
504
'/'.join(location_names[len(section_names):])))
344
505
matches.sort(reverse=True)
347
def _gpg_signing_command(self):
348
"""See Config.gpg_signing_command."""
349
command = super(LocationConfig, self)._gpg_signing_command()
350
if command is not None:
352
return self._get_global_config()._gpg_signing_command()
354
def _log_format(self):
355
"""See Config.log_format."""
356
command = super(LocationConfig, self)._log_format()
357
if command is not None:
359
return self._get_global_config()._log_format()
361
def _get_user_id(self):
362
user_id = super(LocationConfig, self)._get_user_id()
363
if user_id is not None:
365
return self._get_global_config()._get_user_id()
367
def _get_user_option(self, option_name):
368
"""See Config._get_user_option."""
369
option_value = super(LocationConfig,
370
self)._get_user_option(option_name)
371
if option_value is not None:
373
return self._get_global_config()._get_user_option(option_name)
375
def _get_signature_checking(self):
376
"""See Config._get_signature_checking."""
377
check = super(LocationConfig, self)._get_signature_checking()
378
if check is not None:
380
return self._get_global_config()._get_signature_checking()
382
def _post_commit(self):
383
"""See Config.post_commit."""
384
hook = self._get_user_option('post_commit')
387
return self._get_global_config()._post_commit()
389
def set_user_option(self, option, value):
507
for (length, section, extra_path) in matches:
508
sections.append((section, extra_path))
509
# should we stop looking for parent configs here?
511
if self._get_parser()[section].as_bool('ignore_parents'):
517
def _get_option_policy(self, section, option_name):
518
"""Return the policy for the given (section, option_name) pair."""
519
# check for the old 'recurse=False' flag
521
recurse = self._get_parser()[section].as_bool('recurse')
525
return POLICY_NORECURSE
527
policy_key = option_name + ':policy'
529
policy_name = self._get_parser()[section][policy_key]
533
return _policy_value[policy_name]
535
def _set_option_policy(self, section, option_name, option_policy):
536
"""Set the policy for the given option name in the given section."""
537
# The old recurse=False option affects all options in the
538
# section. To handle multiple policies in the section, we
539
# need to convert it to a policy_norecurse key.
541
recurse = self._get_parser()[section].as_bool('recurse')
545
symbol_versioning.warn(
546
'The recurse option is deprecated as of 0.14. '
547
'The section "%s" has been converted to use policies.'
550
del self._get_parser()[section]['recurse']
552
for key in self._get_parser()[section].keys():
553
if not key.endswith(':policy'):
554
self._get_parser()[section][key +
555
':policy'] = 'norecurse'
557
policy_key = option_name + ':policy'
558
policy_name = _policy_name[option_policy]
559
if policy_name is not None:
560
self._get_parser()[section][policy_key] = policy_name
562
if policy_key in self._get_parser()[section]:
563
del self._get_parser()[section][policy_key]
565
def set_user_option(self, option, value, store=STORE_LOCATION):
390
566
"""Save option and its value in the configuration."""
567
assert store in [STORE_LOCATION,
568
STORE_LOCATION_NORECURSE,
569
STORE_LOCATION_APPENDPATH], 'bad storage policy'
391
570
# FIXME: RBC 20051029 This should refresh the parser and also take a
392
# file lock on branches.conf.
571
# file lock on locations.conf.
393
572
conf_dir = os.path.dirname(self._get_filename())
394
573
ensure_config_dir_exists(conf_dir)
395
574
location = self.location
401
580
elif location + '/' in self._get_parser():
402
581
location = location + '/'
403
582
self._get_parser()[location][option]=value
583
# the allowed values of store match the config policies
584
self._set_option_policy(location, option, store)
404
585
self._get_parser().write(file(self._get_filename(), 'wb'))
407
588
class BranchConfig(Config):
408
589
"""A configuration object giving the policy for a branch."""
591
def _get_branch_data_config(self):
592
if self._branch_data_config is None:
593
self._branch_data_config = TreeConfig(self.branch)
594
return self._branch_data_config
410
596
def _get_location_config(self):
411
597
if self._location_config is None:
412
598
self._location_config = LocationConfig(self.branch.base)
413
599
return self._location_config
601
def _get_global_config(self):
602
if self._global_config is None:
603
self._global_config = GlobalConfig()
604
return self._global_config
606
def _get_best_value(self, option_name):
607
"""This returns a user option from local, tree or global config.
609
They are tried in that order. Use get_safe_value if trusted values
612
for source in self.option_sources:
613
value = getattr(source(), option_name)()
614
if value is not None:
618
def _get_safe_value(self, option_name):
619
"""This variant of get_best_value never returns untrusted values.
621
It does not return values from the branch data, because the branch may
622
not be controlled by the user.
624
We may wish to allow locations.conf to control whether branches are
625
trusted in the future.
627
for source in (self._get_location_config, self._get_global_config):
628
value = getattr(source(), option_name)()
629
if value is not None:
415
633
def _get_user_id(self):
416
634
"""Return the full user id for the branch.
426
644
except errors.NoSuchFile, e:
429
return self._get_location_config()._get_user_id()
647
return self._get_best_value('_get_user_id')
431
649
def _get_signature_checking(self):
432
650
"""See Config._get_signature_checking."""
433
return self._get_location_config()._get_signature_checking()
651
return self._get_best_value('_get_signature_checking')
653
def _get_signing_policy(self):
654
"""See Config._get_signing_policy."""
655
return self._get_best_value('_get_signing_policy')
435
657
def _get_user_option(self, option_name):
436
658
"""See Config._get_user_option."""
437
return self._get_location_config()._get_user_option(option_name)
659
for source in self.option_sources:
660
value = source()._get_user_option(option_name)
661
if value is not None:
665
def set_user_option(self, name, value, store=STORE_BRANCH,
667
if store == STORE_BRANCH:
668
self._get_branch_data_config().set_option(value, name)
669
elif store == STORE_GLOBAL:
670
self._get_global_config().set_user_option(name, value)
672
self._get_location_config().set_user_option(name, value, store)
675
if store in (STORE_GLOBAL, STORE_BRANCH):
676
mask_value = self._get_location_config().get_user_option(name)
677
if mask_value is not None:
678
trace.warning('Value "%s" is masked by "%s" from'
679
' locations.conf', value, mask_value)
681
if store == STORE_GLOBAL:
682
branch_config = self._get_branch_data_config()
683
mask_value = branch_config.get_user_option(name)
684
if mask_value is not None:
685
trace.warning('Value "%s" is masked by "%s" from'
686
' branch.conf', value, mask_value)
439
689
def _gpg_signing_command(self):
440
690
"""See Config.gpg_signing_command."""
441
return self._get_location_config()._gpg_signing_command()
691
return self._get_safe_value('_gpg_signing_command')
443
693
def __init__(self, branch):
444
694
super(BranchConfig, self).__init__()
445
695
self._location_config = None
696
self._branch_data_config = None
697
self._global_config = None
446
698
self.branch = branch
699
self.option_sources = (self._get_location_config,
700
self._get_branch_data_config,
701
self._get_global_config)
448
703
def _post_commit(self):
449
704
"""See Config.post_commit."""
450
return self._get_location_config()._post_commit()
705
return self._get_safe_value('_post_commit')
707
def _get_nickname(self):
708
value = self._get_explicit_nickname()
709
if value is not None:
711
return urlutils.unescape(self.branch.base.split('/')[-2])
713
def has_explicit_nickname(self):
714
"""Return true if a nickname has been explicitly assigned."""
715
return self._get_explicit_nickname() is not None
717
def _get_explicit_nickname(self):
718
return self._get_best_value('_get_nickname')
452
720
def _log_format(self):
453
721
"""See Config.log_format."""
454
return self._get_location_config()._log_format()
722
return self._get_best_value('_log_format')
457
725
def ensure_config_dir_exists(path=None):
482
750
base = os.environ.get('BZR_HOME', None)
483
751
if sys.platform == 'win32':
485
base = os.environ.get('APPDATA', None)
753
base = win32utils.get_appdata_location_unicode()
487
755
base = os.environ.get('HOME', None)
489
raise BzrError('You must have one of BZR_HOME, APPDATA, or HOME set')
490
return pathjoin(base, 'bazaar', '2.0')
757
raise errors.BzrError('You must have one of BZR_HOME, APPDATA, or HOME set')
758
return osutils.pathjoin(base, 'bazaar', '2.0')
492
760
# cygwin, linux, and darwin all have a $HOME directory
494
762
base = os.path.expanduser("~")
495
return pathjoin(base, ".bazaar")
763
return osutils.pathjoin(base, ".bazaar")
498
766
def config_filename():
499
767
"""Return per-user configuration ini file filename."""
500
return pathjoin(config_dir(), 'bazaar.conf')
768
return osutils.pathjoin(config_dir(), 'bazaar.conf')
503
771
def branches_config_filename():
504
772
"""Return per-user configuration ini file filename."""
505
return pathjoin(config_dir(), 'branches.conf')
773
return osutils.pathjoin(config_dir(), 'branches.conf')
776
def locations_config_filename():
777
"""Return per-user configuration ini file filename."""
778
return osutils.pathjoin(config_dir(), 'locations.conf')
781
def user_ignore_config_filename():
782
"""Return the user default ignore filename"""
783
return osutils.pathjoin(config_dir(), 'ignore')
508
786
def _auto_user_id():
521
# XXX: Any good way to get real user name on win32?
799
if sys.platform == 'win32':
800
name = win32utils.get_user_name_unicode()
802
raise errors.BzrError("Cannot autodetect user name.\n"
803
"Please, set your name with command like:\n"
804
'bzr whoami "Your Name <name@domain.com>"')
805
host = win32utils.get_host_name_unicode()
807
host = socket.gethostname()
808
return name, (name + '@' + host)
525
812
uid = os.getuid()
526
813
w = pwd.getpwuid(uid)
529
gecos = w.pw_gecos.decode(bzrlib.user_encoding)
530
username = w.pw_name.decode(bzrlib.user_encoding)
531
except UnicodeDecodeError:
532
# We're using pwd, therefore we're on Unix, so /etc/passwd is ok.
533
raise errors.BzrError("Can't decode username in " \
534
"/etc/passwd as %s." % bzrlib.user_encoding)
815
# we try utf-8 first, because on many variants (like Linux),
816
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
817
# false positives. (many users will have their user encoding set to
818
# latin-1, which cannot raise UnicodeError.)
820
gecos = w.pw_gecos.decode('utf-8')
824
gecos = w.pw_gecos.decode(bzrlib.user_encoding)
825
encoding = bzrlib.user_encoding
827
raise errors.BzrCommandError('Unable to determine your name. '
828
'Use "bzr whoami" to set it.')
830
username = w.pw_name.decode(encoding)
832
raise errors.BzrCommandError('Unable to determine your name. '
833
'Use "bzr whoami" to set it.')
536
835
comma = gecos.find(',')
565
864
m = re.search(r'[\w+.-]+@[\w+.-]+', e)
567
raise errors.BzrError("%r doesn't seem to contain "
568
"a reasonable email address" % e)
866
raise errors.NoEmailInUsername(e)
569
867
return m.group(0)
571
class TreeConfig(object):
870
class TreeConfig(IniBasedConfig):
572
871
"""Branch configuration data associated with its contents, not location"""
573
872
def __init__(self, branch):
574
873
self.branch = branch
875
def _get_parser(self, file=None):
877
return IniBasedConfig._get_parser(file)
878
return self._get_config()
576
880
def _get_config(self):
578
obj = ConfigObj(self.branch.control_files.get('branch.conf'),
882
obj = ConfigObj(self.branch.control_files.get('branch.conf'),
579
883
encoding='utf-8')
580
884
except errors.NoSuchFile:
581
885
obj = ConfigObj(encoding='utf=8')