/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: John Arbash Meinel
  • Date: 2008-06-05 16:27:16 UTC
  • mfrom: (3475 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3476.
  • Revision ID: john@arbash-meinel.com-20080605162716-a3hn238tnctbfd8j
merge bzr.dev, resolve NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
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,
439
440
 
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')
 
444
 
 
445
    def get_aliases(self):
 
446
        """Return the aliases section."""
 
447
        if 'ALIASES' in self._get_parser():
 
448
            return self._get_parser()['ALIASES']
 
449
        else:
 
450
            return {}
 
451
 
 
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')
 
455
 
 
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()
 
463
 
 
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()
 
471
 
 
472
    def _write_config_file(self):
449
473
        f = open(self._get_filename(), 'wb')
450
474
        self._get_parser().write(f)
451
475
        f.close()
569
593
 
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' %
 
600
                (store, option))
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.
640
666
    
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.
643
669
        """
644
670
        try:
645
 
            return (self.branch.control_files.get_utf8("email") 
646
 
                    .read()
 
671
            return (self.branch._transport.get_bytes("email")
647
672
                    .decode(bzrlib.user_encoding)
648
673
                    .rstrip("\r\n"))
649
674
        except errors.NoSuchFile, e:
890
915
class TreeConfig(IniBasedConfig):
891
916
    """Branch configuration data associated with its contents, not location"""
892
917
 
 
918
    # XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
 
919
 
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
895
926
 
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()
900
 
 
901
 
    def _get_config(self):
902
 
        try:
903
 
            obj = ConfigObj(self.branch.control_files.get('branch.conf'),
904
 
                            encoding='utf-8')
905
 
        except errors.NoSuchFile:
906
 
            obj = ConfigObj(encoding='utf=8')
907
 
        return obj
 
930
        return self._config._get_configobj()
908
931
 
909
932
    def get_option(self, name, section=None, default=None):
910
933
        self.branch.lock_read()
911
934
        try:
912
 
            obj = self._get_config()
913
 
            try:
914
 
                if section is not None:
915
 
                    obj = obj[section]
916
 
                result = obj[name]
917
 
            except KeyError:
918
 
                result = default
 
935
            return self._config.get_option(name, section, default)
919
936
        finally:
920
937
            self.branch.unlock()
921
938
        return result
924
941
        """Set a per-branch configuration option"""
925
942
        self.branch.lock_write()
926
943
        try:
927
 
            cfg_obj = self._get_config()
928
 
            if section is None:
929
 
                obj = cfg_obj
930
 
            else:
931
 
                try:
932
 
                    obj = cfg_obj[section]
933
 
                except KeyError:
934
 
                    cfg_obj[section] = {}
935
 
                    obj = cfg_obj[section]
936
 
            obj[name] = value
937
 
            out_file = StringIO()
938
 
            cfg_obj.write(out_file)
939
 
            out_file.seek(0)
940
 
            self.branch.control_files.put('branch.conf', out_file)
 
944
            self._config.set_option(value, name, section)
941
945
        finally:
942
946
            self.branch.unlock()
943
947
 
1015
1019
        """
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)
 
1024
 
1018
1025
            a_scheme, a_host, a_user, a_path = map(
1019
1026
                auth_def.get, ['scheme', 'host', 'user', 'path'])
1020
1027
 
1052
1059
                # Can't find a user
1053
1060
                continue
1054
1061
            credentials = dict(name=auth_def_name,
1055
 
                               user=a_user, password=auth_def['password'],
 
1062
                               user=a_user,
 
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'])
 
1122
                password = None
1110
1123
        else:
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:
1125
1138
 
1126
1139
    def decode_password(self, credentials, encoding):
1127
1140
        return credentials
 
1141
 
 
1142
 
 
1143
class TransportConfig(object):
 
1144
    """A Config that reads/writes a config file on a Transport.
 
1145
 
 
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.
 
1149
    """
 
1150
 
 
1151
    def __init__(self, transport, filename):
 
1152
        self._transport = transport
 
1153
        self._filename = filename
 
1154
 
 
1155
    def get_option(self, name, section=None, default=None):
 
1156
        """Return the value associated with a named option.
 
1157
 
 
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
 
1162
        """
 
1163
        configobj = self._get_configobj()
 
1164
        if section is None:
 
1165
            section_obj = configobj
 
1166
        else:
 
1167
            try:
 
1168
                section_obj = configobj[section]
 
1169
            except KeyError:
 
1170
                return default
 
1171
        return section_obj.get(name, default)
 
1172
 
 
1173
    def set_option(self, value, name, section=None):
 
1174
        """Set the value associated with a named option.
 
1175
 
 
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)
 
1179
        """
 
1180
        configobj = self._get_configobj()
 
1181
        if section is None:
 
1182
            configobj[name] = value
 
1183
        else:
 
1184
            configobj.setdefault(section, {})[name] = value
 
1185
        self._set_configobj(configobj)
 
1186
 
 
1187
    def _get_configobj(self):
 
1188
        try:
 
1189
            return ConfigObj(self._transport.get(self._filename),
 
1190
                             encoding='utf-8')
 
1191
        except errors.NoSuchFile:
 
1192
            return ConfigObj(encoding='utf-8')
 
1193
 
 
1194
    def _set_configobj(self, configobj):
 
1195
        out_file = StringIO()
 
1196
        configobj.write(out_file)
 
1197
        out_file.seek(0)
 
1198
        self._transport.put_file(self._filename, out_file)