~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

(vila) Default to no ssl cert verification on osx and windows (Vincent
 Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
                   turns on create_signatures.
56
56
create_signatures - this option controls whether bzr will always create
57
57
                    gpg signatures or not on commits.  There is an unused
58
 
                    option which in future is expected to work if
 
58
                    option which in future is expected to work if               
59
59
                    branch settings require signatures.
60
60
log_format - this option sets the default log format.  Possible values are
61
61
             long, short, line, or a plugin can register new formats.
92
92
    lazy_regex,
93
93
    library_state,
94
94
    lockdir,
 
95
    mail_client,
95
96
    mergetools,
96
97
    osutils,
97
98
    symbol_versioning,
239
240
        return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
240
241
                                             sys.stdout)
241
242
 
 
243
    def get_mail_client(self):
 
244
        """Get a mail client to use"""
 
245
        selected_client = self.get_user_option('mail_client')
 
246
        _registry = mail_client.mail_client_registry
 
247
        try:
 
248
            mail_client_class = _registry.get(selected_client)
 
249
        except KeyError:
 
250
            raise errors.UnknownMailClient(selected_client)
 
251
        return mail_client_class(self)
 
252
 
242
253
    def _get_signature_checking(self):
243
254
        """Template method to override signature checking policy."""
244
255
 
1471
1482
        value = self._get_explicit_nickname()
1472
1483
        if value is not None:
1473
1484
            return value
1474
 
        if self.branch.name:
1475
 
            return self.branch.name
1476
1485
        return urlutils.unescape(self.branch.base.split('/')[-2])
1477
1486
 
1478
1487
    def has_explicit_nickname(self):
2373
2382
            raise AssertionError('%r is not supported as a default value'
2374
2383
                                 % (default,))
2375
2384
        self.default_from_env = default_from_env
2376
 
        self._help = help
 
2385
        self.help = help
2377
2386
        self.from_unicode = from_unicode
2378
2387
        self.unquote = unquote
2379
2388
        if invalid and invalid not in ('warning', 'error'):
2380
2389
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2381
2390
        self.invalid = invalid
2382
2391
 
2383
 
    @property
2384
 
    def help(self):
2385
 
        return self._help
2386
 
 
2387
2392
    def convert_from_unicode(self, store, unicode_value):
2388
2393
        if self.unquote and store is not None and unicode_value is not None:
2389
2394
            unicode_value = store.unquote(unicode_value)
2529
2534
        return l
2530
2535
 
2531
2536
 
2532
 
class RegistryOption(Option):
2533
 
    """Option for a choice from a registry."""
2534
 
 
2535
 
    def __init__(self, name, registry, default_from_env=None,
2536
 
                 help=None, invalid=None):
2537
 
        """A registry based Option definition.
2538
 
 
2539
 
        This overrides the base class so the conversion from a unicode string
2540
 
        can take quoting into account.
2541
 
        """
2542
 
        super(RegistryOption, self).__init__(
2543
 
            name, default=lambda: unicode(registry.default_key),
2544
 
            default_from_env=default_from_env,
2545
 
            from_unicode=self.from_unicode, help=help,
2546
 
            invalid=invalid, unquote=False)
2547
 
        self.registry = registry
2548
 
 
2549
 
    def from_unicode(self, unicode_str):
2550
 
        if not isinstance(unicode_str, basestring):
2551
 
            raise TypeError
2552
 
        try:
2553
 
            return self.registry.get(unicode_str)
2554
 
        except KeyError:
2555
 
            raise ValueError(
2556
 
                "Invalid value %s for %s."
2557
 
                "See help for a list of possible values." % (unicode_str,
2558
 
                    self.name))
2559
 
 
2560
 
    @property
2561
 
    def help(self):
2562
 
        ret = [self._help, "\n\nThe following values are supported:\n"]
2563
 
        for key in self.registry.keys():
2564
 
            ret.append(" %s - %s\n" % (key, self.registry.get_help(key)))
2565
 
        return "".join(ret)
2566
 
 
2567
 
 
2568
2537
class OptionRegistry(registry.Registry):
2569
2538
    """Register config options by their name.
2570
2539
 
2660
2629
           help="""\
