133
class ConfigObj(configobj.ConfigObj):
135
def __init__(self, infile=None, **kwargs):
136
# We define our own interpolation mechanism calling it option expansion
137
super(ConfigObj, self).__init__(infile=infile,
142
def get_bool(self, section, key):
143
return self[section].as_bool(key)
145
def get_value(self, section, name):
146
# Try [] for the old DEFAULT section.
147
if section == "DEFAULT":
152
return self[section][name]
155
# FIXME: Until we can guarantee that each config file is loaded once and and
156
# only once for a given bzrlib session, we don't want to re-read the file every
157
# time we query for an option so we cache the value (bad ! watch out for tests
158
# needing to restore the proper value).This shouldn't be part of 2.4.0 final,
159
# yell at mgz^W vila and the RM if this is still present at that time
161
_expand_default_value = None
162
def _get_expand_default_value():
163
global _expand_default_value
164
if _expand_default_value is not None:
165
return _expand_default_value
166
conf = GlobalConfig()
167
# Note that we must not use None for the expand value below or we'll run
168
# into infinite recursion. Using False really would be quite silly ;)
169
expand = conf.get_user_option_as_bool('bzr.config.expand', expand=True)
171
# This is an opt-in feature, you *really* need to clearly say you want
174
_expand_default_value = expand
127
def ConfigObj(*args, **kwargs):
129
if _ConfigObj is None:
130
class ConfigObj(configobj.ConfigObj):
132
def get_bool(self, section, key):
133
return self[section].as_bool(key)
135
def get_value(self, section, name):
136
# Try [] for the old DEFAULT section.
137
if section == "DEFAULT":
142
return self[section][name]
143
_ConfigObj = ConfigObj
144
return _ConfigObj(*args, **kwargs)
178
147
class Config(object):
214
179
def _get_signing_policy(self):
215
180
"""Template method to override signature creation policy."""
219
def expand_options(self, string, env=None):
220
"""Expand option references in the string in the configuration context.
222
:param string: The string containing option to expand.
224
:param env: An option dict defining additional configuration options or
225
overriding existing ones.
227
:returns: The expanded string.
229
return self._expand_options_in_string(string, env)
231
def _expand_options_in_list(self, slist, env=None, _ref_stack=None):
232
"""Expand options in a list of strings in the configuration context.
234
:param slist: A list of strings.
236
:param env: An option dict defining additional configuration options or
237
overriding existing ones.
239
:param _ref_stack: Private list containing the options being
240
expanded to detect loops.
242
:returns: The flatten list of expanded strings.
244
# expand options in each value separately flattening lists
247
value = self._expand_options_in_string(s, env, _ref_stack)
248
if isinstance(value, list):
254
def _expand_options_in_string(self, string, env=None, _ref_stack=None):
255
"""Expand options in the string in the configuration context.
257
:param string: The string to be expanded.
259
:param env: An option dict defining additional configuration options or
260
overriding existing ones.
262
:param _ref_stack: Private list containing the options being
263
expanded to detect loops.
265
:returns: The expanded string.
268
# Not much to expand there
270
if _ref_stack is None:
271
# What references are currently resolved (to detect loops)
273
if self.option_ref_re is None:
274
# We want to match the most embedded reference first (i.e. for
275
# '{{foo}}' we will get '{foo}',
276
# for '{bar{baz}}' we will get '{baz}'
277
self.option_ref_re = re.compile('({[^{}]+})')
279
# We need to iterate until no more refs appear ({{foo}} will need two
280
# iterations for example).
282
raw_chunks = self.option_ref_re.split(result)
283
if len(raw_chunks) == 1:
284
# Shorcut the trivial case: no refs
288
# Split will isolate refs so that every other chunk is a ref
290
for chunk in raw_chunks:
293
# Keep only non-empty strings (or we get bogus empty
294
# slots when a list value is involved).
299
if name in _ref_stack:
300
raise errors.OptionExpansionLoop(string, _ref_stack)
301
_ref_stack.append(name)
302
value = self._expand_option(name, env, _ref_stack)
304
raise errors.ExpandingUnknownOption(name, string)
305
if isinstance(value, list):
313
# Once a list appears as the result of an expansion, all
314
# callers will get a list result. This allows a consistent
315
# behavior even when some options in the expansion chain
316
# defined as strings (no comma in their value) but their
317
# expanded value is a list.
318
return self._expand_options_in_list(chunks, env, _ref_stack)
320
result = ''.join(chunks)
323
def _expand_option(self, name, env, _ref_stack):
324
if env is not None and name in env:
325
# Special case, values provided in env takes precedence over
329
# FIXME: This is a limited implementation, what we really need is a
330
# way to query the bzr config for the value of an option,
331
# respecting the scope rules (That is, once we implement fallback
332
# configs, getting the option value should restart from the top
333
# config, not the current one) -- vila 20101222
334
value = self.get_user_option(name, expand=False)
335
if isinstance(value, list):
336
value = self._expand_options_in_list(value, env, _ref_stack)
338
value = self._expand_options_in_string(value, env, _ref_stack)
341
182
def _get_user_option(self, option_name):
342
183
"""Template method to provide a user option."""
345
def get_user_option(self, option_name, expand=None):
346
"""Get a generic option - no special process, no default.
348
:param option_name: The queried option.
350
:param expand: Whether options references should be expanded.
352
:returns: The value of the option.
355
expand = _get_expand_default_value()
356
value = self._get_user_option(option_name)
358
if isinstance(value, list):
359
value = self._expand_options_in_list(value)
360
elif isinstance(value, dict):
361
trace.warning('Cannot expand "%s":'
362
' Dicts do not support option expansion'
365
value = self._expand_options_in_string(value)
368
def get_user_option_as_bool(self, option_name, expand=None):
186
def get_user_option(self, option_name):
187
"""Get a generic option - no special process, no default."""
188
return self._get_user_option(option_name)
190
def get_user_option_as_bool(self, option_name):
369
191
"""Get a generic option as a boolean - no special process, no default.
371
193
:return None if the option doesn't exist or its value can't be
372
194
interpreted as a boolean. Returns True or False otherwise.
374
s = self.get_user_option(option_name, expand=expand)
196
s = self._get_user_option(option_name)
376
198
# The option doesn't exist
530
def get_merge_tools(self):
532
for (oname, value, section, conf_id, parser) in self._get_options():
533
if oname.startswith('bzr.mergetool.'):
534
tool_name = oname[len('bzr.mergetool.'):]
535
tools[tool_name] = value
536
trace.mutter('loaded merge tools: %r' % tools)
539
def find_merge_tool(self, name):
540
# We fake a defaults mechanism here by checking if the given name can
541
# be found in the known_merge_tools if it's not found in the config.
542
# This should be done through the proposed config defaults mechanism
543
# when it becomes available in the future.
544
command_line = (self.get_user_option('bzr.mergetool.%s' % name,
546
or mergetools.known_merge_tools.get(name, None))
550
352
class IniBasedConfig(Config):
551
353
"""A configuration policy that draws from ini files."""
553
def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
555
"""Base class for configuration files using an ini-like syntax.
557
:param file_name: The configuration file path.
355
def __init__(self, get_filename):
559
356
super(IniBasedConfig, self).__init__()
560
self.file_name = file_name
561
if symbol_versioning.deprecated_passed(get_filename):
562
symbol_versioning.warn(
563
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
564
' Use file_name instead.',
567
if get_filename is not None:
568
self.file_name = get_filename()
570
self.file_name = file_name
357
self._get_filename = get_filename
572
358
self._parser = None
575
def from_string(cls, str_or_unicode, file_name=None, save=False):
576
"""Create a config object from a string.
578
:param str_or_unicode: A string representing the file content. This will
581
:param file_name: The configuration file path.
583
:param _save: Whether the file should be saved upon creation.
585
conf = cls(file_name=file_name)
586
conf._create_from_string(str_or_unicode, save)
589
def _create_from_string(self, str_or_unicode, save):
590
self._content = StringIO(str_or_unicode.encode('utf-8'))
591
# Some tests use in-memory configs, some other always need the config
592
# file to exist on disk.
594
self._write_config_file()
596
def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
360
def _get_parser(self, file=None):
597
361
if self._parser is not None:
598
362
return self._parser
599
if symbol_versioning.deprecated_passed(file):
600
symbol_versioning.warn(
601
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
602
' Use IniBasedConfig(_content=xxx) instead.',
605
if self._content is not None:
606
co_input = self._content
607
elif self.file_name is None:
608
raise AssertionError('We have no content to create the config')
364
input = self._get_filename()
610
co_input = self.file_name
612
self._parser = ConfigObj(co_input, encoding='utf-8')
368
self._parser = ConfigObj(input, encoding='utf-8')
613
369
except configobj.ConfigObjError, e:
614
370
raise errors.ParseConfigError(e.errors, e.config.filename)
615
# Make sure self.reload() will use the right file name
616
self._parser.filename = self.file_name
617
371
return self._parser
620
"""Reload the config file from disk."""
621
if self.file_name is None:
622
raise AssertionError('We need a file name to reload the config')
623
if self._parser is not None:
624
self._parser.reload()
626
373
def _get_matching_sections(self):
627
374
"""Return an ordered list of (section_name, extra_path) pairs.
639
386
"""Override this to define the section used by the config."""
642
def _get_sections(self, name=None):
643
"""Returns an iterator of the sections specified by ``name``.
645
:param name: The section name. If None is supplied, the default
646
configurations are yielded.
648
:return: A tuple (name, section, config_id) for all sections that will
649
be walked by user_get_option() in the 'right' order. The first one
650
is where set_user_option() will update the value.
652
parser = self._get_parser()
654
yield (name, parser[name], self.config_id())
656
# No section name has been given so we fallback to the configobj
657
# itself which holds the variables defined outside of any section.
658
yield (None, parser, self.config_id())
660
def _get_options(self, sections=None):
661
"""Return an ordered list of (name, value, section, config_id) tuples.
663
All options are returned with their associated value and the section
664
they appeared in. ``config_id`` is a unique identifier for the
665
configuration file the option is defined in.
667
:param sections: Default to ``_get_matching_sections`` if not
668
specified. This gives a better control to daughter classes about
669
which sections should be searched. This is a list of (name,
674
parser = self._get_parser()
676
for (section_name, _) in self._get_matching_sections():
678
section = parser[section_name]
680
# This could happen for an empty file for which we define a
681
# DEFAULT section. FIXME: Force callers to provide sections
682
# instead ? -- vila 20100930
684
sections.append((section_name, section))
685
config_id = self.config_id()
686
for (section_name, section) in sections:
687
for (name, value) in section.iteritems():
688
yield (name, parser._quote(value), section_name,
691
389
def _get_option_policy(self, section, option_name):
692
390
"""Return the policy for the given (section, option_name) pair."""
693
391
return POLICY_NONE
780
478
def _get_nickname(self):
781
479
return self.get_user_option('nickname')
783
def remove_user_option(self, option_name, section_name=None):
784
"""Remove a user option and save the configuration file.
786
:param option_name: The option to be removed.
788
:param section_name: The section the option is defined in, default to
792
parser = self._get_parser()
793
if section_name is None:
796
section = parser[section_name]
798
del section[option_name]
800
raise errors.NoSuchConfigOption(option_name)
801
self._write_config_file()
803
481
def _write_config_file(self):
804
if self.file_name is None:
805
raise AssertionError('We cannot save, self.file_name is None')
806
conf_dir = os.path.dirname(self.file_name)
807
ensure_config_dir_exists(conf_dir)
808
atomic_file = atomicfile.AtomicFile(self.file_name)
482
filename = self._get_filename()
483
atomic_file = atomicfile.AtomicFile(filename)
809
484
self._get_parser().write(atomic_file)
810
485
atomic_file.commit()
811
486
atomic_file.close()
812
osutils.copy_ownership_from_path(self.file_name)
815
class LockableConfig(IniBasedConfig):
816
"""A configuration needing explicit locking for access.
818
If several processes try to write the config file, the accesses need to be
821
Daughter classes should decorate all methods that update a config with the
822
``@needs_write_lock`` decorator (they call, directly or indirectly, the
823
``_write_config_file()`` method. These methods (typically ``set_option()``
824
and variants must reload the config file from disk before calling
825
``_write_config_file()``), this can be achieved by calling the
826
``self.reload()`` method. Note that the lock scope should cover both the
827
reading and the writing of the config file which is why the decorator can't
828
be applied to ``_write_config_file()`` only.
830
This should be enough to implement the following logic:
831
- lock for exclusive write access,
832
- reload the config file from disk,
836
This logic guarantees that a writer can update a value without erasing an
837
update made by another writer.
842
def __init__(self, file_name):
843
super(LockableConfig, self).__init__(file_name=file_name)
844
self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
845
# FIXME: It doesn't matter that we don't provide possible_transports
846
# below since this is currently used only for local config files ;
847
# local transports are not shared. But if/when we start using
848
# LockableConfig for other kind of transports, we will need to reuse
849
# whatever connection is already established -- vila 20100929
850
self.transport = transport.get_transport(self.dir)
851
self._lock = lockdir.LockDir(self.transport, 'lock')
853
def _create_from_string(self, unicode_bytes, save):
854
super(LockableConfig, self)._create_from_string(unicode_bytes, False)
856
# We need to handle the saving here (as opposed to IniBasedConfig)
859
self._write_config_file()
862
def lock_write(self, token=None):
863
"""Takes a write lock in the directory containing the config file.
865
If the directory doesn't exist it is created.
867
ensure_config_dir_exists(self.dir)
868
return self._lock.lock_write(token)
873
def break_lock(self):
874
self._lock.break_lock()
877
def remove_user_option(self, option_name, section_name=None):
878
super(LockableConfig, self).remove_user_option(option_name,
881
def _write_config_file(self):
882
if self._lock is None or not self._lock.is_held:
883
# NB: if the following exception is raised it probably means a
884
# missing @needs_write_lock decorator on one of the callers.
885
raise errors.ObjectNotLocked(self)
886
super(LockableConfig, self)._write_config_file()
889
class GlobalConfig(LockableConfig):
487
osutils.copy_ownership_from_path(filename)
490
class GlobalConfig(IniBasedConfig):
890
491
"""The configuration that should be used for a specific location."""
893
super(GlobalConfig, self).__init__(file_name=config_filename())
899
def from_string(cls, str_or_unicode, save=False):
900
"""Create a config object from a string.
902
:param str_or_unicode: A string representing the file content. This
903
will be utf-8 encoded.
905
:param save: Whether the file should be saved upon creation.
908
conf._create_from_string(str_or_unicode, save)
911
493
def get_editor(self):
912
494
return self._get_user_option('editor')
497
super(GlobalConfig, self).__init__(config_filename)
915
499
def set_user_option(self, option, value):
916
500
"""Save option and its value in the configuration."""
917
501
self._set_option(option, value, 'DEFAULT')
939
520
self._write_config_file()
941
522
def _set_option(self, option, value, section):
523
# FIXME: RBC 20051029 This should refresh the parser and also take a
524
# file lock on bazaar.conf.
525
conf_dir = os.path.dirname(self._get_filename())
526
ensure_config_dir_exists(conf_dir)
943
527
self._get_parser().setdefault(section, {})[option] = value
944
528
self._write_config_file()
947
def _get_sections(self, name=None):
948
"""See IniBasedConfig._get_sections()."""
949
parser = self._get_parser()
950
# We don't give access to options defined outside of any section, we
951
# used the DEFAULT section by... default.
952
if name in (None, 'DEFAULT'):
953
# This could happen for an empty file where the DEFAULT section
954
# doesn't exist yet. So we force DEFAULT when yielding
956
if 'DEFAULT' not in parser:
957
parser['DEFAULT']= {}
958
yield (name, parser[name], self.config_id())
961
def remove_user_option(self, option_name, section_name=None):
962
if section_name is None:
963
# We need to force the default section.
964
section_name = 'DEFAULT'
965
# We need to avoid the LockableConfig implementation or we'll lock
967
super(LockableConfig, self).remove_user_option(option_name,
970
def _iter_for_location_by_parts(sections, location):
971
"""Keep only the sessions matching the specified location.
973
:param sections: An iterable of section names.
975
:param location: An url or a local path to match against.
977
:returns: An iterator of (section, extra_path, nb_parts) where nb is the
978
number of path components in the section name, section is the section
979
name and extra_path is the difference between location and the section
982
location_parts = location.rstrip('/').split('/')
984
for section in sections:
985
# location is a local path if possible, so we need
986
# to convert 'file://' urls to local paths if necessary.
988
# FIXME: I don't think the above comment is still up to date,
989
# LocationConfig is always instantiated with an url -- vila 2011-04-07
991
# This also avoids having file:///path be a more exact
992
# match than '/path'.
994
# FIXME: Not sure about the above either, but since the path components
995
# are compared in sync, adding two empty components (//) is likely to
996
# trick the comparison and also trick the check on the number of
997
# components, so we *should* take only the relevant part of the url. On
998
# the other hand, this means 'file://' urls *can't* be used in sections
999
# so more work is probably needed -- vila 2011-04-07
1001
if section.startswith('file://'):
1002
section_path = urlutils.local_path_from_url(section)
1004
section_path = section
1005
section_parts = section_path.rstrip('/').split('/')
1008
if len(section_parts) > len(location_parts):
1009
# More path components in the section, they can't match
1012
# Rely on zip truncating in length to the length of the shortest
1013
# argument sequence.
1014
names = zip(location_parts, section_parts)
1016
if not fnmatch.fnmatch(name[0], name[1]):
1021
# build the path difference between the section and the location
1022
extra_path = '/'.join(location_parts[len(section_parts):])
1023
yield section, extra_path, len(section_parts)
1026
class LocationConfig(LockableConfig):
531
class LocationConfig(IniBasedConfig):
1027
532
"""A configuration object that gives the policy for a location."""
1029
534
def __init__(self, location):
1030
super(LocationConfig, self).__init__(
1031
file_name=locations_config_filename())
535
name_generator = locations_config_filename
536
if (not os.path.exists(name_generator()) and
537
os.path.exists(branches_config_filename())):
538
if sys.platform == 'win32':
539
trace.warning('Please rename %s to %s'
540
% (branches_config_filename(),
541
locations_config_filename()))
543
trace.warning('Please rename ~/.bazaar/branches.conf'
544
' to ~/.bazaar/locations.conf')
545
name_generator = branches_config_filename
546
super(LocationConfig, self).__init__(name_generator)
1032
547
# local file locations are looked up by local path, rather than
1033
548
# by file url. This is because the config file is a user
1034
549
# file, and we would rather not expose the user to file urls.
1036
551
location = urlutils.local_path_from_url(location)
1037
552
self.location = location
1039
def config_id(self):
1043
def from_string(cls, str_or_unicode, location, save=False):
1044
"""Create a config object from a string.
1046
:param str_or_unicode: A string representing the file content. This will
1049
:param location: The location url to filter the configuration.
1051
:param save: Whether the file should be saved upon creation.
1053
conf = cls(location)
1054
conf._create_from_string(str_or_unicode, save)
1057
554
def _get_matching_sections(self):
1058
555
"""Return an ordered list of section names matching this location."""
1059
matches = list(_iter_for_location_by_parts(self._get_parser(),
1061
# put the longest (aka more specific) locations first
1063
key=lambda (section, extra_path, length): (length, section),
1065
for (section, extra_path, length) in matches:
1066
yield section, extra_path
556
sections = self._get_parser()
557
location_names = self.location.split('/')
558
if self.location.endswith('/'):
559
del location_names[-1]
561
for section in sections:
562
# location is a local path if possible, so we need
563
# to convert 'file://' urls to local paths if necessary.
564
# This also avoids having file:///path be a more exact
565
# match than '/path'.
566
if section.startswith('file://'):
567
section_path = urlutils.local_path_from_url(section)
569
section_path = section
570
section_names = section_path.split('/')
571
if section.endswith('/'):
572
del section_names[-1]
573
names = zip(location_names, section_names)
576
if not fnmatch(name[0], name[1]):
581
# so, for the common prefix they matched.
582
# if section is longer, no match.
583
if len(section_names) > len(location_names):
585
matches.append((len(section_names), section,
586
'/'.join(location_names[len(section_names):])))
587
matches.sort(reverse=True)
589
for (length, section, extra_path) in matches:
590
sections.append((section, extra_path))
1067
591
# should we stop looking for parent configs here?
1069
593
if self._get_parser()[section].as_bool('ignore_parents'):
1071
595
except KeyError:
1074
def _get_sections(self, name=None):
1075
"""See IniBasedConfig._get_sections()."""
1076
# We ignore the name here as the only sections handled are named with
1077
# the location path and we don't expose embedded sections either.
1078
parser = self._get_parser()
1079
for name, extra_path in self._get_matching_sections():
1080
yield (name, parser[name], self.config_id())
1082
599
def _get_option_policy(self, section, option_name):
1083
600
"""Return the policy for the given (section, option_name) pair."""
1135
651
STORE_LOCATION_APPENDPATH]:
1136
652
raise ValueError('bad storage policy %r for %r' %
1137
653
(store, option))
654
# FIXME: RBC 20051029 This should refresh the parser and also take a
655
# file lock on locations.conf.
656
conf_dir = os.path.dirname(self._get_filename())
657
ensure_config_dir_exists(conf_dir)
1139
658
location = self.location
1140
659
if location.endswith('/'):
1141
660
location = location[:-1]
1142
parser = self._get_parser()
1143
if not location in parser and not location + '/' in parser:
1144
parser[location] = {}
1145
elif location + '/' in parser:
661
if (not location in self._get_parser() and
662
not location + '/' in self._get_parser()):
663
self._get_parser()[location]={}
664
elif location + '/' in self._get_parser():
1146
665
location = location + '/'
1147
parser[location][option]=value
666
self._get_parser()[location][option]=value
1148
667
# the allowed values of store match the config policies
1149
668
self._set_option_policy(location, option, store)
1150
669
self._write_config_file()
1246
def _get_sections(self, name=None):
1247
"""See IniBasedConfig.get_sections()."""
1248
for source in self.option_sources:
1249
for section in source()._get_sections(name):
1252
def _get_options(self, sections=None):
1254
# First the locations options
1255
for option in self._get_location_config()._get_options():
1257
# Then the branch options
1258
branch_config = self._get_branch_data_config()
1259
if sections is None:
1260
sections = [('DEFAULT', branch_config._get_parser())]
1261
# FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
1262
# Config itself has no notion of sections :( -- vila 20101001
1263
config_id = self.config_id()
1264
for (section_name, section) in sections:
1265
for (name, value) in section.iteritems():
1266
yield (name, value, section_name,
1267
config_id, branch_config._get_parser())
1268
# Then the global options
1269
for option in self._get_global_config()._get_options():
1272
751
def set_user_option(self, name, value, store=STORE_BRANCH,
1273
752
warn_masked=False):
1274
753
if store == STORE_BRANCH:
1343
829
def config_dir():
1344
830
"""Return per-user configuration directory.
1346
By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1347
and Linux. On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1348
that will be used instead.
832
By default this is ~/.bazaar/
1350
834
TODO: Global option --config-dir to override this.
1352
836
base = os.environ.get('BZR_HOME', None)
1353
837
if sys.platform == 'win32':
1354
# environ variables on Windows are in user encoding/mbcs. So decode
1356
if base is not None:
1357
base = base.decode('mbcs')
1358
838
if base is None:
1359
839
base = win32utils.get_appdata_location_unicode()
1360
840
if base is None:
1361
841
base = os.environ.get('HOME', None)
1362
if base is not None:
1363
base = base.decode('mbcs')
1364
842
if base is None:
1365
843
raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1367
845
return osutils.pathjoin(base, 'bazaar', '2.0')
1368
elif sys.platform == 'darwin':
1370
# this takes into account $HOME
1371
base = os.path.expanduser("~")
1372
return osutils.pathjoin(base, '.bazaar')
1374
847
if base is None:
1376
xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1378
xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1379
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1380
if osutils.isdir(xdg_dir):
1382
"Using configuration in XDG directory %s." % xdg_dir)
1385
848
base = os.path.expanduser("~")
1386
849
return osutils.pathjoin(base, ".bazaar")
1433
901
return os.path.expanduser('~/.cache')
1436
def _get_default_mail_domain():
1437
"""If possible, return the assumed default email domain.
1439
:returns: string mail domain, or None.
1441
if sys.platform == 'win32':
1442
# No implementation yet; patches welcome
1445
f = open('/etc/mailname')
1446
except (IOError, OSError), e:
1449
domain = f.read().strip()
1455
def _auto_user_id():
1456
"""Calculate automatic user identification.
1458
:returns: (realname, email), either of which may be None if they can't be
1461
Only used when none is set in the environment or the id file.
1463
This only returns an email address if we can be fairly sure the
1464
address is reasonable, ie if /etc/mailname is set on unix.
1466
This doesn't use the FQDN as the default domain because that may be
1467
slow, and it doesn't use the hostname alone because that's not normally
1468
a reasonable address.
1470
if sys.platform == 'win32':
1471
# No implementation to reliably determine Windows default mail
1472
# address; please add one.
1475
default_mail_domain = _get_default_mail_domain()
1476
if not default_mail_domain:
1482
w = pwd.getpwuid(uid)
1484
mutter('no passwd entry for uid %d?' % uid)
1487
# we try utf-8 first, because on many variants (like Linux),
1488
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
1489
# false positives. (many users will have their user encoding set to
1490
# latin-1, which cannot raise UnicodeError.)
1492
gecos = w.pw_gecos.decode('utf-8')
1494
except UnicodeError:
1496
encoding = osutils.get_user_encoding()
1497
gecos = w.pw_gecos.decode(encoding)
1498
except UnicodeError, e:
1499
mutter("cannot decode passwd entry %s" % w)
1502
username = w.pw_name.decode(encoding)
1503
except UnicodeError, e:
1504
mutter("cannot decode passwd entry %s" % w)
1507
comma = gecos.find(',')
1511
realname = gecos[:comma]
1513
return realname, (username + '@' + default_mail_domain)
1516
904
def parse_username(username):
1517
905
"""Parse e-mail username and return a (name, address) tuple."""
1518
906
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
2092
1461
configobj.write(out_file)
2093
1462
out_file.seek(0)
2094
1463
self._transport.put_file(self._filename, out_file)
2097
class cmd_config(commands.Command):
2098
__doc__ = """Display, set or remove a configuration option.
2100
Display the active value for a given option.
2102
If --all is specified, NAME is interpreted as a regular expression and all
2103
matching options are displayed mentioning their scope. The active value
2104
that bzr will take into account is the first one displayed for each option.
2106
If no NAME is given, --all .* is implied.
2108
Setting a value is achieved by using name=value without spaces. The value
2109
is set in the most relevant scope and can be checked by displaying the
2113
takes_args = ['name?']
2117
# FIXME: This should be a registry option so that plugins can register
2118
# their own config files (or not) -- vila 20101002
2119
commands.Option('scope', help='Reduce the scope to the specified'
2120
' configuration file',
2122
commands.Option('all',
2123
help='Display all the defined values for the matching options.',
2125
commands.Option('remove', help='Remove the option from'
2126
' the configuration file'),
2129
@commands.display_command
2130
def run(self, name=None, all=False, directory=None, scope=None,
2132
if directory is None:
2134
directory = urlutils.normalize_url(directory)
2136
raise errors.BzrError(
2137
'--all and --remove are mutually exclusive.')
2139
# Delete the option in the given scope
2140
self._remove_config_option(name, directory, scope)
2142
# Defaults to all options
2143
self._show_matching_options('.*', directory, scope)
2146
name, value = name.split('=', 1)
2148
# Display the option(s) value(s)
2150
self._show_matching_options(name, directory, scope)
2152
self._show_value(name, directory, scope)
2155
raise errors.BzrError(
2156
'Only one option can be set.')
2157
# Set the option value
2158
self._set_config_option(name, value, directory, scope)
2160
def _get_configs(self, directory, scope=None):
2161
"""Iterate the configurations specified by ``directory`` and ``scope``.
2163
:param directory: Where the configurations are derived from.
2165
:param scope: A specific config to start from.
2167
if scope is not None:
2168
if scope == 'bazaar':
2169
yield GlobalConfig()
2170
elif scope == 'locations':
2171
yield LocationConfig(directory)
2172
elif scope == 'branch':
2173
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2175
yield br.get_config()
2178
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2180
yield br.get_config()
2181
except errors.NotBranchError:
2182
yield LocationConfig(directory)
2183
yield GlobalConfig()
2185
def _show_value(self, name, directory, scope):
2187
for c in self._get_configs(directory, scope):
2190
for (oname, value, section, conf_id, parser) in c._get_options():
2192
# Display only the first value and exit
2194
# FIXME: We need to use get_user_option to take policies
2195
# into account and we need to make sure the option exists
2196
# too (hence the two for loops), this needs a better API
2198
value = c.get_user_option(name)
2199
# Quote the value appropriately
2200
value = parser._quote(value)
2201
self.outf.write('%s\n' % (value,))
2205
raise errors.NoSuchConfigOption(name)
2207
def _show_matching_options(self, name, directory, scope):
2208
name = re.compile(name)
2209
# We want any error in the regexp to be raised *now* so we need to
2210
# avoid the delay introduced by the lazy regexp.
2211
name._compile_and_collapse()
2214
for c in self._get_configs(directory, scope):
2215
for (oname, value, section, conf_id, parser) in c._get_options():
2216
if name.search(oname):
2217
if cur_conf_id != conf_id:
2218
# Explain where the options are defined
2219
self.outf.write('%s:\n' % (conf_id,))
2220
cur_conf_id = conf_id
2222
if (section not in (None, 'DEFAULT')
2223
and cur_section != section):
2224
# Display the section if it's not the default (or only)
2226
self.outf.write(' [%s]\n' % (section,))
2227
cur_section = section
2228
self.outf.write(' %s = %s\n' % (oname, value))
2230
def _set_config_option(self, name, value, directory, scope):
2231
for conf in self._get_configs(directory, scope):
2232
conf.set_user_option(name, value)
2235
raise errors.NoSuchConfig(scope)
2237
def _remove_config_option(self, name, directory, scope):
2239
raise errors.BzrCommandError(
2240
'--remove expects an option to remove.')
2242
for conf in self._get_configs(directory, scope):
2243
for (section_name, section, conf_id) in conf._get_sections():
2244
if scope is not None and conf_id != scope:
2245
# Not the right configuration file
2248
if conf_id != conf.config_id():
2249
conf = self._get_configs(directory, conf_id).next()
2250
# We use the first section in the first config where the
2251
# option is defined to remove it
2252
conf.remove_user_option(name, section_name)
2257
raise errors.NoSuchConfig(scope)
2259
raise errors.NoSuchConfigOption(name)