361
351
class IniBasedConfig(Config):
362
352
"""A configuration policy that draws from ini files."""
364
def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
366
"""Base class for configuration files using an ini-like syntax.
368
:param file_name: The configuration file path.
354
def __init__(self, get_filename):
370
355
super(IniBasedConfig, self).__init__()
371
self.file_name = file_name
372
if symbol_versioning.deprecated_passed(get_filename):
373
symbol_versioning.warn(
374
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
375
' Use file_name instead.',
378
if get_filename is not None:
379
self.file_name = get_filename()
381
self.file_name = file_name
356
self._get_filename = get_filename
383
357
self._parser = None
386
def from_string(cls, str_or_unicode, file_name=None, save=False):
387
"""Create a config object from a string.
389
:param str_or_unicode: A string representing the file content. This will
392
:param file_name: The configuration file path.
394
:param _save: Whether the file should be saved upon creation.
396
conf = cls(file_name=file_name)
397
conf._create_from_string(str_or_unicode, save)
400
def _create_from_string(self, str_or_unicode, save):
401
self._content = StringIO(str_or_unicode.encode('utf-8'))
402
# Some tests use in-memory configs, some other always need the config
403
# file to exist on disk.
405
self._write_config_file()
407
def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
def _get_parser(self, file=None):
408
360
if self._parser is not None:
409
361
return self._parser
410
if symbol_versioning.deprecated_passed(file):
411
symbol_versioning.warn(
412
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
413
' Use IniBasedConfig(_content=xxx) instead.',
416
if self._content is not None:
417
co_input = self._content
418
elif self.file_name is None:
419
raise AssertionError('We have no content to create the config')
363
input = self._get_filename()
421
co_input = self.file_name
423
self._parser = ConfigObj(co_input, encoding='utf-8')
367
self._parser = ConfigObj(input, encoding='utf-8')
424
368
except configobj.ConfigObjError, e:
425
369
raise errors.ParseConfigError(e.errors, e.config.filename)
426
# Make sure self.reload() will use the right file name
427
self._parser.filename = self.file_name
428
370
return self._parser
431
"""Reload the config file from disk."""
432
if self.file_name is None:
433
raise AssertionError('We need a file name to reload the config')
434
if self._parser is not None:
435
self._parser.reload()
437
372
def _get_matching_sections(self):
438
373
"""Return an ordered list of (section_name, extra_path) pairs.
450
385
"""Override this to define the section used by the config."""
453
def _get_sections(self, name=None):
454
"""Returns an iterator of the sections specified by ``name``.
456
:param name: The section name. If None is supplied, the default
457
configurations are yielded.
459
:return: A tuple (name, section, config_id) for all sections that will
460
be walked by user_get_option() in the 'right' order. The first one
461
is where set_user_option() will update the value.
463
parser = self._get_parser()
465
yield (name, parser[name], self.config_id())
467
# No section name has been given so we fallback to the configobj
468
# itself which holds the variables defined outside of any section.
469
yield (None, parser, self.config_id())
471
def _get_options(self, sections=None):
472
"""Return an ordered list of (name, value, section, config_id) tuples.
474
All options are returned with their associated value and the section
475
they appeared in. ``config_id`` is a unique identifier for the
476
configuration file the option is defined in.
478
:param sections: Default to ``_get_matching_sections`` if not
479
specified. This gives a better control to daughter classes about
480
which sections should be searched. This is a list of (name,
485
parser = self._get_parser()
487
for (section_name, _) in self._get_matching_sections():
489
section = parser[section_name]
491
# This could happen for an empty file for which we define a
492
# DEFAULT section. FIXME: Force callers to provide sections
493
# instead ? -- vila 20100930
495
sections.append((section_name, section))
496
config_id = self.config_id()
497
for (section_name, section) in sections:
498
for (name, value) in section.iteritems():
499
yield (name, value, section_name, config_id)
501
388
def _get_option_policy(self, section, option_name):
502
389
"""Return the policy for the given (section, option_name) pair."""
503
390
return POLICY_NONE
590
477
def _get_nickname(self):
591
478
return self.get_user_option('nickname')
593
def remove_user_option(self, option_name, section_name=None):
594
"""Remove a user option and save the configuration file.
596
:param option_name: The option to be removed.
598
:param section_name: The section the option is defined in, default to
602
parser = self._get_parser()
603
if section_name is None:
606
section = parser[section_name]
480
def _write_config_file(self):
481
f = file(self._get_filename(), "wb")
608
del section[option_name]
610
raise errors.NoSuchConfigOption(option_name)
611
self._write_config_file()
613
def _write_config_file(self):
614
if self.file_name is None:
615
raise AssertionError('We cannot save, self.file_name is None')
616
conf_dir = os.path.dirname(self.file_name)
617
ensure_config_dir_exists(conf_dir)
618
atomic_file = atomicfile.AtomicFile(self.file_name)
619
self._get_parser().write(atomic_file)
622
osutils.copy_ownership_from_path(self.file_name)
625
class LockableConfig(IniBasedConfig):
626
"""A configuration needing explicit locking for access.
628
If several processes try to write the config file, the accesses need to be
631
Daughter classes should decorate all methods that update a config with the
632
``@needs_write_lock`` decorator (they call, directly or indirectly, the
633
``_write_config_file()`` method. These methods (typically ``set_option()``
634
and variants must reload the config file from disk before calling
635
``_write_config_file()``), this can be achieved by calling the
636
``self.reload()`` method. Note that the lock scope should cover both the
637
reading and the writing of the config file which is why the decorator can't
638
be applied to ``_write_config_file()`` only.
640
This should be enough to implement the following logic:
641
- lock for exclusive write access,
642
- reload the config file from disk,
646
This logic guarantees that a writer can update a value without erasing an
647
update made by another writer.
652
def __init__(self, file_name):
653
super(LockableConfig, self).__init__(file_name=file_name)
654
self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
655
self.transport = transport.get_transport(self.dir)
656
self._lock = lockdir.LockDir(self.transport, 'lock')
658
def _create_from_string(self, unicode_bytes, save):
659
super(LockableConfig, self)._create_from_string(unicode_bytes, False)
661
# We need to handle the saving here (as opposed to IniBasedConfig)
664
self._write_config_file()
667
def lock_write(self, token=None):
668
"""Takes a write lock in the directory containing the config file.
670
If the directory doesn't exist it is created.
672
ensure_config_dir_exists(self.dir)
673
return self._lock.lock_write(token)
678
def break_lock(self):
679
self._lock.break_lock()
682
def remove_user_option(self, option_name, section_name=None):
683
super(LockableConfig, self).remove_user_option(option_name,
686
def _write_config_file(self):
687
if self._lock is None or not self._lock.is_held:
688
# NB: if the following exception is raised it probably means a
689
# missing @needs_write_lock decorator on one of the callers.
690
raise errors.ObjectNotLocked(self)
691
super(LockableConfig, self)._write_config_file()
694
class GlobalConfig(LockableConfig):
483
osutils.copy_ownership_from_path(f.name)
484
self._get_parser().write(f)
489
class GlobalConfig(IniBasedConfig):
695
490
"""The configuration that should be used for a specific location."""
698
super(GlobalConfig, self).__init__(file_name=config_filename())
704
def from_string(cls, str_or_unicode, save=False):
705
"""Create a config object from a string.
707
:param str_or_unicode: A string representing the file content. This
708
will be utf-8 encoded.
710
:param save: Whether the file should be saved upon creation.
713
conf._create_from_string(str_or_unicode, save)
716
492
def get_editor(self):
717
493
return self._get_user_option('editor')
496
super(GlobalConfig, self).__init__(config_filename)
720
498
def set_user_option(self, option, value):
721
499
"""Save option and its value in the configuration."""
722
500
self._set_option(option, value, 'DEFAULT')
744
519
self._write_config_file()
746
521
def _set_option(self, option, value, section):
522
# FIXME: RBC 20051029 This should refresh the parser and also take a
523
# file lock on bazaar.conf.
524
conf_dir = os.path.dirname(self._get_filename())
525
ensure_config_dir_exists(conf_dir)
748
526
self._get_parser().setdefault(section, {})[option] = value
749
527
self._write_config_file()
752
def _get_sections(self, name=None):
753
"""See IniBasedConfig._get_sections()."""
754
parser = self._get_parser()
755
# We don't give access to options defined outside of any section, we
756
# used the DEFAULT section by... default.
757
if name in (None, 'DEFAULT'):
758
# This could happen for an empty file where the DEFAULT section
759
# doesn't exist yet. So we force DEFAULT when yielding
761
if 'DEFAULT' not in parser:
762
parser['DEFAULT']= {}
763
yield (name, parser[name], self.config_id())
766
def remove_user_option(self, option_name, section_name=None):
767
if section_name is None:
768
# We need to force the default section.
769
section_name = 'DEFAULT'
770
# We need to avoid the LockableConfig implementation or we'll lock
772
super(LockableConfig, self).remove_user_option(option_name,
776
class LocationConfig(LockableConfig):
530
class LocationConfig(IniBasedConfig):
777
531
"""A configuration object that gives the policy for a location."""
779
533
def __init__(self, location):
780
super(LocationConfig, self).__init__(
781
file_name=locations_config_filename())
534
name_generator = locations_config_filename
535
if (not os.path.exists(name_generator()) and
536
os.path.exists(branches_config_filename())):
537
if sys.platform == 'win32':
538
trace.warning('Please rename %s to %s'
539
% (branches_config_filename(),
540
locations_config_filename()))
542
trace.warning('Please rename ~/.bazaar/branches.conf'
543
' to ~/.bazaar/locations.conf')
544
name_generator = branches_config_filename
545
super(LocationConfig, self).__init__(name_generator)
782
546
# local file locations are looked up by local path, rather than
783
547
# by file url. This is because the config file is a user
784
548
# file, and we would rather not expose the user to file urls.
914
650
STORE_LOCATION_APPENDPATH]:
915
651
raise ValueError('bad storage policy %r for %r' %
653
# FIXME: RBC 20051029 This should refresh the parser and also take a
654
# file lock on locations.conf.
655
conf_dir = os.path.dirname(self._get_filename())
656
ensure_config_dir_exists(conf_dir)
918
657
location = self.location
919
658
if location.endswith('/'):
920
659
location = location[:-1]
921
parser = self._get_parser()
922
if not location in parser and not location + '/' in parser:
923
parser[location] = {}
924
elif location + '/' in parser:
660
if (not location in self._get_parser() and
661
not location + '/' in self._get_parser()):
662
self._get_parser()[location]={}
663
elif location + '/' in self._get_parser():
925
664
location = location + '/'
926
parser[location][option]=value
665
self._get_parser()[location][option]=value
927
666
# the allowed values of store match the config policies
928
667
self._set_option_policy(location, option, store)
929
668
self._write_config_file()
932
671
class BranchConfig(Config):
933
672
"""A configuration object giving the policy for a branch."""
935
def __init__(self, branch):
936
super(BranchConfig, self).__init__()
937
self._location_config = None
938
self._branch_data_config = None
939
self._global_config = None
941
self.option_sources = (self._get_location_config,
942
self._get_branch_data_config,
943
self._get_global_config)
948
674
def _get_branch_data_config(self):
949
675
if self._branch_data_config is None:
950
676
self._branch_data_config = TreeConfig(self.branch)
951
self._branch_data_config.config_id = self.config_id
952
677
return self._branch_data_config
954
679
def _get_location_config(self):
1025
def _get_sections(self, name=None):
1026
"""See IniBasedConfig.get_sections()."""
1027
for source in self.option_sources:
1028
for section in source()._get_sections(name):
1031
def _get_options(self, sections=None):
1033
# First the locations options
1034
for option in self._get_location_config()._get_options():
1036
# Then the branch options
1037
branch_config = self._get_branch_data_config()
1038
if sections is None:
1039
sections = [('DEFAULT', branch_config._get_parser())]
1040
# FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
1041
# Config itself has no notion of sections :( -- vila 20101001
1042
config_id = self.config_id()
1043
for (section_name, section) in sections:
1044
for (name, value) in section.iteritems():
1045
yield (name, value, section_name, config_id)
1046
# Then the global options
1047
for option in self._get_global_config()._get_options():
1050
750
def set_user_option(self, name, value, store=STORE_BRANCH,
1051
751
warn_masked=False):
1052
752
if store == STORE_BRANCH:
1070
770
trace.warning('Value "%s" is masked by "%s" from'
1071
771
' branch.conf', value, mask_value)
1073
def remove_user_option(self, option_name, section_name=None):
1074
self._get_branch_data_config().remove_option(option_name, section_name)
1076
773
def _gpg_signing_command(self):
1077
774
"""See Config.gpg_signing_command."""
1078
775
return self._get_safe_value('_gpg_signing_command')
777
def __init__(self, branch):
778
super(BranchConfig, self).__init__()
779
self._location_config = None
780
self._branch_data_config = None
781
self._global_config = None
783
self.option_sources = (self._get_location_config,
784
self._get_branch_data_config,
785
self._get_global_config)
1080
787
def _post_commit(self):
1081
788
"""See Config.post_commit."""
1082
789
return self._get_safe_value('_post_commit')
1237
949
def set_option(self, value, name, section=None):
1238
950
"""Set a per-branch configuration option"""
1239
# FIXME: We shouldn't need to lock explicitly here but rather rely on
1240
# higher levels providing the right lock -- vila 20101004
1241
951
self.branch.lock_write()
1243
953
self._config.set_option(value, name, section)
1245
955
self.branch.unlock()
1247
def remove_option(self, option_name, section_name=None):
1248
# FIXME: We shouldn't need to lock explicitly here but rather rely on
1249
# higher levels providing the right lock -- vila 20101004
1250
self.branch.lock_write()
1252
self._config.remove_option(option_name, section_name)
1254
self.branch.unlock()
1257
958
class AuthenticationConfig(object):
1258
959
"""The authentication configuration file based on a ini file.
1767
1460
configobj.write(out_file)
1768
1461
out_file.seek(0)
1769
1462
self._transport.put_file(self._filename, out_file)
1772
class cmd_config(commands.Command):
1773
__doc__ = """Display, set or remove a configuration option.
1775
Display the MATCHING configuration options mentioning their scope (the
1776
configuration file they are defined in). The active value that bzr will
1777
take into account is the first one displayed.
1779
Setting a value is achieved by using name=value without spaces. The value
1780
is set in the most relevant scope and can be checked by displaying the
1785
takes_args = ['matching?']
1789
# FIXME: This should be a registry option so that plugins can register
1790
# their own config files (or not) -- vila 20101002
1791
commands.Option('scope', help='Reduce the scope to the specified'
1792
' configuration file',
1794
commands.Option('remove', help='Remove the option from'
1795
' the configuration file'),
1798
@commands.display_command
1799
def run(self, matching=None, directory=None, scope=None, remove=False):
1800
if directory is None:
1802
directory = urlutils.normalize_url(directory)
1803
if matching is None:
1804
self._show_config('*', directory)
1807
self._remove_config_option(matching, directory, scope)
1809
pos = matching.find('=')
1811
self._show_config(matching, directory)
1813
self._set_config_option(matching[:pos], matching[pos+1:],
1816
def _get_configs(self, directory, scope=None):
1817
"""Iterate the configurations specified by ``directory`` and ``scope``.
1819
:param directory: Where the configurations are derived from.
1821
:param scope: A specific config to start from.
1823
if scope is not None:
1824
if scope == 'bazaar':
1825
yield GlobalConfig()
1826
elif scope == 'locations':
1827
yield LocationConfig(directory)
1828
elif scope == 'branch':
1829
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
1831
yield br.get_config()
1834
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
1836
yield br.get_config()
1837
except errors.NotBranchError:
1838
yield LocationConfig(directory)
1839
yield GlobalConfig()
1841
def _show_config(self, matching, directory):
1842
# Turn the glob into a regexp
1843
matching_re = re.compile(fnmatch.translate(matching))
1845
for c in self._get_configs(directory):
1846
for (name, value, section, conf_id) in c._get_options():
1847
if matching_re.search(name):
1848
if cur_conf_id != conf_id:
1849
self.outf.write('%s:\n' % (conf_id,))
1850
cur_conf_id = conf_id
1851
self.outf.write(' %s = %s\n' % (name, value))
1853
def _set_config_option(self, name, value, directory, scope):
1854
for conf in self._get_configs(directory, scope):
1855
conf.set_user_option(name, value)
1858
raise errors.NoSuchConfig(scope)
1860
def _remove_config_option(self, name, directory, scope):
1862
for conf in self._get_configs(directory, scope):
1863
for (section_name, section, conf_id) in conf._get_sections():
1864
if scope is not None and conf_id != scope:
1865
# Not the right configuration file
1868
if conf_id != conf.config_id():
1869
conf = self._get_configs(directory, conf_id).next()
1870
# We use the first section in the first config where the
1871
# option is defined to remove it
1872
conf.remove_user_option(name, section_name)
1877
raise errors.NoSuchConfig(scope)
1879
raise errors.NoSuchConfigOption(name)