258
259
Something similar to 'Martin Pool <mbp@sourcefrog.net>'
260
$BZR_EMAIL can be set to override this (as well as the
261
deprecated $BZREMAIL), then
261
$BZR_EMAIL can be set to override this, then
262
262
the concrete policy type is checked, and finally
263
263
$EMAIL is examined.
264
If none is found, a reasonable default is (hopefully)
264
If no username can be found, errors.NoWhoami exception is raised.
267
266
TODO: Check it's reasonably well-formed.
279
278
return v.decode(osutils.get_user_encoding())
281
name, email = _auto_user_id()
283
return '%s <%s>' % (name, email)
280
raise errors.NoWhoami()
282
def ensure_username(self):
283
"""Raise errors.NoWhoami if username is not set.
285
This method relies on the username() function raising the error.
287
289
def signature_checking(self):
288
290
"""What is the current policy for signature checking?."""
350
352
class IniBasedConfig(Config):
351
353
"""A configuration policy that draws from ini files."""
353
def __init__(self, get_filename):
355
def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
357
"""Base class for configuration files using an ini-like syntax.
359
:param file_name: The configuration file path.
354
361
super(IniBasedConfig, self).__init__()
355
self._get_filename = get_filename
362
if symbol_versioning.deprecated_passed(get_filename):
363
symbol_versioning.warn(
364
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
365
' Use file_name instead.',
368
if get_filename is None:
369
# Tests use in-memory config files that doesn't need to be
371
self.file_name = None
373
self.file_name = get_filename()
375
self.file_name = file_name
356
377
self._parser = None
358
def _get_parser(self, file=None):
380
def from_string(cls, str_or_unicode):
381
"""Create a config object from bytes.
383
:param str_or_unicode: A string representing the file content. This will
387
conf._content = StringIO(str_or_unicode.encode('utf-8'))
390
def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
391
if self._parser is not None:
360
392
return self._parser
362
input = self._get_filename()
393
if symbol_versioning.deprecated_passed(file):
394
symbol_versioning.warn(
395
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
396
' Use IniBasedConfig(_content=xxx) instead.',
399
if self._content is not None:
400
co_input = self._content
401
elif self.file_name is None:
402
raise AssertionError('We have no content to create the config')
404
co_input = self.file_name
366
self._parser = ConfigObj(input, encoding='utf-8')
406
self._parser = ConfigObj(co_input, encoding='utf-8')
367
407
except configobj.ConfigObjError, e:
368
408
raise errors.ParseConfigError(e.errors, e.config.filename)
369
409
return self._parser
476
516
def _get_nickname(self):
477
517
return self.get_user_option('nickname')
519
def _write_config_file(self):
520
if self.file_name is None:
521
raise AssertionError('We cannot save, self.file_name is None')
522
atomic_file = atomicfile.AtomicFile(self.file_name)
523
self._get_parser().write(atomic_file)
526
osutils.copy_ownership_from_path(self.file_name)
480
529
class GlobalConfig(IniBasedConfig):
481
530
"""The configuration that should be used for a specific location."""
533
super(GlobalConfig, self).__init__(file_name=config_filename())
483
535
def get_editor(self):
484
536
return self._get_user_option('editor')
487
super(GlobalConfig, self).__init__(config_filename)
489
538
def set_user_option(self, option, value):
490
539
"""Save option and its value in the configuration."""
491
540
self._set_option(option, value, 'DEFAULT')
512
561
def _set_option(self, option, value, section):
513
562
# FIXME: RBC 20051029 This should refresh the parser and also take a
514
563
# file lock on bazaar.conf.
515
conf_dir = os.path.dirname(self._get_filename())
564
conf_dir = os.path.dirname(self.file_name)
516
565
ensure_config_dir_exists(conf_dir)
517
566
self._get_parser().setdefault(section, {})[option] = value
518
567
self._write_config_file()
520
def _write_config_file(self):
521
path = self._get_filename()
523
osutils.copy_ownership_from_path(path)
524
self._get_parser().write(f)
528
570
class LocationConfig(IniBasedConfig):
529
571
"""A configuration object that gives the policy for a location."""
531
573
def __init__(self, location):
532
name_generator = locations_config_filename
533
if (not os.path.exists(name_generator()) and
534
os.path.exists(branches_config_filename())):
535
if sys.platform == 'win32':
536
trace.warning('Please rename %s to %s'
537
% (branches_config_filename(),
538
locations_config_filename()))
540
trace.warning('Please rename ~/.bazaar/branches.conf'
541
' to ~/.bazaar/locations.conf')
542
name_generator = branches_config_filename
543
super(LocationConfig, self).__init__(name_generator)
574
super(LocationConfig, self).__init__(
575
file_name=locations_config_filename())
544
576
# local file locations are looked up by local path, rather than
545
577
# by file url. This is because the config file is a user
546
578
# file, and we would rather not expose the user to file urls.
548
580
location = urlutils.local_path_from_url(location)
549
581
self.location = location
584
def from_string(cls, str_or_unicode, location):
585
"""Create a config object from bytes.
587
:param str_or_unicode: A string representing the file content. This will
590
:param location: The location url to filter the configuration.
593
conf._content = StringIO(str_or_unicode.encode('utf-8'))
551
596
def _get_matching_sections(self):
552
597
"""Return an ordered list of section names matching this location."""
553
598
sections = self._get_parser()
651
696
# FIXME: RBC 20051029 This should refresh the parser and also take a
652
697
# file lock on locations.conf.
653
conf_dir = os.path.dirname(self._get_filename())
698
conf_dir = os.path.dirname(self.file_name)
654
699
ensure_config_dir_exists(conf_dir)
655
700
location = self.location
656
701
if location.endswith('/'):
663
708
self._get_parser()[location][option]=value
664
709
# the allowed values of store match the config policies
665
710
self._set_option_policy(location, option, store)
666
self._get_parser().write(file(self._get_filename(), 'wb'))
711
self._write_config_file()
669
714
class BranchConfig(Config):
670
715
"""A configuration object giving the policy for a branch."""
717
def __init__(self, branch):
718
super(BranchConfig, self).__init__()
719
self._location_config = None
720
self._branch_data_config = None
721
self._global_config = None
723
self.option_sources = (self._get_location_config,
724
self._get_branch_data_config,
725
self._get_global_config)
672
727
def _get_branch_data_config(self):
673
728
if self._branch_data_config is None:
674
729
self._branch_data_config = TreeConfig(self.branch)
772
827
"""See Config.gpg_signing_command."""
773
828
return self._get_safe_value('_gpg_signing_command')
775
def __init__(self, branch):
776
super(BranchConfig, self).__init__()
777
self._location_config = None
778
self._branch_data_config = None
779
self._global_config = None
781
self.option_sources = (self._get_location_config,
782
self._get_branch_data_config,
783
self._get_global_config)
785
830
def _post_commit(self):
786
831
"""See Config.post_commit."""
787
832
return self._get_safe_value('_post_commit')
842
887
return osutils.pathjoin(base, 'bazaar', '2.0')
844
# cygwin, linux, and darwin all have a $HOME directory
846
890
base = os.path.expanduser("~")
847
891
return osutils.pathjoin(base, ".bazaar")
852
896
return osutils.pathjoin(config_dir(), 'bazaar.conf')
855
def branches_config_filename():
856
"""Return per-user configuration ini file filename."""
857
return osutils.pathjoin(config_dir(), 'branches.conf')
860
899
def locations_config_filename():
861
900
"""Return per-user configuration ini file filename."""
862
901
return osutils.pathjoin(config_dir(), 'locations.conf')
899
938
return os.path.expanduser('~/.cache')
903
"""Calculate automatic user identification.
905
Returns (realname, email).
907
Only used when none is set in the environment or the id file.
909
This previously used the FQDN as the default domain, but that can
910
be very slow on machines where DNS is broken. So now we simply
915
if sys.platform == 'win32':
916
name = win32utils.get_user_name_unicode()
918
raise errors.BzrError("Cannot autodetect user name.\n"
919
"Please, set your name with command like:\n"
920
'bzr whoami "Your Name <name@domain.com>"')
921
host = win32utils.get_host_name_unicode()
923
host = socket.gethostname()
924
return name, (name + '@' + host)
930
w = pwd.getpwuid(uid)
932
raise errors.BzrCommandError('Unable to determine your name. '
933
'Please use "bzr whoami" to set it.')
935
# we try utf-8 first, because on many variants (like Linux),
936
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
937
# false positives. (many users will have their user encoding set to
938
# latin-1, which cannot raise UnicodeError.)
940
gecos = w.pw_gecos.decode('utf-8')
944
encoding = osutils.get_user_encoding()
945
gecos = w.pw_gecos.decode(encoding)
947
raise errors.BzrCommandError('Unable to determine your name. '
948
'Use "bzr whoami" to set it.')
950
username = w.pw_name.decode(encoding)
952
raise errors.BzrCommandError('Unable to determine your name. '
953
'Use "bzr whoami" to set it.')
955
comma = gecos.find(',')
959
realname = gecos[:comma]
966
user_encoding = osutils.get_user_encoding()
967
realname = username = getpass.getuser().decode(user_encoding)
968
except UnicodeDecodeError:
969
raise errors.BzrError("Can't decode username as %s." % \
972
return realname, (username + '@' + socket.gethostname())
975
941
def parse_username(username):
976
942
"""Parse e-mail username and return a (name, address) tuple."""
977
943
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1063
1029
"""Save the config file, only tests should use it for now."""
1064
1030
conf_dir = os.path.dirname(self._filename)
1065
1031
ensure_config_dir_exists(conf_dir)
1066
self._get_config().write(file(self._filename, 'wb'))
1032
f = file(self._filename, 'wb')
1034
self._get_config().write(f)
1068
1038
def _set_option(self, section_name, option_name, value):
1069
1039
"""Set an authentication configuration option"""
1517
1487
return StringIO()
1519
1489
def _get_configobj(self):
1520
return ConfigObj(self._get_config_file(), encoding='utf-8')
1490
f = self._get_config_file()
1492
return ConfigObj(f, encoding='utf-8')
1522
1496
def _set_configobj(self, configobj):
1523
1497
out_file = StringIO()