2661
2630
Whether revisions associated with tags should be fetched.
2662
2631
"""))
2663
 
option_registry.register_lazy(
2664
 
    'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
2665
2632
option_registry.register(
2666
2633
    Option('bzr.workingtree.worth_saving_limit', default=10,
2667
2634
           from_unicode=int_from_store,  invalid='warning',
2675
2642
a file has been touched.
2676
2643
'''))
2677
2644
option_registry.register(
2678
 
    Option('bugtracker', default=None,
2679
 
           help='''\
2680
 
Default bug tracker to use.
2681
 
 
2682
 
This bug tracker will be used for example when marking bugs
2683
 
as fixed using ``bzr commit --fixes``, if no explicit
2684
 
bug tracker was specified.
2685
 
'''))
2686
 
option_registry.register(
2687
2645
    Option('check_signatures', default=CHECK_IF_POSSIBLE,
2688
2646
           from_unicode=signature_policy_from_unicode,
2689
2647
           help='''\
2791
2749
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2792
2750
may be provided by plugins.
2793
2751
'''))
2794
 
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
2795
 
    'opt_mail_client')
2796
2752
option_registry.register(
2797
2753
    Option('output_encoding',
2798
2754
           help= 'Unicode encoding for output'
2895
2851
option_registry.register(
2896
2852
    Option('submit_to',
2897
2853
           help='''Where submissions from this branch are mailed to.'''))
2898
 
option_registry.register(
2899
 
    ListOption('suppress_warnings',
2900
 
           default=[],
2901
 
           help="List of warning classes to suppress."))
2902
 
option_registry.register(
2903
 
    Option('validate_signatures_in_log', default=False,
2904
 
           from_unicode=bool_from_store, invalid='warning',
2905
 
           help='''Whether to validate signatures in bzr log.'''))
 
2854
 
2906
2855
option_registry.register_lazy('ssl.ca_certs',
2907
2856
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2908
2857
 
2910
2859
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2911
2860
 
2912
2861
 
 
2862
 
2913
2863
class Section(object):
2914
2864
    """A section defines a dict of option name => value.
2915
2865
 
3418
3368
        self.branch = branch
3419
3369
        self.id = 'branch'
3420
3370
 
 
3371
    def lock_write(self, token=None):
 
3372
        return self.branch.lock_write(token)
 
3373
 
 
3374
    def unlock(self):
 
3375
        return self.branch.unlock()
 
3376
 
 
3377
    @needs_write_lock
 
3378
    def save(self):
 
3379
        # We need to be able to override the undecorated implementation
 
3380
        self.save_without_locking()
 
3381
 
 
3382
    def save_without_locking(self):
 
3383
        super(BranchStore, self).save()
 
3384
 
3421
3385
 
3422
3386
class ControlStore(LockableIniFileStore):
3423
3387
 
3645
3609
        self.store = store
3646
3610
        self.mutable_section_id = mutable_section_id
3647
3611
 
3648
 
    def iter_sections(self):
3649
 
        """Iterate all the defined sections."""
3650
 
        # Ensuring lazy loading is achieved by delaying section matching (which
3651
 
        # implies querying the persistent storage) until it can't be avoided
3652
 
        # anymore by using callables to describe (possibly empty) section
3653
 
        # lists.
3654
 
        for sections in self.sections_def:
3655
 
            for store, section in sections():
3656
 
                yield store, section
3657
 
 
3658
 
    def get(self, name, expand=None, convert=True):
 
3612
    def get(self, name, expand=None):
3659
3613
        """Return the *first* option value found in the sections.
3660
3614
 
3661
3615
        This is where we guarantee that sections coming from Store are loaded
3668
3622
 
3669
3623
        :param expand: Whether options references should be expanded.
3670
3624
 
3671
 
        :param convert: Whether the option value should be converted from
3672
 
            unicode (do nothing for non-registered options).
3673
 
 
3674
3625
        :returns: The value of the option.
3675
3626
        """
3676
3627
        # FIXME: No caching of options nor sections yet -- vila 20110503
3699
3650
                                      % (name, type(val)))
3700
3651
                if opt is None:
3701
3652
                    val = found_store.unquote(val)
3702
 
                elif convert:
 
3653
                else:
3703
3654
                    val = opt.convert_from_unicode(found_store, val)
3704
3655
            return val
3705
3656
 
3709
3660
            value = opt.get_override()
3710
3661
            value = expand_and_convert(value)
3711
3662
        if value is None:
3712
 
            for store, section in self.iter_sections():
3713
 
                value = section.get(name)
 
3663
            # Ensuring lazy loading is achieved by delaying section matching
 
3664
            # (which implies querying the persistent storage) until it can't be
 
3665
            # avoided anymore by using callables to describe (possibly empty)
 
