1
# Copyright (C) 2005-2012 Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
"""Configuration that affects the behaviour of Bazaar.
21
Currently this configuration resides in ~/.bazaar/bazaar.conf
22
and ~/.bazaar/locations.conf, which is written to by bzr.
24
In bazaar.conf the following options may be set:
26
editor=name-of-program
27
email=Your Name <your@email.address>
28
check_signatures=require|ignore|check-available(default)
29
create_signatures=always|never|when-required(default)
30
gpg_signing_command=name-of-program
31
log_format=name-of-format
32
validate_signatures_in_log=true|false(default)
33
acceptable_keys=pattern1,pattern2
34
gpg_signing_key=amy@example.com
36
in locations.conf, you specify the url of a branch and options for it.
37
Wildcards may be used - * and ? as normal in shell completion. Options
38
set in both bazaar.conf and locations.conf are overridden by the locations.conf
40
[/home/robertc/source]
41
recurse=False|True(default)
43
check_signatures= as above
44
create_signatures= as above.
45
validate_signatures_in_log=as above
46
acceptable_keys=as above
48
explanation of options
49
----------------------
50
editor - this option sets the pop up editor to use during commits.
51
email - this option sets the user id bzr will use when committing.
52
check_signatures - this option will control whether bzr will require good gpg
53
signatures, ignore them, or check them if they are
54
present. Currently it is unused except that check_signatures
55
turns on create_signatures.
56
create_signatures - this option controls whether bzr will always create
57
gpg signatures or not on commits. There is an unused
58
option which in future is expected to work if
59
branch settings require signatures.
60
log_format - this option sets the default log format. Possible values are
61
long, short, line, or a plugin can register new formats.
62
validate_signatures_in_log - show GPG signature validity in log output
63
acceptable_keys - comma separated list of key patterns acceptable for
64
verify-signatures command
66
In bazaar.conf you can also define aliases in the ALIASES sections, example
69
lastlog=log --line -r-10..-1
70
ll=log --line -r-10..-1
75
from __future__ import absolute_import
76
from cStringIO import StringIO
81
from bzrlib.decorators import needs_write_lock
82
from bzrlib.lazy_import import lazy_import
83
lazy_import(globals(), """
105
from bzrlib.i18n import gettext
106
from bzrlib.util.configobj import configobj
114
from bzrlib.symbol_versioning import (
132
POLICY_APPENDPATH = 2
136
POLICY_NORECURSE: 'norecurse',
137
POLICY_APPENDPATH: 'appendpath',
142
'norecurse': POLICY_NORECURSE,
143
'appendpath': POLICY_APPENDPATH,
147
STORE_LOCATION = POLICY_NONE
148
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
149
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
154
def signature_policy_from_unicode(signature_string):
155
"""Convert a string to a signing policy."""
156
if signature_string.lower() == 'check-available':
157
return CHECK_IF_POSSIBLE
158
if signature_string.lower() == 'ignore':
160
if signature_string.lower() == 'require':
162
raise ValueError("Invalid signatures policy '%s'"
166
def signing_policy_from_unicode(signature_string):
167
"""Convert a string to a signing policy."""
168
if signature_string.lower() == 'when-required':
169
return SIGN_WHEN_REQUIRED
170
if signature_string.lower() == 'never':
172
if signature_string.lower() == 'always':
174
raise ValueError("Invalid signing policy '%s'"
178
class ConfigObj(configobj.ConfigObj):
180
def __init__(self, infile=None, **kwargs):
181
# We define our own interpolation mechanism calling it option expansion
182
super(ConfigObj, self).__init__(infile=infile,
186
def get_bool(self, section, key):
187
return self[section].as_bool(key)
189
def get_value(self, section, name):
190
# Try [] for the old DEFAULT section.
191
if section == "DEFAULT":
196
return self[section][name]
199
class Config(object):
200
"""A configuration policy - what username, editor, gpg needs etc."""
203
super(Config, self).__init__()
206
"""Returns a unique ID for the config."""
207
raise NotImplementedError(self.config_id)
209
def get_change_editor(self, old_tree, new_tree):
210
from bzrlib import diff
211
cmd = self._get_change_editor()
214
return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
217
def _get_signature_checking(self):
218
"""Template method to override signature checking policy."""
220
def _get_signing_policy(self):
221
"""Template method to override signature creation policy."""
225
def expand_options(self, string, env=None):
226
"""Expand option references in the string in the configuration context.
228
:param string: The string containing option to expand.
230
:param env: An option dict defining additional configuration options or
231
overriding existing ones.
233
:returns: The expanded string.
235
return self._expand_options_in_string(string, env)
237
def _expand_options_in_list(self, slist, env=None, _ref_stack=None):
238
"""Expand options in a list of strings in the configuration context.
240
:param slist: A list of strings.
242
:param env: An option dict defining additional configuration options or
243
overriding existing ones.
245
:param _ref_stack: Private list containing the options being
246
expanded to detect loops.
248
:returns: The flatten list of expanded strings.
250
# expand options in each value separately flattening lists
253
value = self._expand_options_in_string(s, env, _ref_stack)
254
if isinstance(value, list):
260
def _expand_options_in_string(self, string, env=None, _ref_stack=None):
261
"""Expand options in the string in the configuration context.
263
:param string: The string to be expanded.
265
:param env: An option dict defining additional configuration options or
266
overriding existing ones.
268
:param _ref_stack: Private list containing the options being
269
expanded to detect loops.
271
:returns: The expanded string.
274
# Not much to expand there
276
if _ref_stack is None:
277
# What references are currently resolved (to detect loops)
279
if self.option_ref_re is None:
280
# We want to match the most embedded reference first (i.e. for
281
# '{{foo}}' we will get '{foo}',
282
# for '{bar{baz}}' we will get '{baz}'
283
self.option_ref_re = re.compile('({[^{}]+})')
285
# We need to iterate until no more refs appear ({{foo}} will need two
286
# iterations for example).
288
raw_chunks = self.option_ref_re.split(result)
289
if len(raw_chunks) == 1:
290
# Shorcut the trivial case: no refs
294
# Split will isolate refs so that every other chunk is a ref
296
for chunk in raw_chunks:
299
# Keep only non-empty strings (or we get bogus empty
300
# slots when a list value is involved).
305
if name in _ref_stack:
306
raise errors.OptionExpansionLoop(string, _ref_stack)
307
_ref_stack.append(name)
308
value = self._expand_option(name, env, _ref_stack)
310
raise errors.ExpandingUnknownOption(name, string)
311
if isinstance(value, list):
319
# Once a list appears as the result of an expansion, all
320
# callers will get a list result. This allows a consistent
321
# behavior even when some options in the expansion chain
322
# defined as strings (no comma in their value) but their
323
# expanded value is a list.
324
return self._expand_options_in_list(chunks, env, _ref_stack)
326
result = ''.join(chunks)
329
def _expand_option(self, name, env, _ref_stack):
330
if env is not None and name in env:
331
# Special case, values provided in env takes precedence over
335
# FIXME: This is a limited implementation, what we really need is a
336
# way to query the bzr config for the value of an option,
337
# respecting the scope rules (That is, once we implement fallback
338
# configs, getting the option value should restart from the top
339
# config, not the current one) -- vila 20101222
340
value = self.get_user_option(name, expand=False)
341
if isinstance(value, list):
342
value = self._expand_options_in_list(value, env, _ref_stack)
344
value = self._expand_options_in_string(value, env, _ref_stack)
347
def _get_user_option(self, option_name):
348
"""Template method to provide a user option."""
351
def get_user_option(self, option_name, expand=True):
352
"""Get a generic option - no special process, no default.
354
:param option_name: The queried option.
356
:param expand: Whether options references should be expanded.
358
:returns: The value of the option.
360
value = self._get_user_option(option_name)
362
if isinstance(value, list):
363
value = self._expand_options_in_list(value)
364
elif isinstance(value, dict):
365
trace.warning('Cannot expand "%s":'
366
' Dicts do not support option expansion'
369
value = self._expand_options_in_string(value)
370
for hook in OldConfigHooks['get']:
371
hook(self, option_name, value)
374
def get_user_option_as_bool(self, option_name, expand=None, default=None):
375
"""Get a generic option as a boolean.
377
:param expand: Allow expanding references to other config values.
378
:param default: Default value if nothing is configured
379
:return None if the option doesn't exist or its value can't be
380
interpreted as a boolean. Returns True or False otherwise.
382
s = self.get_user_option(option_name, expand=expand)
384
# The option doesn't exist
386
val = ui.bool_from_string(s)
388
# The value can't be interpreted as a boolean
389
trace.warning('Value "%s" is not a boolean for "%s"',
393
def get_user_option_as_list(self, option_name, expand=None):
394
"""Get a generic option as a list - no special process, no default.
396
:return None if the option doesn't exist. Returns the value as a list
399
l = self.get_user_option(option_name, expand=expand)
400
if isinstance(l, (str, unicode)):
401
# A single value, most probably the user forgot (or didn't care to
406
@deprecated_method(deprecated_in((2, 5, 0)))
407
def get_user_option_as_int_from_SI(self, option_name, default=None):
408
"""Get a generic option from a human readable size in SI units, e.g 10MB
410
Accepted suffixes are K,M,G. It is case-insensitive and may be followed
411
by a trailing b (i.e. Kb, MB). This is intended to be practical and not
414
:return Integer, expanded to its base-10 value if a proper SI unit is
415
found. If the option doesn't exist, or isn't a value in
416
SI units, return default (which defaults to None)
418
val = self.get_user_option(option_name)
419
if isinstance(val, list):
424
p = re.compile("^(\d+)([kmg])*b*$", re.IGNORECASE)
428
val = int(m.group(1))
429
if m.group(2) is not None:
430
if m.group(2).lower() == 'k':
432
elif m.group(2).lower() == 'm':
434
elif m.group(2).lower() == 'g':
437
ui.ui_factory.show_warning(gettext('Invalid config value for "{0}" '
438
' value {1!r} is not an SI unit.').format(
445
@deprecated_method(deprecated_in((2, 5, 0)))
446
def gpg_signing_command(self):
447
"""What program should be used to sign signatures?"""
448
result = self._gpg_signing_command()
453
def _gpg_signing_command(self):
454
"""See gpg_signing_command()."""
457
@deprecated_method(deprecated_in((2, 5, 0)))
458
def log_format(self):
459
"""What log format should be used"""
460
result = self._log_format()
465
def _log_format(self):
466
"""See log_format()."""
469
def validate_signatures_in_log(self):
470
"""Show GPG signature validity in log"""
471
result = self._validate_signatures_in_log()
478
def _validate_signatures_in_log(self):
479
"""See validate_signatures_in_log()."""
482
@deprecated_method(deprecated_in((2, 5, 0)))
483
def acceptable_keys(self):
484
"""Comma separated list of key patterns acceptable to
485
verify-signatures command"""
486
result = self._acceptable_keys()
489
def _acceptable_keys(self):
490
"""See acceptable_keys()."""
493
@deprecated_method(deprecated_in((2, 5, 0)))
494
def post_commit(self):
495
"""An ordered list of python functions to call.
497
Each function takes branch, rev_id as parameters.
499
return self._post_commit()
501
def _post_commit(self):
502
"""See Config.post_commit."""
505
def user_email(self):
506
"""Return just the email component of a username."""
507
return extract_email_address(self.username())
510
"""Return email-style username.
512
Something similar to 'Martin Pool <mbp@sourcefrog.net>'
514
$BZR_EMAIL can be set to override this, then
515
the concrete policy type is checked, and finally
517
If no username can be found, errors.NoWhoami exception is raised.
519
v = os.environ.get('BZR_EMAIL')
521
return v.decode(osutils.get_user_encoding())
522
v = self._get_user_id()
525
return default_email()
527
def ensure_username(self):
528
"""Raise errors.NoWhoami if username is not set.
530
This method relies on the username() function raising the error.
534
@deprecated_method(deprecated_in((2, 5, 0)))
535
def signature_checking(self):
536
"""What is the current policy for signature checking?."""
537
policy = self._get_signature_checking()
538
if policy is not None:
540
return CHECK_IF_POSSIBLE
542
@deprecated_method(deprecated_in((2, 5, 0)))
543
def signing_policy(self):
544
"""What is the current policy for signature checking?."""
545
policy = self._get_signing_policy()
546
if policy is not None:
548
return SIGN_WHEN_REQUIRED
550
@deprecated_method(deprecated_in((2, 5, 0)))
551
def signature_needed(self):
552
"""Is a signature needed when committing ?."""
553
policy = self._get_signing_policy()
555
policy = self._get_signature_checking()
556
if policy is not None:
557
#this warning should go away once check_signatures is
558
#implemented (if not before)
559
trace.warning("Please use create_signatures,"
560
" not check_signatures to set signing policy.")
561
elif policy == SIGN_ALWAYS:
565
@deprecated_method(deprecated_in((2, 5, 0)))
566
def gpg_signing_key(self):
567
"""GPG user-id to sign commits"""
568
key = self.get_user_option('gpg_signing_key')
569
if key == "default" or key == None:
570
return self.user_email()
574
def get_alias(self, value):
575
return self._get_alias(value)
577
def _get_alias(self, value):
580
def get_nickname(self):
581
return self._get_nickname()
583
def _get_nickname(self):
586
def get_bzr_remote_path(self):
588
return os.environ['BZR_REMOTE_PATH']
590
path = self.get_user_option("bzr_remote_path")
595
def suppress_warning(self, warning):
596
"""Should the warning be suppressed or emitted.
598
:param warning: The name of the warning being tested.
600
:returns: True if the warning should be suppressed, False otherwise.
602
warnings = self.get_user_option_as_list('suppress_warnings')
603
if warnings is None or warning not in warnings:
608
def get_merge_tools(self):
610
for (oname, value, section, conf_id, parser) in self._get_options():
611
if oname.startswith('bzr.mergetool.'):
612
tool_name = oname[len('bzr.mergetool.'):]
613
tools[tool_name] = self.get_user_option(oname, False)
614
trace.mutter('loaded merge tools: %r' % tools)
617
def find_merge_tool(self, name):
618
# We fake a defaults mechanism here by checking if the given name can
619
# be found in the known_merge_tools if it's not found in the config.
620
# This should be done through the proposed config defaults mechanism
621
# when it becomes available in the future.
622
command_line = (self.get_user_option('bzr.mergetool.%s' % name,
624
or mergetools.known_merge_tools.get(name, None))
628
class _ConfigHooks(hooks.Hooks):
629
"""A dict mapping hook names and a list of callables for configs.
633
"""Create the default hooks.
635
These are all empty initially, because by default nothing should get
638
super(_ConfigHooks, self).__init__('bzrlib.config', 'ConfigHooks')
639
self.add_hook('load',
640
'Invoked when a config store is loaded.'
641
' The signature is (store).',
643
self.add_hook('save',
644
'Invoked when a config store is saved.'
645
' The signature is (store).',
647
# The hooks for config options
649
'Invoked when a config option is read.'
650
' The signature is (stack, name, value).',
653
'Invoked when a config option is set.'
654
' The signature is (stack, name, value).',
656
self.add_hook('remove',
657
'Invoked when a config option is removed.'
658
' The signature is (stack, name).',
660
ConfigHooks = _ConfigHooks()
663
class _OldConfigHooks(hooks.Hooks):
664
"""A dict mapping hook names and a list of callables for configs.
668
"""Create the default hooks.
670
These are all empty initially, because by default nothing should get
673
super(_OldConfigHooks, self).__init__('bzrlib.config', 'OldConfigHooks')
674
self.add_hook('load',
675
'Invoked when a config store is loaded.'
676
' The signature is (config).',
678
self.add_hook('save',
679
'Invoked when a config store is saved.'
680
' The signature is (config).',
682
# The hooks for config options
684
'Invoked when a config option is read.'
685
' The signature is (config, name, value).',
688
'Invoked when a config option is set.'
689
' The signature is (config, name, value).',
691
self.add_hook('remove',
692
'Invoked when a config option is removed.'
693
' The signature is (config, name).',
695
OldConfigHooks = _OldConfigHooks()
698
class IniBasedConfig(Config):
699
"""A configuration policy that draws from ini files."""
701
def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
703
"""Base class for configuration files using an ini-like syntax.
705
:param file_name: The configuration file path.
707
super(IniBasedConfig, self).__init__()
708
self.file_name = file_name
709
if symbol_versioning.deprecated_passed(get_filename):
710
symbol_versioning.warn(
711
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
712
' Use file_name instead.',
715
if get_filename is not None:
716
self.file_name = get_filename()
718
self.file_name = file_name
723
def from_string(cls, str_or_unicode, file_name=None, save=False):
724
"""Create a config object from a string.
726
:param str_or_unicode: A string representing the file content. This will
729
:param file_name: The configuration file path.
731
:param _save: Whether the file should be saved upon creation.
733
conf = cls(file_name=file_name)
734
conf._create_from_string(str_or_unicode, save)
737
def _create_from_string(self, str_or_unicode, save):
738
self._content = StringIO(str_or_unicode.encode('utf-8'))
739
# Some tests use in-memory configs, some other always need the config
740
# file to exist on disk.
742
self._write_config_file()
744
def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
745
if self._parser is not None:
747
if symbol_versioning.deprecated_passed(file):
748
symbol_versioning.warn(
749
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
750
' Use IniBasedConfig(_content=xxx) instead.',
753
if self._content is not None:
754
co_input = self._content
755
elif self.file_name is None:
756
raise AssertionError('We have no content to create the config')
758
co_input = self.file_name
760
self._parser = ConfigObj(co_input, encoding='utf-8')
761
except configobj.ConfigObjError, e:
762
raise errors.ParseConfigError(e.errors, e.config.filename)
763
except UnicodeDecodeError:
764
raise errors.ConfigContentError(self.file_name)
765
# Make sure self.reload() will use the right file name
766
self._parser.filename = self.file_name
767
for hook in OldConfigHooks['load']:
772
"""Reload the config file from disk."""
773
if self.file_name is None:
774
raise AssertionError('We need a file name to reload the config')
775
if self._parser is not None:
776
self._parser.reload()
777
for hook in ConfigHooks['load']:
780
def _get_matching_sections(self):
781
"""Return an ordered list of (section_name, extra_path) pairs.
783
If the section contains inherited configuration, extra_path is
784
a string containing the additional path components.
786
section = self._get_section()
787
if section is not None:
788
return [(section, '')]
792
def _get_section(self):
793
"""Override this to define the section used by the config."""
796
def _get_sections(self, name=None):
797
"""Returns an iterator of the sections specified by ``name``.
799
:param name: The section name. If None is supplied, the default
800
configurations are yielded.
802
:return: A tuple (name, section, config_id) for all sections that will
803
be walked by user_get_option() in the 'right' order. The first one
804
is where set_user_option() will update the value.
806
parser = self._get_parser()
808
yield (name, parser[name], self.config_id())
810
# No section name has been given so we fallback to the configobj
811
# itself which holds the variables defined outside of any section.
812
yield (None, parser, self.config_id())
814
def _get_options(self, sections=None):
815
"""Return an ordered list of (name, value, section, config_id) tuples.
817
All options are returned with their associated value and the section
818
they appeared in. ``config_id`` is a unique identifier for the
819
configuration file the option is defined in.
821
:param sections: Default to ``_get_matching_sections`` if not
822
specified. This gives a better control to daughter classes about
823
which sections should be searched. This is a list of (name,
828
parser = self._get_parser()
830
for (section_name, _) in self._get_matching_sections():
832
section = parser[section_name]
834
# This could happen for an empty file for which we define a
835
# DEFAULT section. FIXME: Force callers to provide sections
836
# instead ? -- vila 20100930
838
sections.append((section_name, section))
839
config_id = self.config_id()
840
for (section_name, section) in sections:
841
for (name, value) in section.iteritems():
842
yield (name, parser._quote(value), section_name,
845
def _get_option_policy(self, section, option_name):
846
"""Return the policy for the given (section, option_name) pair."""
849
def _get_change_editor(self):
850
return self.get_user_option('change_editor')
852
def _get_signature_checking(self):
853
"""See Config._get_signature_checking."""
854
policy = self._get_user_option('check_signatures')
856
return signature_policy_from_unicode(policy)
858
def _get_signing_policy(self):
859
"""See Config._get_signing_policy"""
860
policy = self._get_user_option('create_signatures')
862
return signing_policy_from_unicode(policy)
864
def _get_user_id(self):
865
"""Get the user id from the 'email' key in the current section."""
866
return self._get_user_option('email')
868
def _get_user_option(self, option_name):
869
"""See Config._get_user_option."""
870
for (section, extra_path) in self._get_matching_sections():
872
value = self._get_parser().get_value(section, option_name)
875
policy = self._get_option_policy(section, option_name)
876
if policy == POLICY_NONE:
878
elif policy == POLICY_NORECURSE:
879
# norecurse items only apply to the exact path
884
elif policy == POLICY_APPENDPATH:
886
value = urlutils.join(value, extra_path)
889
raise AssertionError('Unexpected config policy %r' % policy)
893
def _gpg_signing_command(self):
894
"""See Config.gpg_signing_command."""
895
return self._get_user_option('gpg_signing_command')
897
def _log_format(self):
898
"""See Config.log_format."""
899
return self._get_user_option('log_format')
901
def _validate_signatures_in_log(self):
902
"""See Config.validate_signatures_in_log."""
903
return self._get_user_option('validate_signatures_in_log')
905
def _acceptable_keys(self):
906
"""See Config.acceptable_keys."""
907
return self._get_user_option('acceptable_keys')
909
def _post_commit(self):
910
"""See Config.post_commit."""
911
return self._get_user_option('post_commit')
913
def _get_alias(self, value):
915
return self._get_parser().get_value("ALIASES",
920
def _get_nickname(self):
921
return self.get_user_option('nickname')
923
def remove_user_option(self, option_name, section_name=None):
924
"""Remove a user option and save the configuration file.
926
:param option_name: The option to be removed.
928
:param section_name: The section the option is defined in, default to
932
parser = self._get_parser()
933
if section_name is None:
936
section = parser[section_name]
938
del section[option_name]
940
raise errors.NoSuchConfigOption(option_name)
941
self._write_config_file()
942
for hook in OldConfigHooks['remove']:
943
hook(self, option_name)
945
def _write_config_file(self):
946
if self.file_name is None:
947
raise AssertionError('We cannot save, self.file_name is None')
948
conf_dir = os.path.dirname(self.file_name)
949
ensure_config_dir_exists(conf_dir)
950
atomic_file = atomicfile.AtomicFile(self.file_name)
951
self._get_parser().write(atomic_file)
954
osutils.copy_ownership_from_path(self.file_name)
955
for hook in OldConfigHooks['save']:
959
class LockableConfig(IniBasedConfig):
960
"""A configuration needing explicit locking for access.
962
If several processes try to write the config file, the accesses need to be
965
Daughter classes should decorate all methods that update a config with the
966
``@needs_write_lock`` decorator (they call, directly or indirectly, the
967
``_write_config_file()`` method. These methods (typically ``set_option()``
968
and variants must reload the config file from disk before calling
969
``_write_config_file()``), this can be achieved by calling the
970
``self.reload()`` method. Note that the lock scope should cover both the
971
reading and the writing of the config file which is why the decorator can't
972
be applied to ``_write_config_file()`` only.
974
This should be enough to implement the following logic:
975
- lock for exclusive write access,
976
- reload the config file from disk,
980
This logic guarantees that a writer can update a value without erasing an
981
update made by another writer.
986
def __init__(self, file_name):
987
super(LockableConfig, self).__init__(file_name=file_name)
988
self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
989
# FIXME: It doesn't matter that we don't provide possible_transports
990
# below since this is currently used only for local config files ;
991
# local transports are not shared. But if/when we start using
992
# LockableConfig for other kind of transports, we will need to reuse
993
# whatever connection is already established -- vila 20100929
994
self.transport = transport.get_transport_from_path(self.dir)
995
self._lock = lockdir.LockDir(self.transport, self.lock_name)
997
def _create_from_string(self, unicode_bytes, save):
998
super(LockableConfig, self)._create_from_string(unicode_bytes, False)
1000
# We need to handle the saving here (as opposed to IniBasedConfig)
1001
# to be able to lock
1003
self._write_config_file()
1006
def lock_write(self, token=None):
1007
"""Takes a write lock in the directory containing the config file.
1009
If the directory doesn't exist it is created.
1011
ensure_config_dir_exists(self.dir)
1012
return self._lock.lock_write(token)
1017
def break_lock(self):
1018
self._lock.break_lock()
1021
def remove_user_option(self, option_name, section_name=None):
1022
super(LockableConfig, self).remove_user_option(option_name,
1025
def _write_config_file(self):
1026
if self._lock is None or not self._lock.is_held:
1027
# NB: if the following exception is raised it probably means a
1028
# missing @needs_write_lock decorator on one of the callers.
1029
raise errors.ObjectNotLocked(self)
1030
super(LockableConfig, self)._write_config_file()
1033
class GlobalConfig(LockableConfig):
1034
"""The configuration that should be used for a specific location."""
1037
super(GlobalConfig, self).__init__(file_name=config_filename())
1039
def config_id(self):
1043
def from_string(cls, str_or_unicode, save=False):
1044
"""Create a config object from a string.
1046
:param str_or_unicode: A string representing the file content. This
1047
will be utf-8 encoded.
1049
:param save: Whether the file should be saved upon creation.
1052
conf._create_from_string(str_or_unicode, save)
1056
def set_user_option(self, option, value):
1057
"""Save option and its value in the configuration."""
1058
self._set_option(option, value, 'DEFAULT')
1060
def get_aliases(self):
1061
"""Return the aliases section."""
1062
if 'ALIASES' in self._get_parser():
1063
return self._get_parser()['ALIASES']
1068
def set_alias(self, alias_name, alias_command):
1069
"""Save the alias in the configuration."""
1070
self._set_option(alias_name, alias_command, 'ALIASES')
1073
def unset_alias(self, alias_name):
1074
"""Unset an existing alias."""
1076
aliases = self._get_parser().get('ALIASES')
1077
if not aliases or alias_name not in aliases:
1078
raise errors.NoSuchAlias(alias_name)
1079
del aliases[alias_name]
1080
self._write_config_file()
1082
def _set_option(self, option, value, section):
1084
self._get_parser().setdefault(section, {})[option] = value
1085
self._write_config_file()
1086
for hook in OldConfigHooks['set']:
1087
hook(self, option, value)
1089
def _get_sections(self, name=None):
1090
"""See IniBasedConfig._get_sections()."""
1091
parser = self._get_parser()
1092
# We don't give access to options defined outside of any section, we
1093
# used the DEFAULT section by... default.
1094
if name in (None, 'DEFAULT'):
1095
# This could happen for an empty file where the DEFAULT section
1096
# doesn't exist yet. So we force DEFAULT when yielding
1098
if 'DEFAULT' not in parser:
1099
parser['DEFAULT']= {}
1100
yield (name, parser[name], self.config_id())
1103
def remove_user_option(self, option_name, section_name=None):
1104
if section_name is None:
1105
# We need to force the default section.
1106
section_name = 'DEFAULT'
1107
# We need to avoid the LockableConfig implementation or we'll lock
1109
super(LockableConfig, self).remove_user_option(option_name,
1112
def _iter_for_location_by_parts(sections, location):
1113
"""Keep only the sessions matching the specified location.
1115
:param sections: An iterable of section names.
1117
:param location: An url or a local path to match against.
1119
:returns: An iterator of (section, extra_path, nb_parts) where nb is the
1120
number of path components in the section name, section is the section
1121
name and extra_path is the difference between location and the section
1124
``location`` will always be a local path and never a 'file://' url but the
1125
section names themselves can be in either form.
1127
location_parts = location.rstrip('/').split('/')
1129
for section in sections:
1130
# location is a local path if possible, so we need to convert 'file://'
1131
# urls in section names to local paths if necessary.
1133
# This also avoids having file:///path be a more exact
1134
# match than '/path'.
1136
# FIXME: This still raises an issue if a user defines both file:///path
1137
# *and* /path. Should we raise an error in this case -- vila 20110505
1139
if section.startswith('file://'):
1140
section_path = urlutils.local_path_from_url(section)
1142
section_path = section
1143
section_parts = section_path.rstrip('/').split('/')
1146
if len(section_parts) > len(location_parts):
1147
# More path components in the section, they can't match
1150
# Rely on zip truncating in length to the length of the shortest
1151
# argument sequence.
1152
names = zip(location_parts, section_parts)
1154
if not fnmatch.fnmatch(name[0], name[1]):
1159
# build the path difference between the section and the location
1160
extra_path = '/'.join(location_parts[len(section_parts):])
1161
yield section, extra_path, len(section_parts)
1164
class LocationConfig(LockableConfig):
1165
"""A configuration object that gives the policy for a location."""
1167
def __init__(self, location):
1168
super(LocationConfig, self).__init__(
1169
file_name=locations_config_filename())
1170
# local file locations are looked up by local path, rather than
1171
# by file url. This is because the config file is a user
1172
# file, and we would rather not expose the user to file urls.
1173
if location.startswith('file://'):
1174
location = urlutils.local_path_from_url(location)
1175
self.location = location
1177
def config_id(self):
1181
def from_string(cls, str_or_unicode, location, save=False):
1182
"""Create a config object from a string.
1184
:param str_or_unicode: A string representing the file content. This will
1187
:param location: The location url to filter the configuration.
1189
:param save: Whether the file should be saved upon creation.
1191
conf = cls(location)
1192
conf._create_from_string(str_or_unicode, save)
1195
def _get_matching_sections(self):
1196
"""Return an ordered list of section names matching this location."""
1197
matches = list(_iter_for_location_by_parts(self._get_parser(),
1199
# put the longest (aka more specific) locations first
1201
key=lambda (section, extra_path, length): (length, section),
1203
for (section, extra_path, length) in matches:
1204
yield section, extra_path
1205
# should we stop looking for parent configs here?
1207
if self._get_parser()[section].as_bool('ignore_parents'):
1212
def _get_sections(self, name=None):
1213
"""See IniBasedConfig._get_sections()."""
1214
# We ignore the name here as the only sections handled are named with
1215
# the location path and we don't expose embedded sections either.
1216
parser = self._get_parser()
1217
for name, extra_path in self._get_matching_sections():
1218
yield (name, parser[name], self.config_id())
1220
def _get_option_policy(self, section, option_name):
1221
"""Return the policy for the given (section, option_name) pair."""
1222
# check for the old 'recurse=False' flag
1224
recurse = self._get_parser()[section].as_bool('recurse')
1228
return POLICY_NORECURSE
1230
policy_key = option_name + ':policy'
1232
policy_name = self._get_parser()[section][policy_key]
1236
return _policy_value[policy_name]
1238
def _set_option_policy(self, section, option_name, option_policy):
1239
"""Set the policy for the given option name in the given section."""
1240
# The old recurse=False option affects all options in the
1241
# section. To handle multiple policies in the section, we
1242
# need to convert it to a policy_norecurse key.
1244
recurse = self._get_parser()[section].as_bool('recurse')
1248
symbol_versioning.warn(
1249
'The recurse option is deprecated as of 0.14. '
1250
'The section "%s" has been converted to use policies.'
1253
del self._get_parser()[section]['recurse']
1255
for key in self._get_parser()[section].keys():
1256
if not key.endswith(':policy'):
1257
self._get_parser()[section][key +
1258
':policy'] = 'norecurse'
1260
policy_key = option_name + ':policy'
1261
policy_name = _policy_name[option_policy]
1262
if policy_name is not None:
1263
self._get_parser()[section][policy_key] = policy_name
1265
if policy_key in self._get_parser()[section]:
1266
del self._get_parser()[section][policy_key]
1269
def set_user_option(self, option, value, store=STORE_LOCATION):
1270
"""Save option and its value in the configuration."""
1271
if store not in [STORE_LOCATION,
1272
STORE_LOCATION_NORECURSE,
1273
STORE_LOCATION_APPENDPATH]:
1274
raise ValueError('bad storage policy %r for %r' %
1277
location = self.location
1278
if location.endswith('/'):
1279
location = location[:-1]
1280
parser = self._get_parser()
1281
if not location in parser and not location + '/' in parser:
1282
parser[location] = {}
1283
elif location + '/' in parser:
1284
location = location + '/'
1285
parser[location][option]=value
1286
# the allowed values of store match the config policies
1287
self._set_option_policy(location, option, store)
1288
self._write_config_file()
1289
for hook in OldConfigHooks['set']:
1290
hook(self, option, value)
1293
class BranchConfig(Config):
1294
"""A configuration object giving the policy for a branch."""
1296
def __init__(self, branch):
1297
super(BranchConfig, self).__init__()
1298
self._location_config = None
1299
self._branch_data_config = None
1300
self._global_config = None
1301
self.branch = branch
1302
self.option_sources = (self._get_location_config,
1303
self._get_branch_data_config,
1304
self._get_global_config)
1306
def config_id(self):
1309
def _get_branch_data_config(self):
1310
if self._branch_data_config is None:
1311
self._branch_data_config = TreeConfig(self.branch)
1312
self._branch_data_config.config_id = self.config_id
1313
return self._branch_data_config
1315
def _get_location_config(self):
1316
if self._location_config is None:
1317
self._location_config = LocationConfig(self.branch.base)
1318
return self._location_config
1320
def _get_global_config(self):
1321
if self._global_config is None:
1322
self._global_config = GlobalConfig()
1323
return self._global_config
1325
def _get_best_value(self, option_name):
1326
"""This returns a user option from local, tree or global config.
1328
They are tried in that order. Use get_safe_value if trusted values
1331
for source in self.option_sources:
1332
value = getattr(source(), option_name)()
1333
if value is not None:
1337
def _get_safe_value(self, option_name):
1338
"""This variant of get_best_value never returns untrusted values.
1340
It does not return values from the branch data, because the branch may
1341
not be controlled by the user.
1343
We may wish to allow locations.conf to control whether branches are
1344
trusted in the future.
1346
for source in (self._get_location_config, self._get_global_config):
1347
value = getattr(source(), option_name)()
1348
if value is not None:
1352
def _get_user_id(self):
1353
"""Return the full user id for the branch.
1355
e.g. "John Hacker <jhacker@example.com>"
1356
This is looked up in the email controlfile for the branch.
1358
return self._get_best_value('_get_user_id')
1360
def _get_change_editor(self):
1361
return self._get_best_value('_get_change_editor')
1363
def _get_signature_checking(self):
1364
"""See Config._get_signature_checking."""
1365
return self._get_best_value('_get_signature_checking')
1367
def _get_signing_policy(self):
1368
"""See Config._get_signing_policy."""
1369
return self._get_best_value('_get_signing_policy')
1371
def _get_user_option(self, option_name):
1372
"""See Config._get_user_option."""
1373
for source in self.option_sources:
1374
value = source()._get_user_option(option_name)
1375
if value is not None:
1379
def _get_sections(self, name=None):
1380
"""See IniBasedConfig.get_sections()."""
1381
for source in self.option_sources:
1382
for section in source()._get_sections(name):
1385
def _get_options(self, sections=None):
1387
# First the locations options
1388
for option in self._get_location_config()._get_options():
1390
# Then the branch options
1391
branch_config = self._get_branch_data_config()
1392
if sections is None:
1393
sections = [('DEFAULT', branch_config._get_parser())]
1394
# FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
1395
# Config itself has no notion of sections :( -- vila 20101001
1396
config_id = self.config_id()
1397
for (section_name, section) in sections:
1398
for (name, value) in section.iteritems():
1399
yield (name, value, section_name,
1400
config_id, branch_config._get_parser())
1401
# Then the global options
1402
for option in self._get_global_config()._get_options():
1405
def set_user_option(self, name, value, store=STORE_BRANCH,
1407
if store == STORE_BRANCH:
1408
self._get_branch_data_config().set_option(value, name)
1409
elif store == STORE_GLOBAL:
1410
self._get_global_config().set_user_option(name, value)
1412
self._get_location_config().set_user_option(name, value, store)
1415
if store in (STORE_GLOBAL, STORE_BRANCH):
1416
mask_value = self._get_location_config().get_user_option(name)
1417
if mask_value is not None:
1418
trace.warning('Value "%s" is masked by "%s" from'
1419
' locations.conf', value, mask_value)
1421
if store == STORE_GLOBAL:
1422
branch_config = self._get_branch_data_config()
1423
mask_value = branch_config.get_user_option(name)
1424
if mask_value is not None:
1425
trace.warning('Value "%s" is masked by "%s" from'
1426
' branch.conf', value, mask_value)
1428
def remove_user_option(self, option_name, section_name=None):
1429
self._get_branch_data_config().remove_option(option_name, section_name)
1431
def _gpg_signing_command(self):
1432
"""See Config.gpg_signing_command."""
1433
return self._get_safe_value('_gpg_signing_command')
1435
def _post_commit(self):
1436
"""See Config.post_commit."""
1437
return self._get_safe_value('_post_commit')
1439
def _get_nickname(self):
1440
value = self._get_explicit_nickname()
1441
if value is not None:
1443
if self.branch.name:
1444
return self.branch.name
1445
return urlutils.unescape(self.branch.base.split('/')[-2])
1447
def has_explicit_nickname(self):
1448
"""Return true if a nickname has been explicitly assigned."""
1449
return self._get_explicit_nickname() is not None
1451
def _get_explicit_nickname(self):
1452
return self._get_best_value('_get_nickname')
1454
def _log_format(self):
1455
"""See Config.log_format."""
1456
return self._get_best_value('_log_format')
1458
def _validate_signatures_in_log(self):
1459
"""See Config.validate_signatures_in_log."""
1460
return self._get_best_value('_validate_signatures_in_log')
1462
def _acceptable_keys(self):
1463
"""See Config.acceptable_keys."""
1464
return self._get_best_value('_acceptable_keys')
1467
def ensure_config_dir_exists(path=None):
1468
"""Make sure a configuration directory exists.
1469
This makes sure that the directory exists.
1470
On windows, since configuration directories are 2 levels deep,
1471
it makes sure both the directory and the parent directory exists.
1475
if not os.path.isdir(path):
1476
if sys.platform == 'win32':
1477
parent_dir = os.path.dirname(path)
1478
if not os.path.isdir(parent_dir):
1479
trace.mutter('creating config parent directory: %r', parent_dir)
1480
os.mkdir(parent_dir)
1481
trace.mutter('creating config directory: %r', path)
1483
osutils.copy_ownership_from_path(path)
1487
"""Return per-user configuration directory as unicode string
1489
By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1490
and Linux. On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1491
that will be used instead.
1493
TODO: Global option --config-dir to override this.
1495
base = osutils.path_from_environ('BZR_HOME')
1496
if sys.platform == 'win32':
1498
base = win32utils.get_appdata_location()
1500
base = win32utils.get_home_location()
1501
# GZ 2012-02-01: Really the two level subdirs only make sense inside
1502
# APPDATA, but hard to move. See bug 348640 for more.
1503
return osutils.pathjoin(base, 'bazaar', '2.0')
1505
# GZ 2012-02-01: What should OSX use instead of XDG if anything?
1506
if sys.platform != 'darwin':
1507
xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1509
xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1510
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1511
if osutils.isdir(xdg_dir):
1513
"Using configuration in XDG directory %s." % xdg_dir)
1515
base = osutils._get_home_dir()
1516
return osutils.pathjoin(base, ".bazaar")
1519
def config_filename():
1520
"""Return per-user configuration ini file filename."""
1521
return osutils.pathjoin(config_dir(), 'bazaar.conf')
1524
def locations_config_filename():
1525
"""Return per-user configuration ini file filename."""
1526
return osutils.pathjoin(config_dir(), 'locations.conf')
1529
def authentication_config_filename():
1530
"""Return per-user authentication ini file filename."""
1531
return osutils.pathjoin(config_dir(), 'authentication.conf')
1534
def user_ignore_config_filename():
1535
"""Return the user default ignore filename"""
1536
return osutils.pathjoin(config_dir(), 'ignore')
1540
"""Return the directory name to store crash files.
1542
This doesn't implicitly create it.
1544
On Windows it's in the config directory; elsewhere it's /var/crash
1545
which may be monitored by apport. It can be overridden by
1548
if sys.platform == 'win32':
1549
return osutils.pathjoin(config_dir(), 'Crash')
1551
# XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
1553
return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
1556
def xdg_cache_dir():
1557
# See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1558
# Possibly this should be different on Windows?
1559
e = os.environ.get('XDG_CACHE_DIR', None)
1563
return os.path.expanduser('~/.cache')
1566
def _get_default_mail_domain(mailname_file='/etc/mailname'):
1567
"""If possible, return the assumed default email domain.
1569
:returns: string mail domain, or None.
1571
if sys.platform == 'win32':
1572
# No implementation yet; patches welcome
1575
f = open(mailname_file)
1576
except (IOError, OSError), e:
1579
domain = f.readline().strip()
1585
def default_email():
1586
v = os.environ.get('BZR_EMAIL')
1588
return v.decode(osutils.get_user_encoding())
1589
v = os.environ.get('EMAIL')
1591
return v.decode(osutils.get_user_encoding())
1592
name, email = _auto_user_id()
1594
return u'%s <%s>' % (name, email)
1597
raise errors.NoWhoami()
1600
def _auto_user_id():
1601
"""Calculate automatic user identification.
1603
:returns: (realname, email), either of which may be None if they can't be
1606
Only used when none is set in the environment or the id file.
1608
This only returns an email address if we can be fairly sure the
1609
address is reasonable, ie if /etc/mailname is set on unix.
1611
This doesn't use the FQDN as the default domain because that may be
1612
slow, and it doesn't use the hostname alone because that's not normally
1613
a reasonable address.
1615
if sys.platform == 'win32':
1616
# No implementation to reliably determine Windows default mail
1617
# address; please add one.
1620
default_mail_domain = _get_default_mail_domain()
1621
if not default_mail_domain:
1627
w = pwd.getpwuid(uid)
1629
trace.mutter('no passwd entry for uid %d?' % uid)
1632
# we try utf-8 first, because on many variants (like Linux),
1633
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
1634
# false positives. (many users will have their user encoding set to
1635
# latin-1, which cannot raise UnicodeError.)
1637
gecos = w.pw_gecos.decode('utf-8')
1639
except UnicodeError:
1641
encoding = osutils.get_user_encoding()
1642
gecos = w.pw_gecos.decode(encoding)
1643
except UnicodeError, e:
1644
trace.mutter("cannot decode passwd entry %s" % w)
1647
username = w.pw_name.decode(encoding)
1648
except UnicodeError, e:
1649
trace.mutter("cannot decode passwd entry %s" % w)
1652
comma = gecos.find(',')
1656
realname = gecos[:comma]
1658
return realname, (username + '@' + default_mail_domain)
1661
def parse_username(username):
1662
"""Parse e-mail username and return a (name, address) tuple."""
1663
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1665
return (username, '')
1667
return (match.group(1), match.group(2))
1670
def extract_email_address(e):
1671
"""Return just the address part of an email string.
1673
That is just the user@domain part, nothing else.
1674
This part is required to contain only ascii characters.
1675
If it can't be extracted, raises an error.
1677
>>> extract_email_address('Jane Tester <jane@test.com>')
1680
name, email = parse_username(e)
1682
raise errors.NoEmailInUsername(e)
1686
class TreeConfig(IniBasedConfig):
1687
"""Branch configuration data associated with its contents, not location"""
1689
# XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
1691
def __init__(self, branch):
1692
self._config = branch._get_config()
1693
self.branch = branch
1695
def _get_parser(self, file=None):
1696
if file is not None:
1697
return IniBasedConfig._get_parser(file)
1698
return self._config._get_configobj()
1700
def get_option(self, name, section=None, default=None):
1701
self.branch.lock_read()
1703
return self._config.get_option(name, section, default)
1705
self.branch.unlock()
1707
def set_option(self, value, name, section=None):
1708
"""Set a per-branch configuration option"""
1709
# FIXME: We shouldn't need to lock explicitly here but rather rely on
1710
# higher levels providing the right lock -- vila 20101004
1711
self.branch.lock_write()
1713
self._config.set_option(value, name, section)
1715
self.branch.unlock()
1717
def remove_option(self, option_name, section_name=None):
1718
# FIXME: We shouldn't need to lock explicitly here but rather rely on
1719
# higher levels providing the right lock -- vila 20101004
1720
self.branch.lock_write()
1722
self._config.remove_option(option_name, section_name)
1724
self.branch.unlock()
1727
class AuthenticationConfig(object):
1728
"""The authentication configuration file based on a ini file.
1730
Implements the authentication.conf file described in
1731
doc/developers/authentication-ring.txt.
1734
def __init__(self, _file=None):
1735
self._config = None # The ConfigObj
1737
self._filename = authentication_config_filename()
1738
self._input = self._filename = authentication_config_filename()
1740
# Tests can provide a string as _file
1741
self._filename = None
1744
def _get_config(self):
1745
if self._config is not None:
1748
# FIXME: Should we validate something here ? Includes: empty
1749
# sections are useless, at least one of
1750
# user/password/password_encoding should be defined, etc.
1752
# Note: the encoding below declares that the file itself is utf-8
1753
# encoded, but the values in the ConfigObj are always Unicode.
1754
self._config = ConfigObj(self._input, encoding='utf-8')
1755
except configobj.ConfigObjError, e:
1756
raise errors.ParseConfigError(e.errors, e.config.filename)
1757
except UnicodeError:
1758
raise errors.ConfigContentError(self._filename)
1762
"""Save the config file, only tests should use it for now."""
1763
conf_dir = os.path.dirname(self._filename)
1764
ensure_config_dir_exists(conf_dir)
1765
f = file(self._filename, 'wb')
1767
self._get_config().write(f)
1771
def _set_option(self, section_name, option_name, value):
1772
"""Set an authentication configuration option"""
1773
conf = self._get_config()
1774
section = conf.get(section_name)
1777
section = conf[section]
1778
section[option_name] = value
1781
def get_credentials(self, scheme, host, port=None, user=None, path=None,
1783
"""Returns the matching credentials from authentication.conf file.
1785
:param scheme: protocol
1787
:param host: the server address
1789
:param port: the associated port (optional)
1791
:param user: login (optional)
1793
:param path: the absolute path on the server (optional)
1795
:param realm: the http authentication realm (optional)
1797
:return: A dict containing the matching credentials or None.
1799
- name: the section name of the credentials in the
1800
authentication.conf file,
1801
- user: can't be different from the provided user if any,
1802
- scheme: the server protocol,
1803
- host: the server address,
1804
- port: the server port (can be None),
1805
- path: the absolute server path (can be None),
1806
- realm: the http specific authentication realm (can be None),
1807
- password: the decoded password, could be None if the credential
1808
defines only the user
1809
- verify_certificates: https specific, True if the server
1810
certificate should be verified, False otherwise.
1813
for auth_def_name, auth_def in self._get_config().items():
1814
if type(auth_def) is not configobj.Section:
1815
raise ValueError("%s defined outside a section" % auth_def_name)
1817
a_scheme, a_host, a_user, a_path = map(
1818
auth_def.get, ['scheme', 'host', 'user', 'path'])
1821
a_port = auth_def.as_int('port')
1825
raise ValueError("'port' not numeric in %s" % auth_def_name)
1827
a_verify_certificates = auth_def.as_bool('verify_certificates')
1829
a_verify_certificates = True
1832
"'verify_certificates' not boolean in %s" % auth_def_name)
1835
if a_scheme is not None and scheme != a_scheme:
1837
if a_host is not None:
1838
if not (host == a_host
1839
or (a_host.startswith('.') and host.endswith(a_host))):
1841
if a_port is not None and port != a_port:
1843
if (a_path is not None and path is not None
1844
and not path.startswith(a_path)):
1846
if (a_user is not None and user is not None
1847
and a_user != user):
1848
# Never contradict the caller about the user to be used
1853
# Prepare a credentials dictionary with additional keys
1854
# for the credential providers
1855
credentials = dict(name=auth_def_name,
1862
password=auth_def.get('password', None),
1863
verify_certificates=a_verify_certificates)
1864
# Decode the password in the credentials (or get one)
1865
self.decode_password(credentials,
1866
auth_def.get('password_encoding', None))
1867
if 'auth' in debug.debug_flags:
1868
trace.mutter("Using authentication section: %r", auth_def_name)
1871
if credentials is None:
1872
# No credentials were found in authentication.conf, try the fallback
1873
# credentials stores.
1874
credentials = credential_store_registry.get_fallback_credentials(
1875
scheme, host, port, user, path, realm)
1879
def set_credentials(self, name, host, user, scheme=None, password=None,
1880
port=None, path=None, verify_certificates=None,
1882
"""Set authentication credentials for a host.
1884
Any existing credentials with matching scheme, host, port and path
1885
will be deleted, regardless of name.
1887
:param name: An arbitrary name to describe this set of credentials.
1888
:param host: Name of the host that accepts these credentials.
1889
:param user: The username portion of these credentials.
1890
:param scheme: The URL scheme (e.g. ssh, http) the credentials apply
1892
:param password: Password portion of these credentials.
1893
:param port: The IP port on the host that these credentials apply to.
1894
:param path: A filesystem path on the host that these credentials
1896
:param verify_certificates: On https, verify server certificates if
1898
:param realm: The http authentication realm (optional).
1900
values = {'host': host, 'user': user}
1901
if password is not None:
1902
values['password'] = password
1903
if scheme is not None:
1904
values['scheme'] = scheme
1905
if port is not None:
1906
values['port'] = '%d' % port
1907
if path is not None:
1908
values['path'] = path
1909
if verify_certificates is not None:
1910
values['verify_certificates'] = str(verify_certificates)
1911
if realm is not None:
1912
values['realm'] = realm
1913
config = self._get_config()
1915
for section, existing_values in config.items():
1916
for key in ('scheme', 'host', 'port', 'path', 'realm'):
1917
if existing_values.get(key) != values.get(key):
1921
config.update({name: values})
1924
def get_user(self, scheme, host, port=None, realm=None, path=None,
1925
prompt=None, ask=False, default=None):
1926
"""Get a user from authentication file.
1928
:param scheme: protocol
1930
:param host: the server address
1932
:param port: the associated port (optional)
1934
:param realm: the realm sent by the server (optional)
1936
:param path: the absolute path on the server (optional)
1938
:param ask: Ask the user if there is no explicitly configured username
1941
:param default: The username returned if none is defined (optional).
1943
:return: The found user.
1945
credentials = self.get_credentials(scheme, host, port, user=None,
1946
path=path, realm=realm)
1947
if credentials is not None:
1948
user = credentials['user']
1954
# Create a default prompt suitable for most cases
1955
prompt = u'%s' % (scheme.upper(),) + u' %(host)s username'
1956
# Special handling for optional fields in the prompt
1957
if port is not None:
1958
prompt_host = '%s:%d' % (host, port)
1961
user = ui.ui_factory.get_username(prompt, host=prompt_host)
1966
def get_password(self, scheme, host, user, port=None,
1967
realm=None, path=None, prompt=None):
1968
"""Get a password from authentication file or prompt the user for one.
1970
:param scheme: protocol
1972
:param host: the server address
1974
:param port: the associated port (optional)
1978
:param realm: the realm sent by the server (optional)
1980
:param path: the absolute path on the server (optional)
1982
:return: The found password or the one entered by the user.
1984
credentials = self.get_credentials(scheme, host, port, user, path,
1986
if credentials is not None:
1987
password = credentials['password']
1988
if password is not None and scheme is 'ssh':
1989
trace.warning('password ignored in section [%s],'
1990
' use an ssh agent instead'
1991
% credentials['name'])
1995
# Prompt user only if we could't find a password
1996
if password is None:
1998
# Create a default prompt suitable for most cases
1999
prompt = u'%s' % scheme.upper() + u' %(user)s@%(host)s password'
2000
# Special handling for optional fields in the prompt
2001
if port is not None:
2002
prompt_host = '%s:%d' % (host, port)
2005
password = ui.ui_factory.get_password(prompt,
2006
host=prompt_host, user=user)
2009
def decode_password(self, credentials, encoding):
2011
cs = credential_store_registry.get_credential_store(encoding)
2013
raise ValueError('%r is not a known password_encoding' % encoding)
2014
credentials['password'] = cs.decode_password(credentials)
2018
class CredentialStoreRegistry(registry.Registry):
2019
"""A class that registers credential stores.
2021
A credential store provides access to credentials via the password_encoding
2022
field in authentication.conf sections.
2024
Except for stores provided by bzr itself, most stores are expected to be
2025
provided by plugins that will therefore use
2026
register_lazy(password_encoding, module_name, member_name, help=help,
2027
fallback=fallback) to install themselves.
2029
A fallback credential store is one that is queried if no credentials can be
2030
found via authentication.conf.
2033
def get_credential_store(self, encoding=None):
2034
cs = self.get(encoding)
2039
def is_fallback(self, name):
2040
"""Check if the named credentials store should be used as fallback."""
2041
return self.get_info(name)
2043
def get_fallback_credentials(self, scheme, host, port=None, user=None,
2044
path=None, realm=None):
2045
"""Request credentials from all fallback credentials stores.
2047
The first credentials store that can provide credentials wins.
2050
for name in self.keys():
2051
if not self.is_fallback(name):
2053
cs = self.get_credential_store(name)
2054
credentials = cs.get_credentials(scheme, host, port, user,
2056
if credentials is not None:
2057
# We found some credentials
2061
def register(self, key, obj, help=None, override_existing=False,
2063
"""Register a new object to a name.
2065
:param key: This is the key to use to request the object later.
2066
:param obj: The object to register.
2067
:param help: Help text for this entry. This may be a string or
2068
a callable. If it is a callable, it should take two
2069
parameters (registry, key): this registry and the key that
2070
the help was registered under.
2071
:param override_existing: Raise KeyErorr if False and something has
2072
already been registered for that key. If True, ignore if there
2073
is an existing key (always register the new value).
2074
:param fallback: Whether this credential store should be
2077
return super(CredentialStoreRegistry,
2078
self).register(key, obj, help, info=fallback,
2079
override_existing=override_existing)
2081
def register_lazy(self, key, module_name, member_name,
2082
help=None, override_existing=False,
2084
"""Register a new credential store to be loaded on request.
2086
:param module_name: The python path to the module. Such as 'os.path'.
2087
:param member_name: The member of the module to return. If empty or
2088
None, get() will return the module itself.
2089
:param help: Help text for this entry. This may be a string or
2091
:param override_existing: If True, replace the existing object
2092
with the new one. If False, if there is already something
2093
registered with the same key, raise a KeyError
2094
:param fallback: Whether this credential store should be
2097
return super(CredentialStoreRegistry, self).register_lazy(
2098
key, module_name, member_name, help,
2099
info=fallback, override_existing=override_existing)
2102
credential_store_registry = CredentialStoreRegistry()
2105
class CredentialStore(object):
2106
"""An abstract class to implement storage for credentials"""
2108
def decode_password(self, credentials):
2109
"""Returns a clear text password for the provided credentials."""
2110
raise NotImplementedError(self.decode_password)
2112
def get_credentials(self, scheme, host, port=None, user=None, path=None,
2114
"""Return the matching credentials from this credential store.
2116
This method is only called on fallback credential stores.
2118
raise NotImplementedError(self.get_credentials)
2122
class PlainTextCredentialStore(CredentialStore):
2123
__doc__ = """Plain text credential store for the authentication.conf file"""
2125
def decode_password(self, credentials):
2126
"""See CredentialStore.decode_password."""
2127
return credentials['password']
2130
credential_store_registry.register('plain', PlainTextCredentialStore,
2131
help=PlainTextCredentialStore.__doc__)
2132
credential_store_registry.default_key = 'plain'
2135
class Base64CredentialStore(CredentialStore):
2136
__doc__ = """Base64 credential store for the authentication.conf file"""
2138
def decode_password(self, credentials):
2139
"""See CredentialStore.decode_password."""
2140
# GZ 2012-07-28: Will raise binascii.Error if password is not base64,
2141
# should probably propogate as something more useful.
2142
return base64.decodestring(credentials['password'])
2144
credential_store_registry.register('base64', Base64CredentialStore,
2145
help=Base64CredentialStore.__doc__)
2148
class BzrDirConfig(object):
2150
def __init__(self, bzrdir):
2151
self._bzrdir = bzrdir
2152
self._config = bzrdir._get_config()
2154
def set_default_stack_on(self, value):
2155
"""Set the default stacking location.
2157
It may be set to a location, or None.
2159
This policy affects all branches contained by this control dir, except
2160
for those under repositories.
2162
if self._config is None:
2163
raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
2165
self._config.set_option('', 'default_stack_on')
2167
self._config.set_option(value, 'default_stack_on')
2169
def get_default_stack_on(self):
2170
"""Return the default stacking location.
2172
This will either be a location, or None.
2174
This policy affects all branches contained by this control dir, except
2175
for those under repositories.
2177
if self._config is None:
2179
value = self._config.get_option('default_stack_on')
2185
class TransportConfig(object):
2186
"""A Config that reads/writes a config file on a Transport.
2188
It is a low-level object that considers config data to be name/value pairs
2189
that may be associated with a section. Assigning meaning to these values
2190
is done at higher levels like TreeConfig.
2193
def __init__(self, transport, filename):
2194
self._transport = transport
2195
self._filename = filename
2197
def get_option(self, name, section=None, default=None):
2198
"""Return the value associated with a named option.
2200
:param name: The name of the value
2201
:param section: The section the option is in (if any)
2202
:param default: The value to return if the value is not set
2203
:return: The value or default value
2205
configobj = self._get_configobj()
2207
section_obj = configobj
2210
section_obj = configobj[section]
2213
value = section_obj.get(name, default)
2214
for hook in OldConfigHooks['get']:
2215
hook(self, name, value)
2218
def set_option(self, value, name, section=None):
2219
"""Set the value associated with a named option.
2221
:param value: The value to set
2222
:param name: The name of the value to set
2223
:param section: The section the option is in (if any)
2225
configobj = self._get_configobj()
2227
configobj[name] = value
2229
configobj.setdefault(section, {})[name] = value
2230
for hook in OldConfigHooks['set']:
2231
hook(self, name, value)
2232
self._set_configobj(configobj)
2234
def remove_option(self, option_name, section_name=None):
2235
configobj = self._get_configobj()
2236
if section_name is None:
2237
del configobj[option_name]
2239
del configobj[section_name][option_name]
2240
for hook in OldConfigHooks['remove']:
2241
hook(self, option_name)
2242
self._set_configobj(configobj)
2244
def _get_config_file(self):
2246
f = StringIO(self._transport.get_bytes(self._filename))
2247
for hook in OldConfigHooks['load']:
2250
except errors.NoSuchFile:
2252
except errors.PermissionDenied, e:
2253
trace.warning("Permission denied while trying to open "
2254
"configuration file %s.", urlutils.unescape_for_display(
2255
urlutils.join(self._transport.base, self._filename), "utf-8"))
2258
def _external_url(self):
2259
return urlutils.join(self._transport.external_url(), self._filename)
2261
def _get_configobj(self):
2262
f = self._get_config_file()
2265
conf = ConfigObj(f, encoding='utf-8')
2266
except configobj.ConfigObjError, e:
2267
raise errors.ParseConfigError(e.errors, self._external_url())
2268
except UnicodeDecodeError:
2269
raise errors.ConfigContentError(self._external_url())
2274
def _set_configobj(self, configobj):
2275
out_file = StringIO()
2276
configobj.write(out_file)
2278
self._transport.put_file(self._filename, out_file)
2279
for hook in OldConfigHooks['save']:
2283
class Option(object):
2284
"""An option definition.
2286
The option *values* are stored in config files and found in sections.
2288
Here we define various properties about the option itself, its default
2289
value, how to convert it from stores, what to do when invalid values are
2290
encoutered, in which config files it can be stored.
2293
def __init__(self, name, override_from_env=None,
2294
default=None, default_from_env=None,
2295
help=None, from_unicode=None, invalid=None, unquote=True):
2296
"""Build an option definition.
2298
:param name: the name used to refer to the option.
2300
:param override_from_env: A list of environment variables which can
2301
provide override any configuration setting.
2303
:param default: the default value to use when none exist in the config
2304
stores. This is either a string that ``from_unicode`` will convert
2305
into the proper type, a callable returning a unicode string so that
2306
``from_unicode`` can be used on the return value, or a python
2307
object that can be stringified (so only the empty list is supported
2310
:param default_from_env: A list of environment variables which can
2311
provide a default value. 'default' will be used only if none of the
2312
variables specified here are set in the environment.
2314
:param help: a doc string to explain the option to the user.
2316
:param from_unicode: a callable to convert the unicode string
2317
representing the option value in a store. This is not called for
2320
:param invalid: the action to be taken when an invalid value is
2321
encountered in a store. This is called only when from_unicode is
2322
invoked to convert a string and returns None or raise ValueError or
2323
TypeError. Accepted values are: None (ignore invalid values),
2324
'warning' (emit a warning), 'error' (emit an error message and
2327
:param unquote: should the unicode value be unquoted before conversion.
2328
This should be used only when the store providing the values cannot
2329
safely unquote them (see http://pad.lv/906897). It is provided so
2330
daughter classes can handle the quoting themselves.
2332
if override_from_env is None:
2333
override_from_env = []
2334
if default_from_env is None:
2335
default_from_env = []
2337
self.override_from_env = override_from_env
2338
# Convert the default value to a unicode string so all values are
2339
# strings internally before conversion (via from_unicode) is attempted.
2342
elif isinstance(default, list):
2343
# Only the empty list is supported
2345
raise AssertionError(
2346
'Only empty lists are supported as default values')
2348
elif isinstance(default, (str, unicode, bool, int, float)):
2349
# Rely on python to convert strings, booleans and integers
2350
self.default = u'%s' % (default,)
2351
elif callable(default):
2352
self.default = default
2354
# other python objects are not expected
2355
raise AssertionError('%r is not supported as a default value'
2357
self.default_from_env = default_from_env
2359
self.from_unicode = from_unicode
2360
self.unquote = unquote
2361
if invalid and invalid not in ('warning', 'error'):
2362
raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2363
self.invalid = invalid
2369
def convert_from_unicode(self, store, unicode_value):
2370
if self.unquote and store is not None and unicode_value is not None:
2371
unicode_value = store.unquote(unicode_value)
2372
if self.from_unicode is None or unicode_value is None:
2373
# Don't convert or nothing to convert
2374
return unicode_value
2376
converted = self.from_unicode(unicode_value)
2377
except (ValueError, TypeError):
2378
# Invalid values are ignored
2380
if converted is None and self.invalid is not None:
2381
# The conversion failed
2382
if self.invalid == 'warning':
2383
trace.warning('Value "%s" is not valid for "%s"',
2384
unicode_value, self.name)
2385
elif self.invalid == 'error':
2386
raise errors.ConfigOptionValueError(self.name, unicode_value)
2389
def get_override(self):
2391
for var in self.override_from_env:
2393
# If the env variable is defined, its value takes precedence
2394
value = os.environ[var].decode(osutils.get_user_encoding())
2400
def get_default(self):
2402
for var in self.default_from_env:
2404
# If the env variable is defined, its value is the default one
2405
value = os.environ[var].decode(osutils.get_user_encoding())
2410
# Otherwise, fallback to the value defined at registration
2411
if callable(self.default):
2412
value = self.default()
2413
if not isinstance(value, unicode):
2414
raise AssertionError(
2415
"Callable default value for '%s' should be unicode"
2418
value = self.default
2421
def get_help_topic(self):
2424
def get_help_text(self, additional_see_also=None, plain=True):
2426
from bzrlib import help_topics
2427
result += help_topics._format_see_also(additional_see_also)
2429
result = help_topics.help_as_plain_text(result)
2433
# Predefined converters to get proper values from store
2435
def bool_from_store(unicode_str):
2436
return ui.bool_from_string(unicode_str)
2439
def int_from_store(unicode_str):
2440
return int(unicode_str)
2443
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2445
def int_SI_from_store(unicode_str):
2446
"""Convert a human readable size in SI units, e.g 10MB into an integer.
2448
Accepted suffixes are K,M,G. It is case-insensitive and may be followed
2449
by a trailing b (i.e. Kb, MB). This is intended to be practical and not
2452
:return Integer, expanded to its base-10 value if a proper SI unit is
2453
found, None otherwise.
2455
regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
2456
p = re.compile(regexp, re.IGNORECASE)
2457
m = p.match(unicode_str)
2460
val, _, unit = m.groups()
2464
coeff = _unit_suffixes[unit.upper()]
2466
raise ValueError(gettext('{0} is not an SI unit.').format(unit))
2471
def float_from_store(unicode_str):
2472
return float(unicode_str)
2475
# Use a an empty dict to initialize an empty configobj avoiding all
2476
# parsing and encoding checks
2477
_list_converter_config = configobj.ConfigObj(
2478
{}, encoding='utf-8', list_values=True, interpolation=False)
2481
class ListOption(Option):
2483
def __init__(self, name, default=None, default_from_env=None,
2484
help=None, invalid=None):
2485
"""A list Option definition.
2487
This overrides the base class so the conversion from a unicode string
2488
can take quoting into account.
2490
super(ListOption, self).__init__(
2491
name, default=default, default_from_env=default_from_env,
2492
from_unicode=self.from_unicode, help=help,
2493
invalid=invalid, unquote=False)
2495
def from_unicode(self, unicode_str):
2496
if not isinstance(unicode_str, basestring):
2498
# Now inject our string directly as unicode. All callers got their
2499
# value from configobj, so values that need to be quoted are already
2501
_list_converter_config.reset()
2502
_list_converter_config._parse([u"list=%s" % (unicode_str,)])
2503
maybe_list = _list_converter_config['list']
2504
if isinstance(maybe_list, basestring):
2506
# A single value, most probably the user forgot (or didn't care
2507
# to add) the final ','
2510
# The empty string, convert to empty list
2513
# We rely on ConfigObj providing us with a list already
2518
class RegistryOption(Option):
2519
"""Option for a choice from a registry."""
2521
def __init__(self, name, registry, default_from_env=None,
2522
help=None, invalid=None):
2523
"""A registry based Option definition.
2525
This overrides the base class so the conversion from a unicode string
2526
can take quoting into account.
2528
super(RegistryOption, self).__init__(
2529
name, default=lambda: unicode(registry.default_key),
2530
default_from_env=default_from_env,
2531
from_unicode=self.from_unicode, help=help,
2532
invalid=invalid, unquote=False)
2533
self.registry = registry
2535
def from_unicode(self, unicode_str):
2536
if not isinstance(unicode_str, basestring):
2539
return self.registry.get(unicode_str)
2542
"Invalid value %s for %s."
2543
"See help for a list of possible values." % (unicode_str,
2548
ret = [self._help, "\n\nThe following values are supported:\n"]
2549
for key in self.registry.keys():
2550
ret.append(" %s - %s\n" % (key, self.registry.get_help(key)))
2554
class OptionRegistry(registry.Registry):
2555
"""Register config options by their name.
2557
This overrides ``registry.Registry`` to simplify registration by acquiring
2558
some information from the option object itself.
2561
def register(self, option):
2562
"""Register a new option to its name.
2564
:param option: The option to register. Its name is used as the key.
2566
super(OptionRegistry, self).register(option.name, option,
2569
def register_lazy(self, key, module_name, member_name):
2570
"""Register a new option to be loaded on request.
2572
:param key: the key to request the option later. Since the registration
2573
is lazy, it should be provided and match the option name.
2575
:param module_name: the python path to the module. Such as 'os.path'.
2577
:param member_name: the member of the module to return. If empty or
2578
None, get() will return the module itself.
2580
super(OptionRegistry, self).register_lazy(key,
2581
module_name, member_name)
2583
def get_help(self, key=None):
2584
"""Get the help text associated with the given key"""
2585
option = self.get(key)
2586
the_help = option.help
2587
if callable(the_help):
2588
return the_help(self, key)
2592
option_registry = OptionRegistry()
2595
# Registered options in lexicographical order
2597
option_registry.register(
2598
Option('append_revisions_only',
2599
default=None, from_unicode=bool_from_store, invalid='warning',
2601
Whether to only append revisions to the mainline.
2603
If this is set to true, then it is not possible to change the
2604
existing mainline of the branch.
2606
option_registry.register(
2607
ListOption('acceptable_keys',
2610
List of GPG key patterns which are acceptable for verification.
2612
option_registry.register(
2613
Option('add.maximum_file_size',
2614
default=u'20MB', from_unicode=int_SI_from_store,
2616
Size above which files should be added manually.
2618
Files below this size are added automatically when using ``bzr add`` without
2621
A negative value means disable the size check.
2623
option_registry.register(
2625
default=None, from_unicode=bool_from_store,
2627
Is the branch bound to ``bound_location``.
2629
If set to "True", the branch should act as a checkout, and push each commit to
2630
the bound_location. This option is normally set by ``bind``/``unbind``.
2632
See also: bound_location.
2634
option_registry.register(
2635
Option('bound_location',
2638
The location that commits should go to when acting as a checkout.
2640
This option is normally set by ``bind``.
2644
option_registry.register(
2645
Option('branch.fetch_tags', default=False, from_unicode=bool_from_store,
2647
Whether revisions associated with tags should be fetched.
2649
option_registry.register_lazy(
2650
'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
2651
option_registry.register(
2652
Option('bzr.workingtree.worth_saving_limit', default=10,
2653
from_unicode=int_from_store, invalid='warning',
2655
How many changes before saving the dirstate.
2657
-1 means that we will never rewrite the dirstate file for only
2658
stat-cache changes. Regardless of this setting, we will always rewrite
2659
the dirstate file if a file is added/removed/renamed/etc. This flag only
2660
affects the behavior of updating the dirstate file after we notice that
2661
a file has been touched.
2663
option_registry.register(
2664
Option('bugtracker', default=None,
2666
Default bug tracker to use.
2668
This bug tracker will be used for example when marking bugs
2669
as fixed using ``bzr commit --fixes``, if no explicit
2670
bug tracker was specified.
2672
option_registry.register(
2673
Option('check_signatures', default=CHECK_IF_POSSIBLE,
2674
from_unicode=signature_policy_from_unicode,
2676
GPG checking policy.
2678
Possible values: require, ignore, check-available (default)
2680
this option will control whether bzr will require good gpg
2681
signatures, ignore them, or check them if they are
2684
option_registry.register(
2685
Option('child_submit_format',
2686
help='''The preferred format of submissions to this branch.'''))
2687
option_registry.register(
2688
Option('child_submit_to',
2689
help='''Where submissions to this branch are mailed to.'''))
2690
option_registry.register(
2691
Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2692
from_unicode=signing_policy_from_unicode,
2696
Possible values: always, never, when-required (default)
2698
This option controls whether bzr will always create
2699
gpg signatures or not on commits.
2701
option_registry.register(
2702
Option('dirstate.fdatasync', default=True,
2703
from_unicode=bool_from_store,
2705
Flush dirstate changes onto physical disk?
2707
If true (default), working tree metadata changes are flushed through the
2708
OS buffers to physical disk. This is somewhat slower, but means data
2709
should not be lost if the machine crashes. See also repository.fdatasync.
2711
option_registry.register(
2712
ListOption('debug_flags', default=[],
2713
help='Debug flags to activate.'))
2714
option_registry.register(
2715
Option('default_format', default='2a',
2716
help='Format used when creating branches.'))
2717
option_registry.register(
2718
Option('dpush_strict', default=None,
2719
from_unicode=bool_from_store,
2721
The default value for ``dpush --strict``.
2723
If present, defines the ``--strict`` option default value for checking
2724
uncommitted changes before pushing into a different VCS without any
2725
custom bzr metadata.
2727
option_registry.register(
2729
help='The command called to launch an editor to enter a message.'))
2730
option_registry.register(
2731
Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2732
help='The users identity'))
2733
option_registry.register(
2734
Option('gpg_signing_command',
2737
Program to use use for creating signatures.
2739
This should support at least the -u and --clearsign options.
2741
option_registry.register(
2742
Option('gpg_signing_key',
2745
GPG key to use for signing.
2747
This defaults to the first key associated with the users email.
2749
option_registry.register(
2750
Option('ignore_missing_extensions', default=False,
2751
from_unicode=bool_from_store,
2753
Control the missing extensions warning display.
2755
The warning will not be emitted if set to True.
2757
option_registry.register(
2759
help='Language to translate messages into.'))
2760
option_registry.register(
2761
Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2763
Steal locks that appears to be dead.
2765
If set to True, bzr will check if a lock is supposed to be held by an
2766
active process from the same user on the same machine. If the user and
2767
machine match, but no process with the given PID is active, then bzr
2768
will automatically break the stale lock, and create a new lock for
2770
Otherwise, bzr will prompt as normal to break the lock.
2772
option_registry.register(
2773
Option('log_format', default='long',
2775
Log format to use when displaying revisions.
2777
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2778
may be provided by plugins.
2780
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
2782
option_registry.register(
2783
Option('output_encoding',
2784
help= 'Unicode encoding for output'
2785
' (terminal encoding if not specified).'))
2786
option_registry.register(
2787
Option('parent_location',
2790
The location of the default branch for pull or merge.
2792
This option is normally set when creating a branch, the first ``pull`` or by
2793
``pull --remember``.
2795
option_registry.register(
2796
Option('post_commit', default=None,
2798
Post commit functions.
2800
An ordered list of python functions to call, separated by spaces.
2802
Each function takes branch, rev_id as parameters.
2804
option_registry.register(
2805
Option('public_branch',
2808
A publically-accessible version of this branch.
2810
This implies that the branch setting this option is not publically-accessible.
2811
Used and set by ``bzr send``.
2813
option_registry.register(
2814
Option('push_location',
2817
The location of the default branch for push.
2819
This option is normally set by the first ``push`` or ``push --remember``.
2821
option_registry.register(
2822
Option('push_strict', default=None,
2823
from_unicode=bool_from_store,
2825
The default value for ``push --strict``.
2827
If present, defines the ``--strict`` option default value for checking
2828
uncommitted changes before sending a merge directive.
2830
option_registry.register(
2831
Option('repository.fdatasync', default=True,
2832
from_unicode=bool_from_store,
2834
Flush repository changes onto physical disk?
2836
If true (default), repository changes are flushed through the OS buffers
2837
to physical disk. This is somewhat slower, but means data should not be
2838
lost if the machine crashes. See also dirstate.fdatasync.
2840
option_registry.register_lazy('smtp_server',
2841
'bzrlib.smtp_connection', 'smtp_server')
2842
option_registry.register_lazy('smtp_password',
2843
'bzrlib.smtp_connection', 'smtp_password')
2844
option_registry.register_lazy('smtp_username',
2845
'bzrlib.smtp_connection', 'smtp_username')
2846
option_registry.register(
2847
Option('selftest.timeout',
2849
from_unicode=int_from_store,
2850
help='Abort selftest if one test takes longer than this many seconds',
2853
option_registry.register(
2854
Option('send_strict', default=None,
2855
from_unicode=bool_from_store,
2857
The default value for ``send --strict``.
2859
If present, defines the ``--strict`` option default value for checking
2860
uncommitted changes before sending a bundle.
2863
option_registry.register(
2864
Option('serve.client_timeout',
2865
default=300.0, from_unicode=float_from_store,
2866
help="If we wait for a new request from a client for more than"
2867
" X seconds, consider the client idle, and hangup."))
2868
option_registry.register(
2869
Option('stacked_on_location',
2871
help="""The location where this branch is stacked on."""))
2872
option_registry.register(
2873
Option('submit_branch',
2876
The branch you intend to submit your current work to.
2878
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2879
by the ``submit:`` revision spec.
2881
option_registry.register(
2883
help='''Where submissions from this branch are mailed to.'''))
2884
option_registry.register(
2885
ListOption('suppress_warnings',
2887
help="List of warning classes to suppress."))
2888
option_registry.register(
2889
Option('validate_signatures_in_log', default=False,
2890
from_unicode=bool_from_store, invalid='warning',
2891
help='''Whether to validate signatures in bzr log.'''))
2892
option_registry.register_lazy('ssl.ca_certs',
2893
'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2895
option_registry.register_lazy('ssl.cert_reqs',
2896
'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2899
class Section(object):
2900
"""A section defines a dict of option name => value.
2902
This is merely a read-only dict which can add some knowledge about the
2903
options. It is *not* a python dict object though and doesn't try to mimic
2907
def __init__(self, section_id, options):
2908
self.id = section_id
2909
# We re-use the dict-like object received
2910
self.options = options
2912
def get(self, name, default=None, expand=True):
2913
return self.options.get(name, default)
2915
def iter_option_names(self):
2916
for k in self.options.iterkeys():
2920
# Mostly for debugging use
2921
return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2924
_NewlyCreatedOption = object()
2925
"""Was the option created during the MutableSection lifetime"""
2926
_DeletedOption = object()
2927
"""Was the option deleted during the MutableSection lifetime"""
2930
class MutableSection(Section):
2931
"""A section allowing changes and keeping track of the original values."""
2933
def __init__(self, section_id, options):
2934
super(MutableSection, self).__init__(section_id, options)
2935
self.reset_changes()
2937
def set(self, name, value):
2938
if name not in self.options:
2939
# This is a new option
2940
self.orig[name] = _NewlyCreatedOption
2941
elif name not in self.orig:
2942
self.orig[name] = self.get(name, None)
2943
self.options[name] = value
2945
def remove(self, name):
2946
if name not in self.orig:
2947
self.orig[name] = self.get(name, None)
2948
del self.options[name]
2950
def reset_changes(self):
2953
def apply_changes(self, dirty, store):
2954
"""Apply option value changes.
2956
``self`` has been reloaded from the persistent storage. ``dirty``
2957
contains the changes made since the previous loading.
2959
:param dirty: the mutable section containing the changes.
2961
:param store: the store containing the section
2963
for k, expected in dirty.orig.iteritems():
2964
actual = dirty.get(k, _DeletedOption)
2965
reloaded = self.get(k, _NewlyCreatedOption)
2966
if actual is _DeletedOption:
2967
if k in self.options:
2971
# Report concurrent updates in an ad-hoc way. This should only
2972
# occurs when different processes try to update the same option
2973
# which is not supported (as in: the config framework is not meant
2974
# to be used as a sharing mechanism).
2975
if expected != reloaded:
2976
if actual is _DeletedOption:
2977
actual = '<DELETED>'
2978
if reloaded is _NewlyCreatedOption:
2979
reloaded = '<CREATED>'
2980
if expected is _NewlyCreatedOption:
2981
expected = '<CREATED>'
2982
# Someone changed the value since we get it from the persistent
2984
trace.warning(gettext(
2985
"Option {0} in section {1} of {2} was changed"
2986
" from {3} to {4}. The {5} value will be saved.".format(
2987
k, self.id, store.external_url(), expected,
2989
# No need to keep track of these changes
2990
self.reset_changes()
2993
class Store(object):
2994
"""Abstract interface to persistent storage for configuration options."""
2996
readonly_section_class = Section
2997
mutable_section_class = MutableSection
3000
# Which sections need to be saved (by section id). We use a dict here
3001
# so the dirty sections can be shared by multiple callers.
3002
self.dirty_sections = {}
3004
def is_loaded(self):
3005
"""Returns True if the Store has been loaded.
3007
This is used to implement lazy loading and ensure the persistent
3008
storage is queried only when needed.
3010
raise NotImplementedError(self.is_loaded)
3013
"""Loads the Store from persistent storage."""
3014
raise NotImplementedError(self.load)
3016
def _load_from_string(self, bytes):
3017
"""Create a store from a string in configobj syntax.
3019
:param bytes: A string representing the file content.
3021
raise NotImplementedError(self._load_from_string)
3024
"""Unloads the Store.
3026
This should make is_loaded() return False. This is used when the caller
3027
knows that the persistent storage has changed or may have change since
3030
raise NotImplementedError(self.unload)
3032
def quote(self, value):
3033
"""Quote a configuration option value for storing purposes.
3035
This allows Stacks to present values as they will be stored.
3039
def unquote(self, value):
3040
"""Unquote a configuration option value into unicode.
3042
The received value is quoted as stored.
3047
"""Saves the Store to persistent storage."""
3048
raise NotImplementedError(self.save)
3050
def _need_saving(self):
3051
for s in self.dirty_sections.values():
3053
# At least one dirty section contains a modification
3057
def apply_changes(self, dirty_sections):
3058
"""Apply changes from dirty sections while checking for coherency.
3060
The Store content is discarded and reloaded from persistent storage to
3061
acquire up-to-date values.
3063
Dirty sections are MutableSection which kept track of the value they
3064
are expected to update.
3066
# We need an up-to-date version from the persistent storage, unload the
3067
# store. The reload will occur when needed (triggered by the first
3068
# get_mutable_section() call below.
3070
# Apply the changes from the preserved dirty sections
3071
for section_id, dirty in dirty_sections.iteritems():
3072
clean = self.get_mutable_section(section_id)
3073
clean.apply_changes(dirty, self)
3074
# Everything is clean now
3075
self.dirty_sections = {}
3077
def save_changes(self):
3078
"""Saves the Store to persistent storage if changes occurred.
3080
Apply the changes recorded in the mutable sections to a store content
3081
refreshed from persistent storage.
3083
raise NotImplementedError(self.save_changes)
3085
def external_url(self):
3086
raise NotImplementedError(self.external_url)
3088
def get_sections(self):
3089
"""Returns an ordered iterable of existing sections.
3091
:returns: An iterable of (store, section).
3093
raise NotImplementedError(self.get_sections)
3095
def get_mutable_section(self, section_id=None):
3096
"""Returns the specified mutable section.
3098
:param section_id: The section identifier
3100
raise NotImplementedError(self.get_mutable_section)
3103
# Mostly for debugging use
3104
return "<config.%s(%s)>" % (self.__class__.__name__,
3105
self.external_url())
3108
class CommandLineStore(Store):
3109
"A store to carry command line overrides for the config options."""
3111
def __init__(self, opts=None):
3112
super(CommandLineStore, self).__init__()
3119
# The dict should be cleared but not replaced so it can be shared.
3120
self.options.clear()
3122
def _from_cmdline(self, overrides):
3123
# Reset before accepting new definitions
3125
for over in overrides:
3127
name, value = over.split('=', 1)
3129
raise errors.BzrCommandError(
3130
gettext("Invalid '%s', should be of the form 'name=value'")
3132
self.options[name] = value
3134
def external_url(self):
3135
# Not an url but it makes debugging easier and is never needed
3139
def get_sections(self):
3140
yield self, self.readonly_section_class(None, self.options)
3143
class IniFileStore(Store):
3144
"""A config Store using ConfigObj for storage.
3146
:ivar _config_obj: Private member to hold the ConfigObj instance used to
3147
serialize/deserialize the config file.
3151
"""A config Store using ConfigObj for storage.
3153
super(IniFileStore, self).__init__()
3154
self._config_obj = None
3156
def is_loaded(self):
3157
return self._config_obj != None
3160
self._config_obj = None
3161
self.dirty_sections = {}
3163
def _load_content(self):
3164
"""Load the config file bytes.
3166
This should be provided by subclasses
3168
:return: Byte string
3170
raise NotImplementedError(self._load_content)
3172
def _save_content(self, content):
3173
"""Save the config file bytes.
3175
This should be provided by subclasses
3177
:param content: Config file bytes to write
3179
raise NotImplementedError(self._save_content)
3182
"""Load the store from the associated file."""
3183
if self.is_loaded():
3185
content = self._load_content()
3186
self._load_from_string(content)
3187
for hook in ConfigHooks['load']:
3190
def _load_from_string(self, bytes):
3191
"""Create a config store from a string.
3193
:param bytes: A string representing the file content.
3195
if self.is_loaded():
3196
raise AssertionError('Already loaded: %r' % (self._config_obj,))
3197
co_input = StringIO(bytes)
3199
# The config files are always stored utf8-encoded
3200
self._config_obj = ConfigObj(co_input, encoding='utf-8',
3202
except configobj.ConfigObjError, e:
3203
self._config_obj = None
3204
raise errors.ParseConfigError(e.errors, self.external_url())
3205
except UnicodeDecodeError:
3206
raise errors.ConfigContentError(self.external_url())
3208
def save_changes(self):
3209
if not self.is_loaded():
3212
if not self._need_saving():
3214
# Preserve the current version
3215
dirty_sections = dict(self.dirty_sections.items())
3216
self.apply_changes(dirty_sections)
3217
# Save to the persistent storage
3221
if not self.is_loaded():
3225
self._config_obj.write(out)
3226
self._save_content(out.getvalue())
3227
for hook in ConfigHooks['save']:
3230
def get_sections(self):
3231
"""Get the configobj section in the file order.
3233
:returns: An iterable of (store, section).
3235
# We need a loaded store
3238
except (errors.NoSuchFile, errors.PermissionDenied):
3239
# If the file can't be read, there is no sections
3241
cobj = self._config_obj
3243
yield self, self.readonly_section_class(None, cobj)
3244
for section_name in cobj.sections:
3246
self.readonly_section_class(section_name,
3247
cobj[section_name]))
3249
def get_mutable_section(self, section_id=None):
3250
# We need a loaded store
3253
except errors.NoSuchFile:
3254
# The file doesn't exist, let's pretend it was empty
3255
self._load_from_string('')
3256
if section_id in self.dirty_sections:
3257
# We already created a mutable section for this id
3258
return self.dirty_sections[section_id]
3259
if section_id is None:
3260
section = self._config_obj
3262
section = self._config_obj.setdefault(section_id, {})
3263
mutable_section = self.mutable_section_class(section_id, section)
3264
# All mutable sections can become dirty
3265
self.dirty_sections[section_id] = mutable_section
3266
return mutable_section
3268
def quote(self, value):
3270
# configobj conflates automagical list values and quoting
3271
self._config_obj.list_values = True
3272
return self._config_obj._quote(value)
3274
self._config_obj.list_values = False
3276
def unquote(self, value):
3277
if value and isinstance(value, basestring):
3278
# _unquote doesn't handle None nor empty strings nor anything that
3279
# is not a string, really.
3280
value = self._config_obj._unquote(value)
3283
def external_url(self):
3284
# Since an IniFileStore can be used without a file (at least in tests),
3285
# it's better to provide something than raising a NotImplementedError.
3286
# All daughter classes are supposed to provide an implementation
3288
return 'In-Process Store, no URL'
3290
class TransportIniFileStore(IniFileStore):
3291
"""IniFileStore that loads files from a transport.
3293
:ivar transport: The transport object where the config file is located.
3295
:ivar file_name: The config file basename in the transport directory.
3298
def __init__(self, transport, file_name):
3299
"""A Store using a ini file on a Transport
3301
:param transport: The transport object where the config file is located.
3302
:param file_name: The config file basename in the transport directory.
3304
super(TransportIniFileStore, self).__init__()
3305
self.transport = transport
3306
self.file_name = file_name
3308
def _load_content(self):
3310
return self.transport.get_bytes(self.file_name)
3311
except errors.PermissionDenied:
3312
trace.warning("Permission denied while trying to load "
3313
"configuration store %s.", self.external_url())
3316
def _save_content(self, content):
3317
self.transport.put_bytes(self.file_name, content)
3319
def external_url(self):
3320
# FIXME: external_url should really accepts an optional relpath
3321
# parameter (bug #750169) :-/ -- vila 2011-04-04
3322
# The following will do in the interim but maybe we don't want to
3323
# expose a path here but rather a config ID and its associated
3324
# object </hand wawe>.
3325
return urlutils.join(self.transport.external_url(), self.file_name)
3328
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
3329
# unlockable stores for use with objects that can already ensure the locking
3330
# (think branches). If different stores (not based on ConfigObj) are created,
3331
# they may face the same issue.
3334
class LockableIniFileStore(TransportIniFileStore):
3335
"""A ConfigObjStore using locks on save to ensure store integrity."""
3337
def __init__(self, transport, file_name, lock_dir_name=None):
3338
"""A config Store using ConfigObj for storage.
3340
:param transport: The transport object where the config file is located.
3342
:param file_name: The config file basename in the transport directory.
3344
if lock_dir_name is None:
3345
lock_dir_name = 'lock'
3346
self.lock_dir_name = lock_dir_name
3347
super(LockableIniFileStore, self).__init__(transport, file_name)
3348
self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
3350
def lock_write(self, token=None):
3351
"""Takes a write lock in the directory containing the config file.
3353
If the directory doesn't exist it is created.
3355
# FIXME: This doesn't check the ownership of the created directories as
3356
# ensure_config_dir_exists does. It should if the transport is local
3357
# -- vila 2011-04-06
3358
self.transport.create_prefix()
3359
return self._lock.lock_write(token)
3364
def break_lock(self):
3365
self._lock.break_lock()
3369
# We need to be able to override the undecorated implementation
3370
self.save_without_locking()
3372
def save_without_locking(self):
3373
super(LockableIniFileStore, self).save()
3376
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
3377
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
3378
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
3380
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
3381
# functions or a registry will make it easier and clearer for tests, focusing
3382
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3383
# on a poolie's remark)
3384
class GlobalStore(LockableIniFileStore):
3386
def __init__(self, possible_transports=None):
3387
t = transport.get_transport_from_path(
3388
config_dir(), possible_transports=possible_transports)
3389
super(GlobalStore, self).__init__(t, 'bazaar.conf')
3393
class LocationStore(LockableIniFileStore):
3395
def __init__(self, possible_transports=None):
3396
t = transport.get_transport_from_path(
3397
config_dir(), possible_transports=possible_transports)
3398
super(LocationStore, self).__init__(t, 'locations.conf')
3399
self.id = 'locations'
3402
class BranchStore(TransportIniFileStore):
3404
def __init__(self, branch):
3405
super(BranchStore, self).__init__(branch.control_transport,
3407
self.branch = branch
3411
class ControlStore(LockableIniFileStore):
3413
def __init__(self, bzrdir):
3414
super(ControlStore, self).__init__(bzrdir.transport,
3416
lock_dir_name='branch_lock')
3420
class SectionMatcher(object):
3421
"""Select sections into a given Store.
3423
This is intended to be used to postpone getting an iterable of sections
3427
def __init__(self, store):
3430
def get_sections(self):
3431
# This is where we require loading the store so we can see all defined
3433
sections = self.store.get_sections()
3434
# Walk the revisions in the order provided
3435
for store, s in sections:
3439
def match(self, section):
3440
"""Does the proposed section match.
3442
:param section: A Section object.
3444
:returns: True if the section matches, False otherwise.
3446
raise NotImplementedError(self.match)
3449
class NameMatcher(SectionMatcher):
3451
def __init__(self, store, section_id):
3452
super(NameMatcher, self).__init__(store)
3453
self.section_id = section_id
3455
def match(self, section):
3456
return section.id == self.section_id
3459
class LocationSection(Section):
3461
def __init__(self, section, extra_path, branch_name=None):
3462
super(LocationSection, self).__init__(section.id, section.options)
3463
self.extra_path = extra_path
3464
if branch_name is None:
3466
self.locals = {'relpath': extra_path,
3467
'basename': urlutils.basename(extra_path),
3468
'branchname': branch_name}
3470
def get(self, name, default=None, expand=True):
3471
value = super(LocationSection, self).get(name, default)
3472
if value is not None and expand:
3473
policy_name = self.get(name + ':policy', None)
3474
policy = _policy_value.get(policy_name, POLICY_NONE)
3475
if policy == POLICY_APPENDPATH:
3476
value = urlutils.join(value, self.extra_path)
3477
# expand section local options right now (since POLICY_APPENDPATH
3478
# will never add options references, it's ok to expand after it).
3480
for is_ref, chunk in iter_option_refs(value):
3482
chunks.append(chunk)
3485
if ref in self.locals:
3486
chunks.append(self.locals[ref])
3488
chunks.append(chunk)
3489
value = ''.join(chunks)
3493
class StartingPathMatcher(SectionMatcher):
3494
"""Select sections for a given location respecting the Store order."""
3496
# FIXME: Both local paths and urls can be used for section names as well as
3497
# ``location`` to stay consistent with ``LocationMatcher`` which itself
3498
# inherited the fuzziness from the previous ``LocationConfig``
3499
# implementation. We probably need to revisit which encoding is allowed for
3500
# both ``location`` and section names and how we normalize
3501
# them. http://pad.lv/85479, http://pad.lv/437009 and http://359320 are
3502
# related too. -- vila 2012-01-04
3504
def __init__(self, store, location):
3505
super(StartingPathMatcher, self).__init__(store)
3506
if location.startswith('file://'):
3507
location = urlutils.local_path_from_url(location)
3508
self.location = location
3510
def get_sections(self):
3511
"""Get all sections matching ``location`` in the store.
3513
The most generic sections are described first in the store, then more
3514
specific ones can be provided for reduced scopes.
3516
The returned section are therefore returned in the reversed order so
3517
the most specific ones can be found first.
3519
location_parts = self.location.rstrip('/').split('/')
3522
# Later sections are more specific, they should be returned first
3523
for _, section in reversed(list(store.get_sections())):
3524
if section.id is None:
3525
# The no-name section is always included if present
3526
yield store, LocationSection(section, self.location)
3528
section_path = section.id
3529
if section_path.startswith('file://'):
3530
# the location is already a local path or URL, convert the
3531
# section id to the same format
3532
section_path = urlutils.local_path_from_url(section_path)
3533
if (self.location.startswith(section_path)
3534
or fnmatch.fnmatch(self.location, section_path)):
3535
section_parts = section_path.rstrip('/').split('/')
3536
extra_path = '/'.join(location_parts[len(section_parts):])
3537
yield store, LocationSection(section, extra_path)
3540
class LocationMatcher(SectionMatcher):
3542
def __init__(self, store, location):
3543
super(LocationMatcher, self).__init__(store)
3544
url, params = urlutils.split_segment_parameters(location)
3545
if location.startswith('file://'):
3546
location = urlutils.local_path_from_url(location)
3547
self.location = location
3548
branch_name = params.get('branch')
3549
if branch_name is None:
3550
self.branch_name = urlutils.basename(self.location)
3552
self.branch_name = urlutils.unescape(branch_name)
3554
def _get_matching_sections(self):
3555
"""Get all sections matching ``location``."""
3556
# We slightly diverge from LocalConfig here by allowing the no-name
3557
# section as the most generic one and the lower priority.
3558
no_name_section = None
3560
# Filter out the no_name_section so _iter_for_location_by_parts can be
3561
# used (it assumes all sections have a name).
3562
for _, section in self.store.get_sections():
3563
if section.id is None:
3564
no_name_section = section
3566
all_sections.append(section)
3567
# Unfortunately _iter_for_location_by_parts deals with section names so
3568
# we have to resync.
3569
filtered_sections = _iter_for_location_by_parts(
3570
[s.id for s in all_sections], self.location)
3571
iter_all_sections = iter(all_sections)
3572
matching_sections = []
3573
if no_name_section is not None:
3574
matching_sections.append(
3575
(0, LocationSection(no_name_section, self.location)))
3576
for section_id, extra_path, length in filtered_sections:
3577
# a section id is unique for a given store so it's safe to take the
3578
# first matching section while iterating. Also, all filtered
3579
# sections are part of 'all_sections' and will always be found
3582
section = iter_all_sections.next()
3583
if section_id == section.id:
3584
section = LocationSection(section, extra_path,
3586
matching_sections.append((length, section))
3588
return matching_sections
3590
def get_sections(self):
3591
# Override the default implementation as we want to change the order
3592
matching_sections = self._get_matching_sections()
3593
# We want the longest (aka more specific) locations first
3594
sections = sorted(matching_sections,
3595
key=lambda (length, section): (length, section.id),
3597
# Sections mentioning 'ignore_parents' restrict the selection
3598
for _, section in sections:
3599
# FIXME: We really want to use as_bool below -- vila 2011-04-07
3600
ignore = section.get('ignore_parents', None)
3601
if ignore is not None:
3602
ignore = ui.bool_from_string(ignore)
3605
# Finally, we have a valid section
3606
yield self.store, section
3609
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
3610
"""Describes an expandable option reference.
3612
We want to match the most embedded reference first.
3614
I.e. for '{{foo}}' we will get '{foo}',
3615
for '{bar{baz}}' we will get '{baz}'
3618
def iter_option_refs(string):
3619
# Split isolate refs so every other chunk is a ref
3621
for chunk in _option_ref_re.split(string):
3626
class Stack(object):
3627
"""A stack of configurations where an option can be defined"""
3629
def __init__(self, sections_def, store=None, mutable_section_id=None):
3630
"""Creates a stack of sections with an optional store for changes.
3632
:param sections_def: A list of Section or callables that returns an
3633
iterable of Section. This defines the Sections for the Stack and
3634
can be called repeatedly if needed.
3636
:param store: The optional Store where modifications will be
3637
recorded. If none is specified, no modifications can be done.
3639
:param mutable_section_id: The id of the MutableSection where changes
3640
are recorded. This requires the ``store`` parameter to be
3643
self.sections_def = sections_def
3645
self.mutable_section_id = mutable_section_id
3647
def iter_sections(self):
3648
"""Iterate all the defined sections."""
3649
# Ensuring lazy loading is achieved by delaying section matching (which
3650
# implies querying the persistent storage) until it can't be avoided
3651
# anymore by using callables to describe (possibly empty) section
3653
for sections in self.sections_def:
3654
for store, section in sections():
3655
yield store, section
3657
def get(self, name, expand=True, convert=True):
3658
"""Return the *first* option value found in the sections.
3660
This is where we guarantee that sections coming from Store are loaded
3661
lazily: the loading is delayed until we need to either check that an
3662
option exists or get its value, which in turn may require to discover
3663
in which sections it can be defined. Both of these (section and option
3664
existence) require loading the store (even partially).
3666
:param name: The queried option.
3668
:param expand: Whether options references should be expanded.
3670
:param convert: Whether the option value should be converted from
3671
unicode (do nothing for non-registered options).
3673
:returns: The value of the option.
3675
# FIXME: No caching of options nor sections yet -- vila 20110503
3677
found_store = None # Where the option value has been found
3678
# If the option is registered, it may provide additional info about
3681
opt = option_registry.get(name)
3686
def expand_and_convert(val):
3687
# This may need to be called in different contexts if the value is
3688
# None or ends up being None during expansion or conversion.
3691
if isinstance(val, basestring):
3692
val = self._expand_options_in_string(val)
3694
trace.warning('Cannot expand "%s":'
3695
' %s does not support option expansion'
3696
% (name, type(val)))
3698
val = found_store.unquote(val)
3700
val = opt.convert_from_unicode(found_store, val)
3703
# First of all, check if the environment can override the configuration
3705
if opt is not None and opt.override_from_env:
3706
value = opt.get_override()
3707
value = expand_and_convert(value)
3709
for store, section in self.iter_sections():
3710
value = section.get(name)
3711
if value is not None:
3714
value = expand_and_convert(value)
3715
if opt is not None and value is None:
3716
# If the option is registered, it may provide a default value
3717
value = opt.get_default()
3718
value = expand_and_convert(value)
3719
for hook in ConfigHooks['get']:
3720
hook(self, name, value)
3723
def expand_options(self, string, env=None):
3724
"""Expand option references in the string in the configuration context.
3726
:param string: The string containing option(s) to expand.
3728
:param env: An option dict defining additional configuration options or
3729
overriding existing ones.
3731
:returns: The expanded string.
3733
return self._expand_options_in_string(string, env)
3735
def _expand_options_in_string(self, string, env=None, _refs=None):
3736
"""Expand options in the string in the configuration context.
3738
:param string: The string to be expanded.
3740
:param env: An option dict defining additional configuration options or
3741
overriding existing ones.
3743
:param _refs: Private list (FIFO) containing the options being expanded
3746
:returns: The expanded string.
3749
# Not much to expand there
3752
# What references are currently resolved (to detect loops)
3755
# We need to iterate until no more refs appear ({{foo}} will need two
3756
# iterations for example).
3761
for is_ref, chunk in iter_option_refs(result):
3763
chunks.append(chunk)
3768
raise errors.OptionExpansionLoop(string, _refs)
3770
value = self._expand_option(name, env, _refs)
3772
raise errors.ExpandingUnknownOption(name, string)
3773
chunks.append(value)
3775
result = ''.join(chunks)
3778
def _expand_option(self, name, env, _refs):
3779
if env is not None and name in env:
3780
# Special case, values provided in env takes precedence over
3784
value = self.get(name, expand=False, convert=False)
3785
value = self._expand_options_in_string(value, env, _refs)
3788
def _get_mutable_section(self):
3789
"""Get the MutableSection for the Stack.
3791
This is where we guarantee that the mutable section is lazily loaded:
3792
this means we won't load the corresponding store before setting a value
3793
or deleting an option. In practice the store will often be loaded but
3794
this helps catching some programming errors.
3797
section = store.get_mutable_section(self.mutable_section_id)
3798
return store, section
3800
def set(self, name, value):
3801
"""Set a new value for the option."""
3802
store, section = self._get_mutable_section()
3803
section.set(name, store.quote(value))
3804
for hook in ConfigHooks['set']:
3805
hook(self, name, value)
3807
def remove(self, name):
3808
"""Remove an existing option."""
3809
_, section = self._get_mutable_section()
3810
section.remove(name)
3811
for hook in ConfigHooks['remove']:
3815
# Mostly for debugging use
3816
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3818
def _get_overrides(self):
3819
# Hack around library_state.initialize never called
3820
if bzrlib.global_state is not None:
3821
return bzrlib.global_state.cmdline_overrides.get_sections()
3825
class MemoryStack(Stack):
3826
"""A configuration stack defined from a string.
3828
This is mainly intended for tests and requires no disk resources.
3831
def __init__(self, content=None):
3832
"""Create an in-memory stack from a given content.
3834
It uses a single store based on configobj and support reading and
3837
:param content: The initial content of the store. If None, the store is
3838
not loaded and ``_load_from_string`` can and should be used if
3841
store = IniFileStore()
3842
if content is not None:
3843
store._load_from_string(content)
3844
super(MemoryStack, self).__init__(
3845
[store.get_sections], store)
3848
class _CompatibleStack(Stack):
3849
"""Place holder for compatibility with previous design.
3851
This is intended to ease the transition from the Config-based design to the
3852
Stack-based design and should not be used nor relied upon by plugins.
3854
One assumption made here is that the daughter classes will all use Stores
3855
derived from LockableIniFileStore).
3857
It implements set() and remove () by re-loading the store before applying
3858
the modification and saving it.
3860
The long term plan being to implement a single write by store to save
3861
all modifications, this class should not be used in the interim.
3864
def set(self, name, value):
3867
super(_CompatibleStack, self).set(name, value)
3868
# Force a write to persistent storage
3871
def remove(self, name):
3874
super(_CompatibleStack, self).remove(name)
3875
# Force a write to persistent storage
3879
class GlobalStack(_CompatibleStack):
3880
"""Global options only stack.
3882
The following sections are queried:
3884
* command-line overrides,
3886
* the 'DEFAULT' section in bazaar.conf
3888
This stack will use the ``DEFAULT`` section in bazaar.conf as its
3893
gstore = GlobalStore()
3894
super(GlobalStack, self).__init__(
3895
[self._get_overrides,
3896
NameMatcher(gstore, 'DEFAULT').get_sections],
3897
gstore, mutable_section_id='DEFAULT')
3900
class LocationStack(_CompatibleStack):
3901
"""Per-location options falling back to global options stack.
3904
The following sections are queried:
3906
* command-line overrides,
3908
* the sections matching ``location`` in ``locations.conf``, the order being
3909
defined by the number of path components in the section glob, higher
3910
numbers first (from most specific section to most generic).
3912
* the 'DEFAULT' section in bazaar.conf
3914
This stack will use the ``location`` section in locations.conf as its
3918
def __init__(self, location):
3919
"""Make a new stack for a location and global configuration.
3921
:param location: A URL prefix to """
3922
lstore = LocationStore()
3923
if location.startswith('file://'):
3924
location = urlutils.local_path_from_url(location)
3925
gstore = GlobalStore()
3926
super(LocationStack, self).__init__(
3927
[self._get_overrides,
3928
LocationMatcher(lstore, location).get_sections,
3929
NameMatcher(gstore, 'DEFAULT').get_sections],
3930
lstore, mutable_section_id=location)
3933
class BranchStack(Stack):
3934
"""Per-location options falling back to branch then global options stack.
3936
The following sections are queried:
3938
* command-line overrides,
3940
* the sections matching ``location`` in ``locations.conf``, the order being
3941
defined by the number of path components in the section glob, higher
3942
numbers first (from most specific section to most generic),
3944
* the no-name section in branch.conf,
3946
* the ``DEFAULT`` section in ``bazaar.conf``.
3948
This stack will use the no-name section in ``branch.conf`` as its
3952
def __init__(self, branch):
3953
lstore = LocationStore()
3954
bstore = branch._get_config_store()
3955
gstore = GlobalStore()
3956
super(BranchStack, self).__init__(
3957
[self._get_overrides,
3958
LocationMatcher(lstore, branch.base).get_sections,
3959
NameMatcher(bstore, None).get_sections,
3960
NameMatcher(gstore, 'DEFAULT').get_sections],
3962
self.branch = branch
3964
def lock_write(self, token=None):
3965
return self.branch.lock_write(token)
3968
return self.branch.unlock()
3971
def set(self, name, value):
3972
super(BranchStack, self).set(name, value)
3973
# Unlocking the branch will trigger a store.save_changes() so the last
3974
# unlock saves all the changes.
3977
def remove(self, name):
3978
super(BranchStack, self).remove(name)
3979
# Unlocking the branch will trigger a store.save_changes() so the last
3980
# unlock saves all the changes.
3983
class RemoteControlStack(_CompatibleStack):
3984
"""Remote control-only options stack."""
3986
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3987
# with the stack used for remote bzr dirs. RemoteControlStack only uses
3988
# control.conf and is used only for stack options.
3990
def __init__(self, bzrdir):
3991
cstore = bzrdir._get_config_store()
3992
super(RemoteControlStack, self).__init__(
3993
[NameMatcher(cstore, None).get_sections],
3995
self.bzrdir = bzrdir
3998
class BranchOnlyStack(Stack):
3999
"""Branch-only options stack."""
4001
# FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
4002
# stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
4003
# -- vila 2011-12-16
4005
def __init__(self, branch):
4006
bstore = branch._get_config_store()
4007
super(BranchOnlyStack, self).__init__(
4008
[NameMatcher(bstore, None).get_sections],
4010
self.branch = branch
4012
def lock_write(self, token=None):
4013
return self.branch.lock_write(token)
4016
return self.branch.unlock()
4019
def set(self, name, value):
4020
super(BranchOnlyStack, self).set(name, value)
4021
# Force a write to persistent storage
4022
self.store.save_changes()
4025
def remove(self, name):
4026
super(BranchOnlyStack, self).remove(name)
4027
# Force a write to persistent storage
4028
self.store.save_changes()
4031
class cmd_config(commands.Command):
4032
__doc__ = """Display, set or remove a configuration option.
4034
Display the active value for a given option.
4036
If --all is specified, NAME is interpreted as a regular expression and all
4037
matching options are displayed mentioning their scope. The active value
4038
that bzr will take into account is the first one displayed for each option.
4040
If no NAME is given, --all .* is implied.
4042
Setting a value is achieved by using name=value without spaces. The value
4043
is set in the most relevant scope and can be checked by displaying the
4047
takes_args = ['name?']
4051
# FIXME: This should be a registry option so that plugins can register
4052
# their own config files (or not) and will also address
4053
# http://pad.lv/788991 -- vila 20101115
4054
commands.Option('scope', help='Reduce the scope to the specified'
4055
' configuration file.',
4057
commands.Option('all',
4058
help='Display all the defined values for the matching options.',
4060
commands.Option('remove', help='Remove the option from'
4061
' the configuration file.'),
4064
_see_also = ['configuration']
4066
@commands.display_command
4067
def run(self, name=None, all=False, directory=None, scope=None,
4069
if directory is None:
4071
directory = urlutils.normalize_url(directory)
4073
raise errors.BzrError(
4074
'--all and --remove are mutually exclusive.')
4076
# Delete the option in the given scope
4077
self._remove_config_option(name, directory, scope)
4079
# Defaults to all options
4080
self._show_matching_options('.*', directory, scope)
4083
name, value = name.split('=', 1)
4085
# Display the option(s) value(s)
4087
self._show_matching_options(name, directory, scope)
4089
self._show_value(name, directory, scope)
4092
raise errors.BzrError(
4093
'Only one option can be set.')
4094
# Set the option value
4095
self._set_config_option(name, value, directory, scope)
4097
def _get_stack(self, directory, scope=None, write_access=False):
4098
"""Get the configuration stack specified by ``directory`` and ``scope``.
4100
:param directory: Where the configurations are derived from.
4102
:param scope: A specific config to start from.
4104
:param write_access: Whether a write access to the stack will be
4107
# FIXME: scope should allow access to plugin-specific stacks (even
4108
# reduced to the plugin-specific store), related to
4109
# http://pad.lv/788991 -- vila 2011-11-15
4110
if scope is not None:
4111
if scope == 'bazaar':
4112
return GlobalStack()
4113
elif scope == 'locations':
4114
return LocationStack(directory)
4115
elif scope == 'branch':
4117
controldir.ControlDir.open_containing_tree_or_branch(
4120
self.add_cleanup(br.lock_write().unlock)
4121
return br.get_config_stack()
4122
raise errors.NoSuchConfig(scope)
4126
controldir.ControlDir.open_containing_tree_or_branch(
4129
self.add_cleanup(br.lock_write().unlock)
4130
return br.get_config_stack()
4131
except errors.NotBranchError:
4132
return LocationStack(directory)
4134
def _quote_multiline(self, value):
4136
value = '"""' + value + '"""'
4139
def _show_value(self, name, directory, scope):
4140
conf = self._get_stack(directory, scope)
4141
value = conf.get(name, expand=True, convert=False)
4142
if value is not None:
4143
# Quote the value appropriately
4144
value = self._quote_multiline(value)
4145
self.outf.write('%s\n' % (value,))
4147
raise errors.NoSuchConfigOption(name)
4149
def _show_matching_options(self, name, directory, scope):
4150
name = lazy_regex.lazy_compile(name)
4151
# We want any error in the regexp to be raised *now* so we need to
4152
# avoid the delay introduced by the lazy regexp. But, we still do
4153
# want the nicer errors raised by lazy_regex.
4154
name._compile_and_collapse()
4157
conf = self._get_stack(directory, scope)
4158
for store, section in conf.iter_sections():
4159
for oname in section.iter_option_names():
4160
if name.search(oname):
4161
if cur_store_id != store.id:
4162
# Explain where the options are defined
4163
self.outf.write('%s:\n' % (store.id,))
4164
cur_store_id = store.id
4166
if (section.id is not None and cur_section != section.id):
4167
# Display the section id as it appears in the store
4168
# (None doesn't appear by definition)
4169
self.outf.write(' [%s]\n' % (section.id,))
4170
cur_section = section.id
4171
value = section.get(oname, expand=False)
4172
# Quote the value appropriately
4173
value = self._quote_multiline(value)
4174
self.outf.write(' %s = %s\n' % (oname, value))
4176
def _set_config_option(self, name, value, directory, scope):
4177
conf = self._get_stack(directory, scope, write_access=True)
4178
conf.set(name, value)
4180
def _remove_config_option(self, name, directory, scope):
4182
raise errors.BzrCommandError(
4183
'--remove expects an option to remove.')
4184
conf = self._get_stack(directory, scope, write_access=True)
4188
raise errors.NoSuchConfigOption(name)
4193
# We need adapters that can build a Store or a Stack in a test context. Test
4194
# classes, based on TestCaseWithTransport, can use the registry to parametrize
4195
# themselves. The builder will receive a test instance and should return a
4196
# ready-to-use store or stack. Plugins that define new store/stacks can also
4197
# register themselves here to be tested against the tests defined in
4198
# bzrlib.tests.test_config. Note that the builder can be called multiple times
4199
# for the same test.
4201
# The registered object should be a callable receiving a test instance
4202
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
4204
test_store_builder_registry = registry.Registry()
4206
# The registered object should be a callable receiving a test instance
4207
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
4209
test_stack_builder_registry = registry.Registry()