151
151
mail_client_class = {
152
152
None: mail_client.DefaultMail,
153
153
# Specific clients
154
'emacsclient': mail_client.EmacsMail,
154
155
'evolution': mail_client.Evolution,
155
156
'kmail': mail_client.KMail,
156
157
'mutt': mail_client.Mutt,
440
441
def set_user_option(self, option, value):
441
442
"""Save option and its value in the configuration."""
443
self._set_option(option, value, 'DEFAULT')
445
def get_aliases(self):
446
"""Return the aliases section."""
447
if 'ALIASES' in self._get_parser():
448
return self._get_parser()['ALIASES']
452
def set_alias(self, alias_name, alias_command):
453
"""Save the alias in the configuration."""
454
self._set_option(alias_name, alias_command, 'ALIASES')
456
def unset_alias(self, alias_name):
457
"""Unset an existing alias."""
458
aliases = self._get_parser().get('ALIASES')
459
if not aliases or alias_name not in aliases:
460
raise errors.NoSuchAlias(alias_name)
461
del aliases[alias_name]
462
self._write_config_file()
464
def _set_option(self, option, value, section):
442
465
# FIXME: RBC 20051029 This should refresh the parser and also take a
443
466
# file lock on bazaar.conf.
444
467
conf_dir = os.path.dirname(self._get_filename())
445
468
ensure_config_dir_exists(conf_dir)
446
if 'DEFAULT' not in self._get_parser():
447
self._get_parser()['DEFAULT'] = {}
448
self._get_parser()['DEFAULT'][option] = value
469
self._get_parser().setdefault(section, {})[option] = value
470
self._write_config_file()
472
def _write_config_file(self):
449
473
f = open(self._get_filename(), 'wb')
450
474
self._get_parser().write(f)
570
594
def set_user_option(self, option, value, store=STORE_LOCATION):
571
595
"""Save option and its value in the configuration."""
572
assert store in [STORE_LOCATION,
596
if store not in [STORE_LOCATION,
573
597
STORE_LOCATION_NORECURSE,
574
STORE_LOCATION_APPENDPATH], 'bad storage policy'
598
STORE_LOCATION_APPENDPATH]:
599
raise ValueError('bad storage policy %r for %r' %
575
601
# FIXME: RBC 20051029 This should refresh the parser and also take a
576
602
# file lock on locations.conf.
577
603
conf_dir = os.path.dirname(self._get_filename())
638
664
def _get_user_id(self):
639
665
"""Return the full user id for the branch.
641
e.g. "John Hacker <jhacker@foo.org>"
667
e.g. "John Hacker <jhacker@example.com>"
642
668
This is looked up in the email controlfile for the branch.
645
return (self.branch.control_files.get_utf8("email")
671
return (self.branch._transport.get_bytes("email")
647
672
.decode(bzrlib.user_encoding)
649
674
except errors.NoSuchFile, e:
890
915
class TreeConfig(IniBasedConfig):
891
916
"""Branch configuration data associated with its contents, not location"""
918
# XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
893
920
def __init__(self, branch):
921
# XXX: Really this should be asking the branch for its configuration
922
# data, rather than relying on a Transport, so that it can work
923
# more cleanly with a RemoteBranch that has no transport.
924
self._config = TransportConfig(branch._transport, 'branch.conf')
894
925
self.branch = branch
896
927
def _get_parser(self, file=None):
897
928
if file is not None:
898
929
return IniBasedConfig._get_parser(file)
899
return self._get_config()
901
def _get_config(self):
903
obj = ConfigObj(self.branch.control_files.get('branch.conf'),
905
except errors.NoSuchFile:
906
obj = ConfigObj(encoding='utf=8')
930
return self._config._get_configobj()
909
932
def get_option(self, name, section=None, default=None):
910
933
self.branch.lock_read()
912
obj = self._get_config()
914
if section is not None:
935
return self._config.get_option(name, section, default)
920
937
self.branch.unlock()
924
941
"""Set a per-branch configuration option"""
925
942
self.branch.lock_write()
927
cfg_obj = self._get_config()
932
obj = cfg_obj[section]
934
cfg_obj[section] = {}
935
obj = cfg_obj[section]
937
out_file = StringIO()
938
cfg_obj.write(out_file)
940
self.branch.control_files.put('branch.conf', out_file)
944
self._config.set_option(value, name, section)
942
946
self.branch.unlock()
1016
1020
credentials = None
1017
1021
for auth_def_name, auth_def in self._get_config().items():
1022
if type(auth_def) is not configobj.Section:
1023
raise ValueError("%s defined outside a section" % auth_def_name)
1018
1025
a_scheme, a_host, a_user, a_path = map(
1019
1026
auth_def.get, ['scheme', 'host', 'user', 'path'])
1052
1059
# Can't find a user
1054
1061
credentials = dict(name=auth_def_name,
1055
user=a_user, password=auth_def['password'],
1063
password=auth_def.get('password', None),
1056
1064
verify_certificates=a_verify_certificates)
1057
1065
self.decode_password(credentials,
1058
1066
auth_def.get('password_encoding', None))
1107
1115
credentials = self.get_credentials(scheme, host, port, user, path)
1108
1116
if credentials is not None:
1109
1117
password = credentials['password']
1118
if password is not None and scheme is 'ssh':
1119
trace.warning('password ignored in section [%s],'
1120
' use an ssh agent instead'
1121
% credentials['name'])
1111
1124
password = None
1112
1125
# Prompt user only if we could't find a password
1113
1126
if password is None:
1114
1127
if prompt is None:
1115
# Create a default prompt suitable for most of the cases
1128
# Create a default prompt suitable for most cases
1116
1129
prompt = '%s' % scheme.upper() + ' %(user)s@%(host)s password'
1117
1130
# Special handling for optional fields in the prompt
1118
1131
if port is not None:
1126
1139
def decode_password(self, credentials, encoding):
1127
1140
return credentials
1143
class TransportConfig(object):
1144
"""A Config that reads/writes a config file on a Transport.
1146
It is a low-level object that considers config data to be name/value pairs
1147
that may be associated with a section. Assigning meaning to the these
1148
values is done at higher levels like TreeConfig.
1151
def __init__(self, transport, filename):
1152
self._transport = transport
1153
self._filename = filename
1155
def get_option(self, name, section=None, default=None):
1156
"""Return the value associated with a named option.
1158
:param name: The name of the value
1159
:param section: The section the option is in (if any)
1160
:param default: The value to return if the value is not set
1161
:return: The value or default value
1163
configobj = self._get_configobj()
1165
section_obj = configobj
1168
section_obj = configobj[section]
1171
return section_obj.get(name, default)
1173
def set_option(self, value, name, section=None):
1174
"""Set the value associated with a named option.
1176
:param value: The value to set
1177
:param name: The name of the value to set
1178
:param section: The section the option is in (if any)
1180
configobj = self._get_configobj()
1182
configobj[name] = value
1184
configobj.setdefault(section, {})[name] = value
1185
self._set_configobj(configobj)
1187
def _get_configobj(self):
1189
return ConfigObj(self._transport.get(self._filename),
1191
except errors.NoSuchFile:
1192
return ConfigObj(encoding='utf-8')
1194
def _set_configobj(self, configobj):
1195
out_file = StringIO()
1196
configobj.write(out_file)
1198
self._transport.put_file(self._filename, out_file)