355
342
class IniBasedConfig(Config):
356
343
"""A configuration policy that draws from ini files."""
358
def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
360
"""Base class for configuration files using an ini-like syntax.
362
:param file_name: The configuration file path.
345
def __init__(self, get_filename):
364
346
super(IniBasedConfig, self).__init__()
365
self.file_name = file_name
366
if symbol_versioning.deprecated_passed(get_filename):
367
symbol_versioning.warn(
368
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
369
' Use file_name instead.',
372
if get_filename is not None:
373
self.file_name = get_filename()
375
self.file_name = file_name
347
self._get_filename = get_filename
377
348
self._parser = None
380
def from_string(cls, str_or_unicode, file_name=None, save=False):
381
"""Create a config object from a string.
383
:param str_or_unicode: A string representing the file content. This will
386
:param file_name: The configuration file path.
388
:param _save: Whether the file should be saved upon creation.
390
conf = cls(file_name=file_name)
391
conf._create_from_string(str_or_unicode, save)
394
def _create_from_string(self, str_or_unicode, save):
395
self._content = StringIO(str_or_unicode.encode('utf-8'))
396
# Some tests use in-memory configs, some other always need the config
397
# file to exist on disk.
399
self._write_config_file()
401
def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
350
def _get_parser(self, file=None):
402
351
if self._parser is not None:
403
352
return self._parser
404
if symbol_versioning.deprecated_passed(file):
405
symbol_versioning.warn(
406
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
407
' Use IniBasedConfig(_content=xxx) instead.',
410
if self._content is not None:
411
co_input = self._content
412
elif self.file_name is None:
413
raise AssertionError('We have no content to create the config')
354
input = self._get_filename()
415
co_input = self.file_name
417
self._parser = ConfigObj(co_input, encoding='utf-8')
358
self._parser = ConfigObj(input, encoding='utf-8')
418
359
except configobj.ConfigObjError, e:
419
360
raise errors.ParseConfigError(e.errors, e.config.filename)
420
# Make sure self.reload() will use the right file name
421
self._parser.filename = self.file_name
422
361
return self._parser
425
"""Reload the config file from disk."""
426
if self.file_name is None:
427
raise AssertionError('We need a file name to reload the config')
428
if self._parser is not None:
429
self._parser.reload()
431
363
def _get_matching_sections(self):
432
364
"""Return an ordered list of (section_name, extra_path) pairs.
536
468
def _get_nickname(self):
537
469
return self.get_user_option('nickname')
539
def _write_config_file(self):
540
if self.file_name is None:
541
raise AssertionError('We cannot save, self.file_name is None')
542
conf_dir = os.path.dirname(self.file_name)
543
ensure_config_dir_exists(conf_dir)
544
atomic_file = atomicfile.AtomicFile(self.file_name)
545
self._get_parser().write(atomic_file)
548
osutils.copy_ownership_from_path(self.file_name)
551
class LockableConfig(IniBasedConfig):
552
"""A configuration needing explicit locking for access.
554
If several processes try to write the config file, the accesses need to be
557
Daughter classes should decorate all methods that update a config with the
558
``@needs_write_lock`` decorator (they call, directly or indirectly, the
559
``_write_config_file()`` method. These methods (typically ``set_option()``
560
and variants must reload the config file from disk before calling
561
``_write_config_file()``), this can be achieved by calling the
562
``self.reload()`` method. Note that the lock scope should cover both the
563
reading and the writing of the config file which is why the decorator can't
564
be applied to ``_write_config_file()`` only.
566
This should be enough to implement the following logic:
567
- lock for exclusive write access,
568
- reload the config file from disk,
572
This logic guarantees that a writer can update a value without erasing an
573
update made by another writer.
578
def __init__(self, file_name):
579
super(LockableConfig, self).__init__(file_name=file_name)
580
self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
581
self.transport = transport.get_transport(self.dir)
582
self._lock = lockdir.LockDir(self.transport, 'lock')
584
def _create_from_string(self, unicode_bytes, save):
585
super(LockableConfig, self)._create_from_string(unicode_bytes, False)
587
# We need to handle the saving here (as opposed to IniBasedConfig)
590
self._write_config_file()
593
def lock_write(self, token=None):
594
"""Takes a write lock in the directory containing the config file.
596
If the directory doesn't exist it is created.
598
ensure_config_dir_exists(self.dir)
599
return self._lock.lock_write(token)
604
def break_lock(self):
605
self._lock.break_lock()
607
def _write_config_file(self):
608
if self._lock is None or not self._lock.is_held:
609
# NB: if the following exception is raised it probably means a
610
# missing @needs_write_lock decorator on one of the callers.
611
raise errors.ObjectNotLocked(self)
612
super(LockableConfig, self)._write_config_file()
615
class GlobalConfig(LockableConfig):
472
class GlobalConfig(IniBasedConfig):
616
473
"""The configuration that should be used for a specific location."""
619
super(GlobalConfig, self).__init__(file_name=config_filename())
622
def from_string(cls, str_or_unicode, save=False):
623
"""Create a config object from a string.
625
:param str_or_unicode: A string representing the file content. This
626
will be utf-8 encoded.
628
:param save: Whether the file should be saved upon creation.
631
conf._create_from_string(str_or_unicode, save)
634
475
def get_editor(self):
635
476
return self._get_user_option('editor')
479
super(GlobalConfig, self).__init__(config_filename)
638
481
def set_user_option(self, option, value):
639
482
"""Save option and its value in the configuration."""
640
483
self._set_option(option, value, 'DEFAULT')
662
502
self._write_config_file()
664
504
def _set_option(self, option, value, section):
505
# FIXME: RBC 20051029 This should refresh the parser and also take a
506
# file lock on bazaar.conf.
507
conf_dir = os.path.dirname(self._get_filename())
508
ensure_config_dir_exists(conf_dir)
666
509
self._get_parser().setdefault(section, {})[option] = value
667
510
self._write_config_file()
670
class LocationConfig(LockableConfig):
512
def _write_config_file(self):
513
path = self._get_filename()
514
f = osutils.open_with_ownership(path, 'wb')
515
self._get_parser().write(f)
519
class LocationConfig(IniBasedConfig):
671
520
"""A configuration object that gives the policy for a location."""
673
522
def __init__(self, location):
674
super(LocationConfig, self).__init__(
675
file_name=locations_config_filename())
523
name_generator = locations_config_filename
524
if (not os.path.exists(name_generator()) and
525
os.path.exists(branches_config_filename())):
526
if sys.platform == 'win32':
527
trace.warning('Please rename %s to %s'
528
% (branches_config_filename(),
529
locations_config_filename()))
531
trace.warning('Please rename ~/.bazaar/branches.conf'
532
' to ~/.bazaar/locations.conf')
533
name_generator = branches_config_filename
534
super(LocationConfig, self).__init__(name_generator)
676
535
# local file locations are looked up by local path, rather than
677
536
# by file url. This is because the config file is a user
678
537
# file, and we would rather not expose the user to file urls.
680
539
location = urlutils.local_path_from_url(location)
681
540
self.location = location
684
def from_string(cls, str_or_unicode, location, save=False):
685
"""Create a config object from a string.
687
:param str_or_unicode: A string representing the file content. This will
690
:param location: The location url to filter the configuration.
692
:param save: Whether the file should be saved upon creation.
695
conf._create_from_string(str_or_unicode, save)
698
542
def _get_matching_sections(self):
699
543
"""Return an ordered list of section names matching this location."""
700
544
sections = self._get_parser()
796
639
STORE_LOCATION_APPENDPATH]:
797
640
raise ValueError('bad storage policy %r for %r' %
642
# FIXME: RBC 20051029 This should refresh the parser and also take a
643
# file lock on locations.conf.
644
conf_dir = os.path.dirname(self._get_filename())
645
ensure_config_dir_exists(conf_dir)
800
646
location = self.location
801
647
if location.endswith('/'):
802
648
location = location[:-1]
803
parser = self._get_parser()
804
if not location in parser and not location + '/' in parser:
805
parser[location] = {}
806
elif location + '/' in parser:
649
if (not location in self._get_parser() and
650
not location + '/' in self._get_parser()):
651
self._get_parser()[location]={}
652
elif location + '/' in self._get_parser():
807
653
location = location + '/'
808
parser[location][option]=value
654
self._get_parser()[location][option]=value
809
655
# the allowed values of store match the config policies
810
656
self._set_option_policy(location, option, store)
811
self._write_config_file()
657
self._get_parser().write(file(self._get_filename(), 'wb'))
814
660
class BranchConfig(Config):
815
661
"""A configuration object giving the policy for a branch."""
817
def __init__(self, branch):
818
super(BranchConfig, self).__init__()
819
self._location_config = None
820
self._branch_data_config = None
821
self._global_config = None
823
self.option_sources = (self._get_location_config,
824
self._get_branch_data_config,
825
self._get_global_config)
827
663
def _get_branch_data_config(self):
828
664
if self._branch_data_config is None:
829
665
self._branch_data_config = TreeConfig(self.branch)
927
763
"""See Config.gpg_signing_command."""
928
764
return self._get_safe_value('_gpg_signing_command')
766
def __init__(self, branch):
767
super(BranchConfig, self).__init__()
768
self._location_config = None
769
self._branch_data_config = None
770
self._global_config = None
772
self.option_sources = (self._get_location_config,
773
self._get_branch_data_config,
774
self._get_global_config)
930
776
def _post_commit(self):
931
777
"""See Config.post_commit."""
932
778
return self._get_safe_value('_post_commit')
1038
889
return os.path.expanduser('~/.cache')
893
"""Calculate automatic user identification.
895
Returns (realname, email).
897
Only used when none is set in the environment or the id file.
899
This previously used the FQDN as the default domain, but that can
900
be very slow on machines where DNS is broken. So now we simply
905
if sys.platform == 'win32':
906
name = win32utils.get_user_name_unicode()
908
raise errors.BzrError("Cannot autodetect user name.\n"
909
"Please, set your name with command like:\n"
910
'bzr whoami "Your Name <name@domain.com>"')
911
host = win32utils.get_host_name_unicode()
913
host = socket.gethostname()
914
return name, (name + '@' + host)
920
w = pwd.getpwuid(uid)
922
raise errors.BzrCommandError('Unable to determine your name. '
923
'Please use "bzr whoami" to set it.')
925
# we try utf-8 first, because on many variants (like Linux),
926
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
927
# false positives. (many users will have their user encoding set to
928
# latin-1, which cannot raise UnicodeError.)
930
gecos = w.pw_gecos.decode('utf-8')
934
encoding = osutils.get_user_encoding()
935
gecos = w.pw_gecos.decode(encoding)
937
raise errors.BzrCommandError('Unable to determine your name. '
938
'Use "bzr whoami" to set it.')
940
username = w.pw_name.decode(encoding)
942
raise errors.BzrCommandError('Unable to determine your name. '
943
'Use "bzr whoami" to set it.')
945
comma = gecos.find(',')
949
realname = gecos[:comma]
956
user_encoding = osutils.get_user_encoding()
957
realname = username = getpass.getuser().decode(user_encoding)
958
except UnicodeDecodeError:
959
raise errors.BzrError("Can't decode username as %s." % \
962
return realname, (username + '@' + socket.gethostname())
1041
965
def parse_username(username):
1042
966
"""Parse e-mail username and return a (name, address) tuple."""
1043
967
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)