1
# Copyright (C) 2005-2011 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
33
in locations.conf, you specify the url of a branch and options for it.
34
Wildcards may be used - * and ? as normal in shell completion. Options
35
set in both bazaar.conf and locations.conf are overridden by the locations.conf
37
[/home/robertc/source]
38
recurse=False|True(default)
40
check_signatures= as above
41
create_signatures= as above.
43
explanation of options
44
----------------------
45
editor - this option sets the pop up editor to use during commits.
46
email - this option sets the user id bzr will use when committing.
47
check_signatures - this option controls whether bzr will require good gpg
48
signatures, ignore them, or check them if they are
50
create_signatures - this option controls whether bzr will always create
51
gpg signatures, never create them, or create them if the
52
branch is configured to require them.
53
log_format - this option sets the default log format. Possible values are
54
long, short, line, or a plugin can register new formats.
56
In bazaar.conf you can also define aliases in the ALIASES sections, example
59
lastlog=log --line -r-10..-1
60
ll=log --line -r-10..-1
69
from bzrlib import commands
70
from bzrlib.decorators import needs_write_lock
71
from bzrlib.lazy_import import lazy_import
72
lazy_import(globals(), """
76
from cStringIO import StringIO
96
from bzrlib.util.configobj import configobj
112
POLICY_APPENDPATH = 2
116
POLICY_NORECURSE: 'norecurse',
117
POLICY_APPENDPATH: 'appendpath',
122
'norecurse': POLICY_NORECURSE,
123
'appendpath': POLICY_APPENDPATH,
127
STORE_LOCATION = POLICY_NONE
128
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
129
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
134
class ConfigObj(configobj.ConfigObj):
136
def __init__(self, infile=None, **kwargs):
137
# We define our own interpolation mechanism calling it option expansion
138
super(ConfigObj, self).__init__(infile=infile,
143
def get_bool(self, section, key):
144
return self[section].as_bool(key)
146
def get_value(self, section, name):
147
# Try [] for the old DEFAULT section.
148
if section == "DEFAULT":
153
return self[section][name]
156
# FIXME: Until we can guarantee that each config file is loaded once and and
157
# only once for a given bzrlib session, we don't want to re-read the file every
158
# time we query for an option so we cache the value (bad ! watch out for tests
159
# needing to restore the proper value).This shouldn't be part of 2.4.0 final,
160
# yell at mgz^W vila and the RM if this is still present at that time
162
_expand_default_value = None
163
def _get_expand_default_value():
164
global _expand_default_value
165
if _expand_default_value is not None:
166
return _expand_default_value
167
conf = GlobalConfig()
168
# Note that we must not use None for the expand value below or we'll run
169
# into infinite recursion. Using False really would be quite silly ;)
170
expand = conf.get_user_option_as_bool('bzr.config.expand', expand=True)
172
# This is an opt-in feature, you *really* need to clearly say you want
175
_expand_default_value = expand
179
class Config(object):
180
"""A configuration policy - what username, editor, gpg needs etc."""
183
super(Config, self).__init__()
186
"""Returns a unique ID for the config."""
187
raise NotImplementedError(self.config_id)
189
def get_editor(self):
190
"""Get the users pop up editor."""
191
raise NotImplementedError
193
def get_change_editor(self, old_tree, new_tree):
194
from bzrlib import diff
195
cmd = self._get_change_editor()
198
return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
202
def get_mail_client(self):
203
"""Get a mail client to use"""
204
selected_client = self.get_user_option('mail_client')
205
_registry = mail_client.mail_client_registry
207
mail_client_class = _registry.get(selected_client)
209
raise errors.UnknownMailClient(selected_client)
210
return mail_client_class(self)
212
def _get_signature_checking(self):
213
"""Template method to override signature checking policy."""
215
def _get_signing_policy(self):
216
"""Template method to override signature creation policy."""
220
def expand_options(self, string, env=None):
221
"""Expand option references in the string in the configuration context.
223
:param string: The string containing option to expand.
225
:param env: An option dict defining additional configuration options or
226
overriding existing ones.
228
:returns: The expanded string.
230
return self._expand_options_in_string(string, env)
232
def _expand_options_in_list(self, slist, env=None, _ref_stack=None):
233
"""Expand options in a list of strings in the configuration context.
235
:param slist: A list of strings.
237
:param env: An option dict defining additional configuration options or
238
overriding existing ones.
240
:param _ref_stack: Private list containing the options being
241
expanded to detect loops.
243
:returns: The flatten list of expanded strings.
245
# expand options in each value separately flattening lists
248
value = self._expand_options_in_string(s, env, _ref_stack)
249
if isinstance(value, list):
255
def _expand_options_in_string(self, string, env=None, _ref_stack=None):
256
"""Expand options in the string in the configuration context.
258
:param string: The string to be expanded.
260
:param env: An option dict defining additional configuration options or
261
overriding existing ones.
263
:param _ref_stack: Private list containing the options being
264
expanded to detect loops.
266
:returns: The expanded string.
269
# Not much to expand there
271
if _ref_stack is None:
272
# What references are currently resolved (to detect loops)
274
if self.option_ref_re is None:
275
# We want to match the most embedded reference first (i.e. for
276
# '{{foo}}' we will get '{foo}',
277
# for '{bar{baz}}' we will get '{baz}'
278
self.option_ref_re = re.compile('({[^{}]+})')
280
# We need to iterate until no more refs appear ({{foo}} will need two
281
# iterations for example).
283
raw_chunks = self.option_ref_re.split(result)
284
if len(raw_chunks) == 1:
285
# Shorcut the trivial case: no refs
289
# Split will isolate refs so that every other chunk is a ref
291
for chunk in raw_chunks:
294
# Keep only non-empty strings (or we get bogus empty
295
# slots when a list value is involved).
300
if name in _ref_stack:
301
raise errors.OptionExpansionLoop(string, _ref_stack)
302
_ref_stack.append(name)
303
value = self._expand_option(name, env, _ref_stack)
305
raise errors.ExpandingUnknownOption(name, string)
306
if isinstance(value, list):
314
# Once a list appears as the result of an expansion, all
315
# callers will get a list result. This allows a consistent
316
# behavior even when some options in the expansion chain
317
# defined as strings (no comma in their value) but their
318
# expanded value is a list.
319
return self._expand_options_in_list(chunks, env, _ref_stack)
321
result = ''.join(chunks)
324
def _expand_option(self, name, env, _ref_stack):
325
if env is not None and name in env:
326
# Special case, values provided in env takes precedence over
330
# FIXME: This is a limited implementation, what we really need is a
331
# way to query the bzr config for the value of an option,
332
# respecting the scope rules (That is, once we implement fallback
333
# configs, getting the option value should restart from the top
334
# config, not the current one) -- vila 20101222
335
value = self.get_user_option(name, expand=False)
336
if isinstance(value, list):
337
value = self._expand_options_in_list(value, env, _ref_stack)
339
value = self._expand_options_in_string(value, env, _ref_stack)
342
def _get_user_option(self, option_name):
343
"""Template method to provide a user option."""
346
def get_user_option(self, option_name, expand=None):
347
"""Get a generic option - no special process, no default.
349
:param option_name: The queried option.
351
:param expand: Whether options references should be expanded.
353
:returns: The value of the option.
356
expand = _get_expand_default_value()
357
value = self._get_user_option(option_name)
359
if isinstance(value, list):
360
value = self._expand_options_in_list(value)
361
elif isinstance(value, dict):
362
trace.warning('Cannot expand "%s":'
363
' Dicts do not support option expansion'
366
value = self._expand_options_in_string(value)
369
def get_user_option_as_bool(self, option_name, expand=None):
370
"""Get a generic option as a boolean - no special process, no default.
372
:return None if the option doesn't exist or its value can't be
373
interpreted as a boolean. Returns True or False otherwise.
375
s = self.get_user_option(option_name, expand=expand)
377
# The option doesn't exist
379
val = ui.bool_from_string(s)
381
# The value can't be interpreted as a boolean
382
trace.warning('Value "%s" is not a boolean for "%s"',
386
def get_user_option_as_list(self, option_name, expand=None):
387
"""Get a generic option as a list - no special process, no default.
389
:return None if the option doesn't exist. Returns the value as a list
392
l = self.get_user_option(option_name, expand=expand)
393
if isinstance(l, (str, unicode)):
394
# A single value, most probably the user forgot (or didn't care to
399
def gpg_signing_command(self):
400
"""What program should be used to sign signatures?"""
401
result = self._gpg_signing_command()
406
def _gpg_signing_command(self):
407
"""See gpg_signing_command()."""
410
def log_format(self):
411
"""What log format should be used"""
412
result = self._log_format()
417
def _log_format(self):
418
"""See log_format()."""
421
def post_commit(self):
422
"""An ordered list of python functions to call.
424
Each function takes branch, rev_id as parameters.
426
return self._post_commit()
428
def _post_commit(self):
429
"""See Config.post_commit."""
432
def user_email(self):
433
"""Return just the email component of a username."""
434
return extract_email_address(self.username())
437
"""Return email-style username.
439
Something similar to 'Martin Pool <mbp@sourcefrog.net>'
441
$BZR_EMAIL can be set to override this, then
442
the concrete policy type is checked, and finally
444
If no username can be found, errors.NoWhoami exception is raised.
446
v = os.environ.get('BZR_EMAIL')
448
return v.decode(osutils.get_user_encoding())
449
v = self._get_user_id()
452
v = os.environ.get('EMAIL')
454
return v.decode(osutils.get_user_encoding())
455
name, email = _auto_user_id()
457
return '%s <%s>' % (name, email)
460
raise errors.NoWhoami()
462
def ensure_username(self):
463
"""Raise errors.NoWhoami if username is not set.
465
This method relies on the username() function raising the error.
469
def signature_checking(self):
470
"""What is the current policy for signature checking?."""
471
policy = self._get_signature_checking()
472
if policy is not None:
474
return CHECK_IF_POSSIBLE
476
def signing_policy(self):
477
"""What is the current policy for signature checking?."""
478
policy = self._get_signing_policy()
479
if policy is not None:
481
return SIGN_WHEN_REQUIRED
483
def signature_needed(self):
484
"""Is a signature needed when committing ?."""
485
policy = self._get_signing_policy()
487
policy = self._get_signature_checking()
488
if policy is not None:
489
trace.warning("Please use create_signatures,"
490
" not check_signatures to set signing policy.")
491
if policy == CHECK_ALWAYS:
493
elif policy == SIGN_ALWAYS:
497
def get_alias(self, value):
498
return self._get_alias(value)
500
def _get_alias(self, value):
503
def get_nickname(self):
504
return self._get_nickname()
506
def _get_nickname(self):
509
def get_bzr_remote_path(self):
511
return os.environ['BZR_REMOTE_PATH']
513
path = self.get_user_option("bzr_remote_path")
518
def suppress_warning(self, warning):
519
"""Should the warning be suppressed or emitted.
521
:param warning: The name of the warning being tested.
523
:returns: True if the warning should be suppressed, False otherwise.
525
warnings = self.get_user_option_as_list('suppress_warnings')
526
if warnings is None or warning not in warnings:
531
def get_merge_tools(self):
533
for (oname, value, section, conf_id, parser) in self._get_options():
534
if oname.startswith('bzr.mergetool.'):
535
tool_name = oname[len('bzr.mergetool.'):]
536
tools[tool_name] = value
537
trace.mutter('loaded merge tools: %r' % tools)
540
def find_merge_tool(self, name):
541
# We fake a defaults mechanism here by checking if the given name can
542
# be found in the known_merge_tools if it's not found in the config.
543
# This should be done through the proposed config defaults mechanism
544
# when it becomes available in the future.
545
command_line = (self.get_user_option('bzr.mergetool.%s' % name,
547
or mergetools.known_merge_tools.get(name, None))
551
class IniBasedConfig(Config):
552
"""A configuration policy that draws from ini files."""
554
def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
556
"""Base class for configuration files using an ini-like syntax.
558
:param file_name: The configuration file path.
560
super(IniBasedConfig, self).__init__()
561
self.file_name = file_name
562
if symbol_versioning.deprecated_passed(get_filename):
563
symbol_versioning.warn(
564
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
565
' Use file_name instead.',
568
if get_filename is not None:
569
self.file_name = get_filename()
571
self.file_name = file_name
576
def from_string(cls, str_or_unicode, file_name=None, save=False):
577
"""Create a config object from a string.
579
:param str_or_unicode: A string representing the file content. This will
582
:param file_name: The configuration file path.
584
:param _save: Whether the file should be saved upon creation.
586
conf = cls(file_name=file_name)
587
conf._create_from_string(str_or_unicode, save)
590
def _create_from_string(self, str_or_unicode, save):
591
self._content = StringIO(str_or_unicode.encode('utf-8'))
592
# Some tests use in-memory configs, some other always need the config
593
# file to exist on disk.
595
self._write_config_file()
597
def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
598
if self._parser is not None:
600
if symbol_versioning.deprecated_passed(file):
601
symbol_versioning.warn(
602
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
603
' Use IniBasedConfig(_content=xxx) instead.',
606
if self._content is not None:
607
co_input = self._content
608
elif self.file_name is None:
609
raise AssertionError('We have no content to create the config')
611
co_input = self.file_name
613
self._parser = ConfigObj(co_input, encoding='utf-8')
614
except configobj.ConfigObjError, e:
615
raise errors.ParseConfigError(e.errors, e.config.filename)
616
# Make sure self.reload() will use the right file name
617
self._parser.filename = self.file_name
621
"""Reload the config file from disk."""
622
if self.file_name is None:
623
raise AssertionError('We need a file name to reload the config')
624
if self._parser is not None:
625
self._parser.reload()
627
def _get_matching_sections(self):
628
"""Return an ordered list of (section_name, extra_path) pairs.
630
If the section contains inherited configuration, extra_path is
631
a string containing the additional path components.
633
section = self._get_section()
634
if section is not None:
635
return [(section, '')]
639
def _get_section(self):
640
"""Override this to define the section used by the config."""
643
def _get_sections(self, name=None):
644
"""Returns an iterator of the sections specified by ``name``.
646
:param name: The section name. If None is supplied, the default
647
configurations are yielded.
649
:return: A tuple (name, section, config_id) for all sections that will
650
be walked by user_get_option() in the 'right' order. The first one
651
is where set_user_option() will update the value.
653
parser = self._get_parser()
655
yield (name, parser[name], self.config_id())
657
# No section name has been given so we fallback to the configobj
658
# itself which holds the variables defined outside of any section.
659
yield (None, parser, self.config_id())
661
def _get_options(self, sections=None):
662
"""Return an ordered list of (name, value, section, config_id) tuples.
664
All options are returned with their associated value and the section
665
they appeared in. ``config_id`` is a unique identifier for the
666
configuration file the option is defined in.
668
:param sections: Default to ``_get_matching_sections`` if not
669
specified. This gives a better control to daughter classes about
670
which sections should be searched. This is a list of (name,
675
parser = self._get_parser()
677
for (section_name, _) in self._get_matching_sections():
679
section = parser[section_name]
681
# This could happen for an empty file for which we define a
682
# DEFAULT section. FIXME: Force callers to provide sections
683
# instead ? -- vila 20100930
685
sections.append((section_name, section))
686
config_id = self.config_id()
687
for (section_name, section) in sections:
688
for (name, value) in section.iteritems():
689
yield (name, parser._quote(value), section_name,
692
def _get_option_policy(self, section, option_name):
693
"""Return the policy for the given (section, option_name) pair."""
696
def _get_change_editor(self):
697
return self.get_user_option('change_editor')
699
def _get_signature_checking(self):
700
"""See Config._get_signature_checking."""
701
policy = self._get_user_option('check_signatures')
703
return self._string_to_signature_policy(policy)
705
def _get_signing_policy(self):
706
"""See Config._get_signing_policy"""
707
policy = self._get_user_option('create_signatures')
709
return self._string_to_signing_policy(policy)
711
def _get_user_id(self):
712
"""Get the user id from the 'email' key in the current section."""
713
return self._get_user_option('email')
715
def _get_user_option(self, option_name):
716
"""See Config._get_user_option."""
717
for (section, extra_path) in self._get_matching_sections():
719
value = self._get_parser().get_value(section, option_name)
722
policy = self._get_option_policy(section, option_name)
723
if policy == POLICY_NONE:
725
elif policy == POLICY_NORECURSE:
726
# norecurse items only apply to the exact path
731
elif policy == POLICY_APPENDPATH:
733
value = urlutils.join(value, extra_path)
736
raise AssertionError('Unexpected config policy %r' % policy)
740
def _gpg_signing_command(self):
741
"""See Config.gpg_signing_command."""
742
return self._get_user_option('gpg_signing_command')
744
def _log_format(self):
745
"""See Config.log_format."""
746
return self._get_user_option('log_format')
748
def _post_commit(self):
749
"""See Config.post_commit."""
750
return self._get_user_option('post_commit')
752
def _string_to_signature_policy(self, signature_string):
753
"""Convert a string to a signing policy."""
754
if signature_string.lower() == 'check-available':
755
return CHECK_IF_POSSIBLE
756
if signature_string.lower() == 'ignore':
758
if signature_string.lower() == 'require':
760
raise errors.BzrError("Invalid signatures policy '%s'"
763
def _string_to_signing_policy(self, signature_string):
764
"""Convert a string to a signing policy."""
765
if signature_string.lower() == 'when-required':
766
return SIGN_WHEN_REQUIRED
767
if signature_string.lower() == 'never':
769
if signature_string.lower() == 'always':
771
raise errors.BzrError("Invalid signing policy '%s'"
774
def _get_alias(self, value):
776
return self._get_parser().get_value("ALIASES",
781
def _get_nickname(self):
782
return self.get_user_option('nickname')
784
def remove_user_option(self, option_name, section_name=None):
785
"""Remove a user option and save the configuration file.
787
:param option_name: The option to be removed.
789
:param section_name: The section the option is defined in, default to
793
parser = self._get_parser()
794
if section_name is None:
797
section = parser[section_name]
799
del section[option_name]
801
raise errors.NoSuchConfigOption(option_name)
802
self._write_config_file()
804
def _write_config_file(self):
805
if self.file_name is None:
806
raise AssertionError('We cannot save, self.file_name is None')
807
conf_dir = os.path.dirname(self.file_name)
808
ensure_config_dir_exists(conf_dir)
809
atomic_file = atomicfile.AtomicFile(self.file_name)
810
self._get_parser().write(atomic_file)
813
osutils.copy_ownership_from_path(self.file_name)
816
class LockableConfig(IniBasedConfig):
817
"""A configuration needing explicit locking for access.
819
If several processes try to write the config file, the accesses need to be
822
Daughter classes should decorate all methods that update a config with the
823
``@needs_write_lock`` decorator (they call, directly or indirectly, the
824
``_write_config_file()`` method. These methods (typically ``set_option()``
825
and variants must reload the config file from disk before calling
826
``_write_config_file()``), this can be achieved by calling the
827
``self.reload()`` method. Note that the lock scope should cover both the
828
reading and the writing of the config file which is why the decorator can't
829
be applied to ``_write_config_file()`` only.
831
This should be enough to implement the following logic:
832
- lock for exclusive write access,
833
- reload the config file from disk,
837
This logic guarantees that a writer can update a value without erasing an
838
update made by another writer.
843
def __init__(self, file_name):
844
super(LockableConfig, self).__init__(file_name=file_name)
845
self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
846
# FIXME: It doesn't matter that we don't provide possible_transports
847
# below since this is currently used only for local config files ;
848
# local transports are not shared. But if/when we start using
849
# LockableConfig for other kind of transports, we will need to reuse
850
# whatever connection is already established -- vila 20100929
851
self.transport = transport.get_transport(self.dir)
852
self._lock = lockdir.LockDir(self.transport, 'lock')
854
def _create_from_string(self, unicode_bytes, save):
855
super(LockableConfig, self)._create_from_string(unicode_bytes, False)
857
# We need to handle the saving here (as opposed to IniBasedConfig)
860
self._write_config_file()
863
def lock_write(self, token=None):
864
"""Takes a write lock in the directory containing the config file.
866
If the directory doesn't exist it is created.
868
ensure_config_dir_exists(self.dir)
869
return self._lock.lock_write(token)
874
def break_lock(self):
875
self._lock.break_lock()
878
def remove_user_option(self, option_name, section_name=None):
879
super(LockableConfig, self).remove_user_option(option_name,
882
def _write_config_file(self):
883
if self._lock is None or not self._lock.is_held:
884
# NB: if the following exception is raised it probably means a
885
# missing @needs_write_lock decorator on one of the callers.
886
raise errors.ObjectNotLocked(self)
887
super(LockableConfig, self)._write_config_file()
890
class GlobalConfig(LockableConfig):
891
"""The configuration that should be used for a specific location."""
894
super(GlobalConfig, self).__init__(file_name=config_filename())
900
def from_string(cls, str_or_unicode, save=False):
901
"""Create a config object from a string.
903
:param str_or_unicode: A string representing the file content. This
904
will be utf-8 encoded.
906
:param save: Whether the file should be saved upon creation.
909
conf._create_from_string(str_or_unicode, save)
912
def get_editor(self):
913
return self._get_user_option('editor')
916
def set_user_option(self, option, value):
917
"""Save option and its value in the configuration."""
918
self._set_option(option, value, 'DEFAULT')
920
def get_aliases(self):
921
"""Return the aliases section."""
922
if 'ALIASES' in self._get_parser():
923
return self._get_parser()['ALIASES']
928
def set_alias(self, alias_name, alias_command):
929
"""Save the alias in the configuration."""
930
self._set_option(alias_name, alias_command, 'ALIASES')
933
def unset_alias(self, alias_name):
934
"""Unset an existing alias."""
936
aliases = self._get_parser().get('ALIASES')
937
if not aliases or alias_name not in aliases:
938
raise errors.NoSuchAlias(alias_name)
939
del aliases[alias_name]
940
self._write_config_file()
942
def _set_option(self, option, value, section):
944
self._get_parser().setdefault(section, {})[option] = value
945
self._write_config_file()
948
def _get_sections(self, name=None):
949
"""See IniBasedConfig._get_sections()."""
950
parser = self._get_parser()
951
# We don't give access to options defined outside of any section, we
952
# used the DEFAULT section by... default.
953
if name in (None, 'DEFAULT'):
954
# This could happen for an empty file where the DEFAULT section
955
# doesn't exist yet. So we force DEFAULT when yielding
957
if 'DEFAULT' not in parser:
958
parser['DEFAULT']= {}
959
yield (name, parser[name], self.config_id())
962
def remove_user_option(self, option_name, section_name=None):
963
if section_name is None:
964
# We need to force the default section.
965
section_name = 'DEFAULT'
966
# We need to avoid the LockableConfig implementation or we'll lock
968
super(LockableConfig, self).remove_user_option(option_name,
972
class LocationConfig(LockableConfig):
973
"""A configuration object that gives the policy for a location."""
975
def __init__(self, location):
976
super(LocationConfig, self).__init__(
977
file_name=locations_config_filename())
978
# local file locations are looked up by local path, rather than
979
# by file url. This is because the config file is a user
980
# file, and we would rather not expose the user to file urls.
981
if location.startswith('file://'):
982
location = urlutils.local_path_from_url(location)
983
self.location = location
989
def from_string(cls, str_or_unicode, location, save=False):
990
"""Create a config object from a string.
992
:param str_or_unicode: A string representing the file content. This will
995
:param location: The location url to filter the configuration.
997
:param save: Whether the file should be saved upon creation.
1000
conf._create_from_string(str_or_unicode, save)
1003
def _get_matching_sections(self):
1004
"""Return an ordered list of section names matching this location."""
1005
sections = self._get_parser()
1006
location_names = self.location.split('/')
1007
if self.location.endswith('/'):
1008
del location_names[-1]
1010
for section in sections:
1011
# location is a local path if possible, so we need
1012
# to convert 'file://' urls to local paths if necessary.
1013
# This also avoids having file:///path be a more exact
1014
# match than '/path'.
1015
if section.startswith('file://'):
1016
section_path = urlutils.local_path_from_url(section)
1018
section_path = section
1019
section_names = section_path.split('/')
1020
if section.endswith('/'):
1021
del section_names[-1]
1022
names = zip(location_names, section_names)
1025
if not fnmatch.fnmatch(name[0], name[1]):
1030
# so, for the common prefix they matched.
1031
# if section is longer, no match.
1032
if len(section_names) > len(location_names):
1034
matches.append((len(section_names), section,
1035
'/'.join(location_names[len(section_names):])))
1036
# put the longest (aka more specific) locations first
1037
matches.sort(reverse=True)
1039
for (length, section, extra_path) in matches:
1040
sections.append((section, extra_path))
1041
# should we stop looking for parent configs here?
1043
if self._get_parser()[section].as_bool('ignore_parents'):
1049
def _get_sections(self, name=None):
1050
"""See IniBasedConfig._get_sections()."""
1051
# We ignore the name here as the only sections handled are named with
1052
# the location path and we don't expose embedded sections either.
1053
parser = self._get_parser()
1054
for name, extra_path in self._get_matching_sections():
1055
yield (name, parser[name], self.config_id())
1057
def _get_option_policy(self, section, option_name):
1058
"""Return the policy for the given (section, option_name) pair."""
1059
# check for the old 'recurse=False' flag
1061
recurse = self._get_parser()[section].as_bool('recurse')
1065
return POLICY_NORECURSE
1067
policy_key = option_name + ':policy'
1069
policy_name = self._get_parser()[section][policy_key]
1073
return _policy_value[policy_name]
1075
def _set_option_policy(self, section, option_name, option_policy):
1076
"""Set the policy for the given option name in the given section."""
1077
# The old recurse=False option affects all options in the
1078
# section. To handle multiple policies in the section, we
1079
# need to convert it to a policy_norecurse key.
1081
recurse = self._get_parser()[section].as_bool('recurse')
1085
symbol_versioning.warn(
1086
'The recurse option is deprecated as of 0.14. '
1087
'The section "%s" has been converted to use policies.'
1090
del self._get_parser()[section]['recurse']
1092
for key in self._get_parser()[section].keys():
1093
if not key.endswith(':policy'):
1094
self._get_parser()[section][key +
1095
':policy'] = 'norecurse'
1097
policy_key = option_name + ':policy'
1098
policy_name = _policy_name[option_policy]
1099
if policy_name is not None:
1100
self._get_parser()[section][policy_key] = policy_name
1102
if policy_key in self._get_parser()[section]:
1103
del self._get_parser()[section][policy_key]
1106
def set_user_option(self, option, value, store=STORE_LOCATION):
1107
"""Save option and its value in the configuration."""
1108
if store not in [STORE_LOCATION,
1109
STORE_LOCATION_NORECURSE,
1110
STORE_LOCATION_APPENDPATH]:
1111
raise ValueError('bad storage policy %r for %r' %
1114
location = self.location
1115
if location.endswith('/'):
1116
location = location[:-1]
1117
parser = self._get_parser()
1118
if not location in parser and not location + '/' in parser:
1119
parser[location] = {}
1120
elif location + '/' in parser:
1121
location = location + '/'
1122
parser[location][option]=value
1123
# the allowed values of store match the config policies
1124
self._set_option_policy(location, option, store)
1125
self._write_config_file()
1128
class BranchConfig(Config):
1129
"""A configuration object giving the policy for a branch."""
1131
def __init__(self, branch):
1132
super(BranchConfig, self).__init__()
1133
self._location_config = None
1134
self._branch_data_config = None
1135
self._global_config = None
1136
self.branch = branch
1137
self.option_sources = (self._get_location_config,
1138
self._get_branch_data_config,
1139
self._get_global_config)
1141
def config_id(self):
1144
def _get_branch_data_config(self):
1145
if self._branch_data_config is None:
1146
self._branch_data_config = TreeConfig(self.branch)
1147
self._branch_data_config.config_id = self.config_id
1148
return self._branch_data_config
1150
def _get_location_config(self):
1151
if self._location_config is None:
1152
self._location_config = LocationConfig(self.branch.base)
1153
return self._location_config
1155
def _get_global_config(self):
1156
if self._global_config is None:
1157
self._global_config = GlobalConfig()
1158
return self._global_config
1160
def _get_best_value(self, option_name):
1161
"""This returns a user option from local, tree or global config.
1163
They are tried in that order. Use get_safe_value if trusted values
1166
for source in self.option_sources:
1167
value = getattr(source(), option_name)()
1168
if value is not None:
1172
def _get_safe_value(self, option_name):
1173
"""This variant of get_best_value never returns untrusted values.
1175
It does not return values from the branch data, because the branch may
1176
not be controlled by the user.
1178
We may wish to allow locations.conf to control whether branches are
1179
trusted in the future.
1181
for source in (self._get_location_config, self._get_global_config):
1182
value = getattr(source(), option_name)()
1183
if value is not None:
1187
def _get_user_id(self):
1188
"""Return the full user id for the branch.
1190
e.g. "John Hacker <jhacker@example.com>"
1191
This is looked up in the email controlfile for the branch.
1194
return (self.branch._transport.get_bytes("email")
1195
.decode(osutils.get_user_encoding())
1197
except errors.NoSuchFile, e:
1200
return self._get_best_value('_get_user_id')
1202
def _get_change_editor(self):
1203
return self._get_best_value('_get_change_editor')
1205
def _get_signature_checking(self):
1206
"""See Config._get_signature_checking."""
1207
return self._get_best_value('_get_signature_checking')
1209
def _get_signing_policy(self):
1210
"""See Config._get_signing_policy."""
1211
return self._get_best_value('_get_signing_policy')
1213
def _get_user_option(self, option_name):
1214
"""See Config._get_user_option."""
1215
for source in self.option_sources:
1216
value = source()._get_user_option(option_name)
1217
if value is not None:
1221
def _get_sections(self, name=None):
1222
"""See IniBasedConfig.get_sections()."""
1223
for source in self.option_sources:
1224
for section in source()._get_sections(name):
1227
def _get_options(self, sections=None):
1229
# First the locations options
1230
for option in self._get_location_config()._get_options():
1232
# Then the branch options
1233
branch_config = self._get_branch_data_config()
1234
if sections is None:
1235
sections = [('DEFAULT', branch_config._get_parser())]
1236
# FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
1237
# Config itself has no notion of sections :( -- vila 20101001
1238
config_id = self.config_id()
1239
for (section_name, section) in sections:
1240
for (name, value) in section.iteritems():
1241
yield (name, value, section_name,
1242
config_id, branch_config._get_parser())
1243
# Then the global options
1244
for option in self._get_global_config()._get_options():
1247
def set_user_option(self, name, value, store=STORE_BRANCH,
1249
if store == STORE_BRANCH:
1250
self._get_branch_data_config().set_option(value, name)
1251
elif store == STORE_GLOBAL:
1252
self._get_global_config().set_user_option(name, value)
1254
self._get_location_config().set_user_option(name, value, store)
1257
if store in (STORE_GLOBAL, STORE_BRANCH):
1258
mask_value = self._get_location_config().get_user_option(name)
1259
if mask_value is not None:
1260
trace.warning('Value "%s" is masked by "%s" from'
1261
' locations.conf', value, mask_value)
1263
if store == STORE_GLOBAL:
1264
branch_config = self._get_branch_data_config()
1265
mask_value = branch_config.get_user_option(name)
1266
if mask_value is not None:
1267
trace.warning('Value "%s" is masked by "%s" from'
1268
' branch.conf', value, mask_value)
1270
def remove_user_option(self, option_name, section_name=None):
1271
self._get_branch_data_config().remove_option(option_name, section_name)
1273
def _gpg_signing_command(self):
1274
"""See Config.gpg_signing_command."""
1275
return self._get_safe_value('_gpg_signing_command')
1277
def _post_commit(self):
1278
"""See Config.post_commit."""
1279
return self._get_safe_value('_post_commit')
1281
def _get_nickname(self):
1282
value = self._get_explicit_nickname()
1283
if value is not None:
1285
return urlutils.unescape(self.branch.base.split('/')[-2])
1287
def has_explicit_nickname(self):
1288
"""Return true if a nickname has been explicitly assigned."""
1289
return self._get_explicit_nickname() is not None
1291
def _get_explicit_nickname(self):
1292
return self._get_best_value('_get_nickname')
1294
def _log_format(self):
1295
"""See Config.log_format."""
1296
return self._get_best_value('_log_format')
1299
def ensure_config_dir_exists(path=None):
1300
"""Make sure a configuration directory exists.
1301
This makes sure that the directory exists.
1302
On windows, since configuration directories are 2 levels deep,
1303
it makes sure both the directory and the parent directory exists.
1307
if not os.path.isdir(path):
1308
if sys.platform == 'win32':
1309
parent_dir = os.path.dirname(path)
1310
if not os.path.isdir(parent_dir):
1311
trace.mutter('creating config parent directory: %r', parent_dir)
1312
os.mkdir(parent_dir)
1313
trace.mutter('creating config directory: %r', path)
1315
osutils.copy_ownership_from_path(path)
1319
"""Return per-user configuration directory.
1321
By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1322
and Linux. On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1323
that will be used instead.
1325
TODO: Global option --config-dir to override this.
1327
base = os.environ.get('BZR_HOME', None)
1328
if sys.platform == 'win32':
1329
# environ variables on Windows are in user encoding/mbcs. So decode
1331
if base is not None:
1332
base = base.decode('mbcs')
1334
base = win32utils.get_appdata_location_unicode()
1336
base = os.environ.get('HOME', None)
1337
if base is not None:
1338
base = base.decode('mbcs')
1340
raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1342
return osutils.pathjoin(base, 'bazaar', '2.0')
1343
elif sys.platform == 'darwin':
1345
# this takes into account $HOME
1346
base = os.path.expanduser("~")
1347
return osutils.pathjoin(base, '.bazaar')
1351
xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1353
xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1354
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1355
if osutils.isdir(xdg_dir):
1357
"Using configuration in XDG directory %s." % xdg_dir)
1360
base = os.path.expanduser("~")
1361
return osutils.pathjoin(base, ".bazaar")
1364
def config_filename():
1365
"""Return per-user configuration ini file filename."""
1366
return osutils.pathjoin(config_dir(), 'bazaar.conf')
1369
def locations_config_filename():
1370
"""Return per-user configuration ini file filename."""
1371
return osutils.pathjoin(config_dir(), 'locations.conf')
1374
def authentication_config_filename():
1375
"""Return per-user authentication ini file filename."""
1376
return osutils.pathjoin(config_dir(), 'authentication.conf')
1379
def user_ignore_config_filename():
1380
"""Return the user default ignore filename"""
1381
return osutils.pathjoin(config_dir(), 'ignore')
1385
"""Return the directory name to store crash files.
1387
This doesn't implicitly create it.
1389
On Windows it's in the config directory; elsewhere it's /var/crash
1390
which may be monitored by apport. It can be overridden by
1393
if sys.platform == 'win32':
1394
return osutils.pathjoin(config_dir(), 'Crash')
1396
# XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
1398
return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
1401
def xdg_cache_dir():
1402
# See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1403
# Possibly this should be different on Windows?
1404
e = os.environ.get('XDG_CACHE_DIR', None)
1408
return os.path.expanduser('~/.cache')
1411
def _get_default_mail_domain():
1412
"""If possible, return the assumed default email domain.
1414
:returns: string mail domain, or None.
1416
if sys.platform == 'win32':
1417
# No implementation yet; patches welcome
1420
f = open('/etc/mailname')
1421
except (IOError, OSError), e:
1424
domain = f.read().strip()
1430
def _auto_user_id():
1431
"""Calculate automatic user identification.
1433
:returns: (realname, email), either of which may be None if they can't be
1436
Only used when none is set in the environment or the id file.
1438
This only returns an email address if we can be fairly sure the
1439
address is reasonable, ie if /etc/mailname is set on unix.
1441
This doesn't use the FQDN as the default domain because that may be
1442
slow, and it doesn't use the hostname alone because that's not normally
1443
a reasonable address.
1445
if sys.platform == 'win32':
1446
# No implementation to reliably determine Windows default mail
1447
# address; please add one.
1450
default_mail_domain = _get_default_mail_domain()
1451
if not default_mail_domain:
1457
w = pwd.getpwuid(uid)
1459
mutter('no passwd entry for uid %d?' % uid)
1462
# we try utf-8 first, because on many variants (like Linux),
1463
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
1464
# false positives. (many users will have their user encoding set to
1465
# latin-1, which cannot raise UnicodeError.)
1467
gecos = w.pw_gecos.decode('utf-8')
1469
except UnicodeError:
1471
encoding = osutils.get_user_encoding()
1472
gecos = w.pw_gecos.decode(encoding)
1473
except UnicodeError, e:
1474
mutter("cannot decode passwd entry %s" % w)
1477
username = w.pw_name.decode(encoding)
1478
except UnicodeError, e:
1479
mutter("cannot decode passwd entry %s" % w)
1482
comma = gecos.find(',')
1486
realname = gecos[:comma]
1488
return realname, (username + '@' + default_mail_domain)
1491
def parse_username(username):
1492
"""Parse e-mail username and return a (name, address) tuple."""
1493
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1495
return (username, '')
1497
return (match.group(1), match.group(2))
1500
def extract_email_address(e):
1501
"""Return just the address part of an email string.
1503
That is just the user@domain part, nothing else.
1504
This part is required to contain only ascii characters.
1505
If it can't be extracted, raises an error.
1507
>>> extract_email_address('Jane Tester <jane@test.com>')
1510
name, email = parse_username(e)
1512
raise errors.NoEmailInUsername(e)
1516
class TreeConfig(IniBasedConfig):
1517
"""Branch configuration data associated with its contents, not location"""
1519
# XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
1521
def __init__(self, branch):
1522
self._config = branch._get_config()
1523
self.branch = branch
1525
def _get_parser(self, file=None):
1526
if file is not None:
1527
return IniBasedConfig._get_parser(file)
1528
return self._config._get_configobj()
1530
def get_option(self, name, section=None, default=None):
1531
self.branch.lock_read()
1533
return self._config.get_option(name, section, default)
1535
self.branch.unlock()
1537
def set_option(self, value, name, section=None):
1538
"""Set a per-branch configuration option"""
1539
# FIXME: We shouldn't need to lock explicitly here but rather rely on
1540
# higher levels providing the right lock -- vila 20101004
1541
self.branch.lock_write()
1543
self._config.set_option(value, name, section)
1545
self.branch.unlock()
1547
def remove_option(self, option_name, section_name=None):
1548
# FIXME: We shouldn't need to lock explicitly here but rather rely on
1549
# higher levels providing the right lock -- vila 20101004
1550
self.branch.lock_write()
1552
self._config.remove_option(option_name, section_name)
1554
self.branch.unlock()
1557
class AuthenticationConfig(object):
1558
"""The authentication configuration file based on a ini file.
1560
Implements the authentication.conf file described in
1561
doc/developers/authentication-ring.txt.
1564
def __init__(self, _file=None):
1565
self._config = None # The ConfigObj
1567
self._filename = authentication_config_filename()
1568
self._input = self._filename = authentication_config_filename()
1570
# Tests can provide a string as _file
1571
self._filename = None
1574
def _get_config(self):
1575
if self._config is not None:
1578
# FIXME: Should we validate something here ? Includes: empty
1579
# sections are useless, at least one of
1580
# user/password/password_encoding should be defined, etc.
1582
# Note: the encoding below declares that the file itself is utf-8
1583
# encoded, but the values in the ConfigObj are always Unicode.
1584
self._config = ConfigObj(self._input, encoding='utf-8')
1585
except configobj.ConfigObjError, e:
1586
raise errors.ParseConfigError(e.errors, e.config.filename)
1590
"""Save the config file, only tests should use it for now."""
1591
conf_dir = os.path.dirname(self._filename)
1592
ensure_config_dir_exists(conf_dir)
1593
f = file(self._filename, 'wb')
1595
self._get_config().write(f)
1599
def _set_option(self, section_name, option_name, value):
1600
"""Set an authentication configuration option"""
1601
conf = self._get_config()
1602
section = conf.get(section_name)
1605
section = conf[section]
1606
section[option_name] = value
1609
def get_credentials(self, scheme, host, port=None, user=None, path=None,
1611
"""Returns the matching credentials from authentication.conf file.
1613
:param scheme: protocol
1615
:param host: the server address
1617
:param port: the associated port (optional)
1619
:param user: login (optional)
1621
:param path: the absolute path on the server (optional)
1623
:param realm: the http authentication realm (optional)
1625
:return: A dict containing the matching credentials or None.
1627
- name: the section name of the credentials in the
1628
authentication.conf file,
1629
- user: can't be different from the provided user if any,
1630
- scheme: the server protocol,
1631
- host: the server address,
1632
- port: the server port (can be None),
1633
- path: the absolute server path (can be None),
1634
- realm: the http specific authentication realm (can be None),
1635
- password: the decoded password, could be None if the credential
1636
defines only the user
1637
- verify_certificates: https specific, True if the server
1638
certificate should be verified, False otherwise.
1641
for auth_def_name, auth_def in self._get_config().items():
1642
if type(auth_def) is not configobj.Section:
1643
raise ValueError("%s defined outside a section" % auth_def_name)
1645
a_scheme, a_host, a_user, a_path = map(
1646
auth_def.get, ['scheme', 'host', 'user', 'path'])
1649
a_port = auth_def.as_int('port')
1653
raise ValueError("'port' not numeric in %s" % auth_def_name)
1655
a_verify_certificates = auth_def.as_bool('verify_certificates')
1657
a_verify_certificates = True
1660
"'verify_certificates' not boolean in %s" % auth_def_name)
1663
if a_scheme is not None and scheme != a_scheme:
1665
if a_host is not None:
1666
if not (host == a_host
1667
or (a_host.startswith('.') and host.endswith(a_host))):
1669
if a_port is not None and port != a_port:
1671
if (a_path is not None and path is not None
1672
and not path.startswith(a_path)):
1674
if (a_user is not None and user is not None
1675
and a_user != user):
1676
# Never contradict the caller about the user to be used
1681
# Prepare a credentials dictionary with additional keys
1682
# for the credential providers
1683
credentials = dict(name=auth_def_name,
1690
password=auth_def.get('password', None),
1691
verify_certificates=a_verify_certificates)
1692
# Decode the password in the credentials (or get one)
1693
self.decode_password(credentials,
1694
auth_def.get('password_encoding', None))
1695
if 'auth' in debug.debug_flags:
1696
trace.mutter("Using authentication section: %r", auth_def_name)
1699
if credentials is None:
1700
# No credentials were found in authentication.conf, try the fallback
1701
# credentials stores.
1702
credentials = credential_store_registry.get_fallback_credentials(
1703
scheme, host, port, user, path, realm)
1707
def set_credentials(self, name, host, user, scheme=None, password=None,
1708
port=None, path=None, verify_certificates=None,
1710
"""Set authentication credentials for a host.
1712
Any existing credentials with matching scheme, host, port and path
1713
will be deleted, regardless of name.
1715
:param name: An arbitrary name to describe this set of credentials.
1716
:param host: Name of the host that accepts these credentials.
1717
:param user: The username portion of these credentials.
1718
:param scheme: The URL scheme (e.g. ssh, http) the credentials apply
1720
:param password: Password portion of these credentials.
1721
:param port: The IP port on the host that these credentials apply to.
1722
:param path: A filesystem path on the host that these credentials
1724
:param verify_certificates: On https, verify server certificates if
1726
:param realm: The http authentication realm (optional).
1728
values = {'host': host, 'user': user}
1729
if password is not None:
1730
values['password'] = password
1731
if scheme is not None:
1732
values['scheme'] = scheme
1733
if port is not None:
1734
values['port'] = '%d' % port
1735
if path is not None:
1736
values['path'] = path
1737
if verify_certificates is not None:
1738
values['verify_certificates'] = str(verify_certificates)
1739
if realm is not None:
1740
values['realm'] = realm
1741
config = self._get_config()
1743
for section, existing_values in config.items():
1744
for key in ('scheme', 'host', 'port', 'path', 'realm'):
1745
if existing_values.get(key) != values.get(key):
1749
config.update({name: values})
1752
def get_user(self, scheme, host, port=None, realm=None, path=None,
1753
prompt=None, ask=False, default=None):
1754
"""Get a user from authentication file.
1756
:param scheme: protocol
1758
:param host: the server address
1760
:param port: the associated port (optional)
1762
:param realm: the realm sent by the server (optional)
1764
:param path: the absolute path on the server (optional)
1766
:param ask: Ask the user if there is no explicitly configured username
1769
:param default: The username returned if none is defined (optional).
1771
:return: The found user.
1773
credentials = self.get_credentials(scheme, host, port, user=None,
1774
path=path, realm=realm)
1775
if credentials is not None:
1776
user = credentials['user']
1782
# Create a default prompt suitable for most cases
1783
prompt = scheme.upper() + ' %(host)s username'
1784
# Special handling for optional fields in the prompt
1785
if port is not None:
1786
prompt_host = '%s:%d' % (host, port)
1789
user = ui.ui_factory.get_username(prompt, host=prompt_host)
1794
def get_password(self, scheme, host, user, port=None,
1795
realm=None, path=None, prompt=None):
1796
"""Get a password from authentication file or prompt the user for one.
1798
:param scheme: protocol
1800
:param host: the server address
1802
:param port: the associated port (optional)
1806
:param realm: the realm sent by the server (optional)
1808
:param path: the absolute path on the server (optional)
1810
:return: The found password or the one entered by the user.
1812
credentials = self.get_credentials(scheme, host, port, user, path,
1814
if credentials is not None:
1815
password = credentials['password']
1816
if password is not None and scheme is 'ssh':
1817
trace.warning('password ignored in section [%s],'
1818
' use an ssh agent instead'
1819
% credentials['name'])
1823
# Prompt user only if we could't find a password
1824
if password is None:
1826
# Create a default prompt suitable for most cases
1827
prompt = '%s' % scheme.upper() + ' %(user)s@%(host)s password'
1828
# Special handling for optional fields in the prompt
1829
if port is not None:
1830
prompt_host = '%s:%d' % (host, port)
1833
password = ui.ui_factory.get_password(prompt,
1834
host=prompt_host, user=user)
1837
def decode_password(self, credentials, encoding):
1839
cs = credential_store_registry.get_credential_store(encoding)
1841
raise ValueError('%r is not a known password_encoding' % encoding)
1842
credentials['password'] = cs.decode_password(credentials)
1846
class CredentialStoreRegistry(registry.Registry):
1847
"""A class that registers credential stores.
1849
A credential store provides access to credentials via the password_encoding
1850
field in authentication.conf sections.
1852
Except for stores provided by bzr itself, most stores are expected to be
1853
provided by plugins that will therefore use
1854
register_lazy(password_encoding, module_name, member_name, help=help,
1855
fallback=fallback) to install themselves.
1857
A fallback credential store is one that is queried if no credentials can be
1858
found via authentication.conf.
1861
def get_credential_store(self, encoding=None):
1862
cs = self.get(encoding)
1867
def is_fallback(self, name):
1868
"""Check if the named credentials store should be used as fallback."""
1869
return self.get_info(name)
1871
def get_fallback_credentials(self, scheme, host, port=None, user=None,
1872
path=None, realm=None):
1873
"""Request credentials from all fallback credentials stores.
1875
The first credentials store that can provide credentials wins.
1878
for name in self.keys():
1879
if not self.is_fallback(name):
1881
cs = self.get_credential_store(name)
1882
credentials = cs.get_credentials(scheme, host, port, user,
1884
if credentials is not None:
1885
# We found some credentials
1889
def register(self, key, obj, help=None, override_existing=False,
1891
"""Register a new object to a name.
1893
:param key: This is the key to use to request the object later.
1894
:param obj: The object to register.
1895
:param help: Help text for this entry. This may be a string or
1896
a callable. If it is a callable, it should take two
1897
parameters (registry, key): this registry and the key that
1898
the help was registered under.
1899
:param override_existing: Raise KeyErorr if False and something has
1900
already been registered for that key. If True, ignore if there
1901
is an existing key (always register the new value).
1902
:param fallback: Whether this credential store should be
1905
return super(CredentialStoreRegistry,
1906
self).register(key, obj, help, info=fallback,
1907
override_existing=override_existing)
1909
def register_lazy(self, key, module_name, member_name,
1910
help=None, override_existing=False,
1912
"""Register a new credential store to be loaded on request.
1914
:param module_name: The python path to the module. Such as 'os.path'.
1915
:param member_name: The member of the module to return. If empty or
1916
None, get() will return the module itself.
1917
:param help: Help text for this entry. This may be a string or
1919
:param override_existing: If True, replace the existing object
1920
with the new one. If False, if there is already something
1921
registered with the same key, raise a KeyError
1922
:param fallback: Whether this credential store should be
1925
return super(CredentialStoreRegistry, self).register_lazy(
1926
key, module_name, member_name, help,
1927
info=fallback, override_existing=override_existing)
1930
credential_store_registry = CredentialStoreRegistry()
1933
class CredentialStore(object):
1934
"""An abstract class to implement storage for credentials"""
1936
def decode_password(self, credentials):
1937
"""Returns a clear text password for the provided credentials."""
1938
raise NotImplementedError(self.decode_password)
1940
def get_credentials(self, scheme, host, port=None, user=None, path=None,
1942
"""Return the matching credentials from this credential store.
1944
This method is only called on fallback credential stores.
1946
raise NotImplementedError(self.get_credentials)
1950
class PlainTextCredentialStore(CredentialStore):
1951
__doc__ = """Plain text credential store for the authentication.conf file"""
1953
def decode_password(self, credentials):
1954
"""See CredentialStore.decode_password."""
1955
return credentials['password']
1958
credential_store_registry.register('plain', PlainTextCredentialStore,
1959
help=PlainTextCredentialStore.__doc__)
1960
credential_store_registry.default_key = 'plain'
1963
class BzrDirConfig(object):
1965
def __init__(self, bzrdir):
1966
self._bzrdir = bzrdir
1967
self._config = bzrdir._get_config()
1969
def set_default_stack_on(self, value):
1970
"""Set the default stacking location.
1972
It may be set to a location, or None.
1974
This policy affects all branches contained by this bzrdir, except for
1975
those under repositories.
1977
if self._config is None:
1978
raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
1980
self._config.set_option('', 'default_stack_on')
1982
self._config.set_option(value, 'default_stack_on')
1984
def get_default_stack_on(self):
1985
"""Return the default stacking location.
1987
This will either be a location, or None.
1989
This policy affects all branches contained by this bzrdir, except for
1990
those under repositories.
1992
if self._config is None:
1994
value = self._config.get_option('default_stack_on')
2000
class TransportConfig(object):
2001
"""A Config that reads/writes a config file on a Transport.
2003
It is a low-level object that considers config data to be name/value pairs
2004
that may be associated with a section. Assigning meaning to these values
2005
is done at higher levels like TreeConfig.
2008
def __init__(self, transport, filename):
2009
self._transport = transport
2010
self._filename = filename
2012
def get_option(self, name, section=None, default=None):
2013
"""Return the value associated with a named option.
2015
:param name: The name of the value
2016
:param section: The section the option is in (if any)
2017
:param default: The value to return if the value is not set
2018
:return: The value or default value
2020
configobj = self._get_configobj()
2022
section_obj = configobj
2025
section_obj = configobj[section]
2028
return section_obj.get(name, default)
2030
def set_option(self, value, name, section=None):
2031
"""Set the value associated with a named option.
2033
:param value: The value to set
2034
:param name: The name of the value to set
2035
:param section: The section the option is in (if any)
2037
configobj = self._get_configobj()
2039
configobj[name] = value
2041
configobj.setdefault(section, {})[name] = value
2042
self._set_configobj(configobj)
2044
def remove_option(self, option_name, section_name=None):
2045
configobj = self._get_configobj()
2046
if section_name is None:
2047
del configobj[option_name]
2049
del configobj[section_name][option_name]
2050
self._set_configobj(configobj)
2052
def _get_config_file(self):
2054
return StringIO(self._transport.get_bytes(self._filename))
2055
except errors.NoSuchFile:
2058
def _get_configobj(self):
2059
f = self._get_config_file()
2061
return ConfigObj(f, encoding='utf-8')
2065
def _set_configobj(self, configobj):
2066
out_file = StringIO()
2067
configobj.write(out_file)
2069
self._transport.put_file(self._filename, out_file)
2072
class cmd_config(commands.Command):
2073
__doc__ = """Display, set or remove a configuration option.
2075
Display the active value for a given option.
2077
If --all is specified, NAME is interpreted as a regular expression and all
2078
matching options are displayed mentioning their scope. The active value
2079
that bzr will take into account is the first one displayed for each option.
2081
If no NAME is given, --all .* is implied.
2083
Setting a value is achieved by using name=value without spaces. The value
2084
is set in the most relevant scope and can be checked by displaying the
2088
takes_args = ['name?']
2092
# FIXME: This should be a registry option so that plugins can register
2093
# their own config files (or not) -- vila 20101002
2094
commands.Option('scope', help='Reduce the scope to the specified'
2095
' configuration file',
2097
commands.Option('all',
2098
help='Display all the defined values for the matching options.',
2100
commands.Option('remove', help='Remove the option from'
2101
' the configuration file'),
2104
@commands.display_command
2105
def run(self, name=None, all=False, directory=None, scope=None,
2107
if directory is None:
2109
directory = urlutils.normalize_url(directory)
2111
raise errors.BzrError(
2112
'--all and --remove are mutually exclusive.')
2114
# Delete the option in the given scope
2115
self._remove_config_option(name, directory, scope)
2117
# Defaults to all options
2118
self._show_matching_options('.*', directory, scope)
2121
name, value = name.split('=', 1)
2123
# Display the option(s) value(s)
2125
self._show_matching_options(name, directory, scope)
2127
self._show_value(name, directory, scope)
2130
raise errors.BzrError(
2131
'Only one option can be set.')
2132
# Set the option value
2133
self._set_config_option(name, value, directory, scope)
2135
def _get_configs(self, directory, scope=None):
2136
"""Iterate the configurations specified by ``directory`` and ``scope``.
2138
:param directory: Where the configurations are derived from.
2140
:param scope: A specific config to start from.
2142
if scope is not None:
2143
if scope == 'bazaar':
2144
yield GlobalConfig()
2145
elif scope == 'locations':
2146
yield LocationConfig(directory)
2147
elif scope == 'branch':
2148
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2150
yield br.get_config()
2153
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2155
yield br.get_config()
2156
except errors.NotBranchError:
2157
yield LocationConfig(directory)
2158
yield GlobalConfig()
2160
def _show_value(self, name, directory, scope):
2162
for c in self._get_configs(directory, scope):
2165
for (oname, value, section, conf_id, parser) in c._get_options():
2167
# Display only the first value and exit
2169
# FIXME: We need to use get_user_option to take policies
2170
# into account and we need to make sure the option exists
2171
# too (hence the two for loops), this needs a better API
2173
value = c.get_user_option(name)
2174
# Quote the value appropriately
2175
value = parser._quote(value)
2176
self.outf.write('%s\n' % (value,))
2180
raise errors.NoSuchConfigOption(name)
2182
def _show_matching_options(self, name, directory, scope):
2183
name = re.compile(name)
2184
# We want any error in the regexp to be raised *now* so we need to
2185
# avoid the delay introduced by the lazy regexp.
2186
name._compile_and_collapse()
2189
for c in self._get_configs(directory, scope):
2190
for (oname, value, section, conf_id, parser) in c._get_options():
2191
if name.search(oname):
2192
if cur_conf_id != conf_id:
2193
# Explain where the options are defined
2194
self.outf.write('%s:\n' % (conf_id,))
2195
cur_conf_id = conf_id
2197
if (section not in (None, 'DEFAULT')
2198
and cur_section != section):
2199
# Display the section if it's not the default (or only)
2201
self.outf.write(' [%s]\n' % (section,))
2202
cur_section = section
2203
self.outf.write(' %s = %s\n' % (oname, value))
2205
def _set_config_option(self, name, value, directory, scope):
2206
for conf in self._get_configs(directory, scope):
2207
conf.set_user_option(name, value)
2210
raise errors.NoSuchConfig(scope)
2212
def _remove_config_option(self, name, directory, scope):
2214
raise errors.BzrCommandError(
2215
'--remove expects an option to remove.')
2217
for conf in self._get_configs(directory, scope):
2218
for (section_name, section, conf_id) in conf._get_sections():
2219
if scope is not None and conf_id != scope:
2220
# Not the right configuration file
2223
if conf_id != conf.config_id():
2224
conf = self._get_configs(directory, conf_id).next()
2225
# We use the first section in the first config where the
2226
# option is defined to remove it
2227
conf.remove_user_option(name, section_name)
2232
raise errors.NoSuchConfig(scope)
2234
raise errors.NoSuchConfigOption(name)