3666
            # section lists.
 
3667
            for sections in self.sections_def:
 
3668
                for store, section in sections():
 
3669
                    value = section.get(name)
 
3670
                    if value is not None:
 
3671
                        found_store = store
 
3672
                        break
3714
3673
                if value is not None:
3715
 
                    found_store = store
3716
3674
                    break
3717
3675
            value = expand_and_convert(value)
3718
3676
            if opt is not None and value is None:
3784
3742
            # anything else
3785
3743
            value = env[name]
3786
3744
        else:
3787
 
            value = self.get(name, expand=False, convert=False)
 
3745
            value = self.get(name, expand=False)
3788
3746
            value = self._expand_options_in_string(value, env, _refs)
3789
3747
        return value
3790
3748
 
3933
3891
            lstore, mutable_section_id=location)
3934
3892
 
3935
3893
 
3936
 
class BranchStack(Stack):
 
3894
class BranchStack(_CompatibleStack):
3937
3895
    """Per-location options falling back to branch then global options stack.
3938
3896
 
3939
3897
    The following sections are queried:
3964
3922
            bstore)
3965
3923
        self.branch = branch
3966
3924
 
3967
 
    def lock_write(self, token=None):
3968
 
        return self.branch.lock_write(token)
3969
 
 
3970
 
    def unlock(self):
3971
 
        return self.branch.unlock()
3972
 
 
3973
 
    @needs_write_lock
3974
 
    def set(self, name, value):
3975
 
        super(BranchStack, self).set(name, value)
3976
 
        # Unlocking the branch will trigger a store.save_changes() so the last
3977
 
        # unlock saves all the changes.
3978
 
 
3979
 
    @needs_write_lock
3980
 
    def remove(self, name):
3981
 
        super(BranchStack, self).remove(name)
3982
 
        # Unlocking the branch will trigger a store.save_changes() so the last
3983
 
        # unlock saves all the changes.
3984
 
 
3985
3925
 
3986
3926
class RemoteControlStack(_CompatibleStack):
3987
3927
    """Remote control-only options stack."""
3998
3938
        self.bzrdir = bzrdir
3999
3939
 
4000
3940
 
4001
 
class BranchOnlyStack(Stack):
 
3941
class BranchOnlyStack(_CompatibleStack):
4002
3942
    """Branch-only options stack."""
4003
3943
 
4004
3944
    # FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
4012
3952
            bstore)
4013
3953
        self.branch = branch
4014
3954
 
4015
 
    def lock_write(self, token=None):
4016
 
        return self.branch.lock_write(token)
4017
 
 
4018
 
    def unlock(self):
4019
 
        return self.branch.unlock()
4020
 
 
4021
 
    @needs_write_lock
4022
 
    def set(self, name, value):
4023
 
        super(BranchOnlyStack, self).set(name, value)
4024
 
        # Force a write to persistent storage
4025
 
        self.store.save_changes()
4026
 
 
4027
 
    @needs_write_lock
4028
 
    def remove(self, name):
4029
 
        super(BranchOnlyStack, self).remove(name)
4030
 
        # Force a write to persistent storage
4031
 
        self.store.save_changes()
4032
 
 
 
3955
 
 
3956
# Use a an empty dict to initialize an empty configobj avoiding all
 
3957
# parsing and encoding checks
 
3958
_quoting_config = configobj.ConfigObj(
 
3959
    {}, encoding='utf-8', interpolation=False, list_values=True)
4033
3960
 
4034
3961
class cmd_config(commands.Command):
4035
3962
    __doc__ = """Display, set or remove a configuration option.
4097
4024
                # Set the option value
4098
4025
                self._set_config_option(name, value, directory, scope)
4099
4026
 
4100
 
    def _get_stack(self, directory, scope=None, write_access=False):
 
4027
    def _get_stack(self, directory, scope=None):
4101
4028
        """Get the configuration stack specified by ``directory`` and ``scope``.
4102
4029
 
4103
4030
        :param directory: Where the configurations are derived from.
4104
4031
 
4105
4032
        :param scope: A specific config to start from.
4106
 
 
4107
 
        :param write_access: Whether a write access to the stack will be
4108
 
            attempted.
4109
4033
        """
4110
4034
        # FIXME: scope should allow access to plugin-specific stacks (even
4111
4035
        # reduced to the plugin-specific store), related to
4119
4043
                (_, br, _) = (
4120
4044
                    controldir.ControlDir.open_containing_tree_or_branch(
4121
4045
                        directory))
4122
 
                if write_access:
4123
 
                    self.add_cleanup(br.lock_write().unlock)
4124
4046
                return br.get_config_stack()
4125
4047
            raise errors.NoSuchConfig(scope)
4126
4048
        else:
4128
4050
                (_, br, _) = (
4129
4051
                    controldir.ControlDir.open_containing_tree_or_branch(
4130
4052
                        directory))
4131
 
                if write_access:
4132
 
                    self.add_cleanup(br.lock_write().unlock)
4133
4053
                return br.get_config_stack()
4134
4054
            except errors.NotBranchError:
4135
4055
                return LocationStack(directory)
4136
4056
 
4137
 
    def _quote_multiline(self, value):
4138
 
        if '\n' in value:
4139
 
            value = '"""' + value + '"""'
4140
 
        return value
4141
 
 
4142
4057
    def _show_value(self, name, directory, scope):
4143
4058
        conf = self._get_stack(directory, scope)
4144
 
        value = conf.get(name, expand=True, convert=False)
 
4059
        value = conf.get(name, expand=True)
4145
4060
        if value is not None:
4146
4061
            # Quote the value appropriately
4147
 
            value = self._quote_multiline(value)
 
4062
            value = _quoting_config._quote(value)
4148
4063
            self.outf.write('%s\n' % (value,))
4149
4064
        else:
4150
4065
            raise errors.NoSuchConfigOption(name)
4158
4073
        cur_store_id = None
4159
4074
        cur_section = None
4160
4075
        conf = self._get_stack(directory, scope)
4161
 
        for store, section in conf.iter_sections():
4162
 
            for oname in section.iter_option_names():
4163
 
                if name.search(oname):
4164
 
                    if cur_store_id != store.id:
4165
 
                        # Explain where the options are defined
4166
 
                        self.outf.write('%s:\n' % (store.id,))
4167
 
                        cur_store_id = store.id
4168
 
                        cur_section = None
4169
 
                    if (section.id is not None and cur_section != section.id):
4170
 
                        # Display the section id as it appears in the store
4171
 
                        # (None doesn't appear by definition)
4172
 
                        self.outf.write('  [%s]\n' % (section.id,))
4173
 
                        cur_section = section.id
4174
 
                    value = section.get(oname, expand=False)
4175
 
                    # Quote the value appropriately
4176
 
                    value = self._quote_multiline(value)
4177
 
                    self.outf.write('  %s = %s\n' % (oname, value))
 
4076
        for sections in conf.sections_def:
 
4077
            for store, section in sections():
 
4078
                for oname in section.iter_option_names():
 
4079
                    if name.search(oname):
 
4080
                        if cur_store_id != store.id:
 
4081
                            # Explain where the options are defined
 
4082
                            self.outf.write('%s:\n' % (store.id,))
 
4083
                            cur_store_id = store.id
 
4084
                            cur_section = None
 
4085
                        if (section.id is not None
 
4086
                            and cur_section != section.id):
 
4087
                            # Display the section id as it appears in the store
 
4088
                            # (None doesn't appear by definition)
 
4089
                            self.outf.write('  [%s]\n' % (section.id,))
 
4090
                            cur_section = section.id
 
4091
                        value = section.get(oname, expand=False)
 
4092
                        # Since we don't use the stack, we need to restore a
 
4093
                        # proper quoting.
 
4094
                        try:
 
4095
                            opt = option_registry.get(oname)
 
4096
                            value = opt.convert_from_unicode(store, value)
 
4097
                        except KeyError:
 
4098
                            value = store.unquote(value)
 
4099
                        value = _quoting_config._quote(value)
 
4100
                        self.outf.write('  %s = %s\n' % (oname, value))
4178
4101
 
4179
4102
    def _set_config_option(self, name, value, directory, scope):
4180
 
        conf = self._get_stack(directory, scope, write_access=True)
 
4103
        conf = self._get_stack(directory, scope)
4181
4104
        conf.set(name, value)
4182
4105
 
4183
4106
    def _remove_config_option(self, name, directory, scope):
4184
4107
        if name is None:
4185
4108
            raise errors.BzrCommandError(
4186
4109
                '--remove expects an option to remove.')
4187
 
        conf = self._get_stack(directory, scope, write_access=True)
 
4110
        conf = self._get_stack(directory, scope)
4188
4111
        try:
4189
4112
            conf.remove(name)
4190
4113
        except KeyError: