~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Martin
  • Date: 2012-07-28 15:26:22 UTC
  • mto: This revision was merged to the branch mainline in revision 6546.
  • Revision ID: gzlist@googlemail.com-20120728152622-wkjruul7dtg6c0ts
Add release notes

Show diffs side-by-side

added added

removed removed

Lines of Context:
89
89
    atomicfile,
90
90
    controldir,
91
91
    debug,
92
 
    directory_service,
93
92
    errors,
94
93
    lazy_regex,
95
94
    library_state,
1488
1487
    """Return per-user configuration directory as unicode string
1489
1488
 
1490
1489
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1491
 
    and Linux.  On Mac OS X and Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1490
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1492
1491
    that will be used instead.
1493
1492
 
1494
1493
    TODO: Global option --config-dir to override this.
1503
1502
        #                APPDATA, but hard to move. See bug 348640 for more.
1504
1503
        return osutils.pathjoin(base, 'bazaar', '2.0')
1505
1504
    if base is None:
1506
 
        xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1507
 
        if xdg_dir is None:
1508
 
            xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1509
 
        xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1510
 
        if osutils.isdir(xdg_dir):
1511
 
            trace.mutter(
1512
 
                "Using configuration in XDG directory %s." % xdg_dir)
1513
 
            return xdg_dir
 
1505
        # GZ 2012-02-01: What should OSX use instead of XDG if anything?
 
1506
        if sys.platform != 'darwin':
 
1507
            xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
 
1508
            if xdg_dir is None:
 
1509
                xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
 
1510
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1511
            if osutils.isdir(xdg_dir):
 
1512
                trace.mutter(
 
1513
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1514
                return xdg_dir
1514
1515
        base = osutils._get_home_dir()
1515
1516
    return osutils.pathjoin(base, ".bazaar")
1516
1517
 
1555
1556
def xdg_cache_dir():
1556
1557
    # See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1557
1558
    # Possibly this should be different on Windows?
1558
 
    e = os.environ.get('XDG_CACHE_HOME', None)
 
1559
    e = os.environ.get('XDG_CACHE_DIR', None)
1559
1560
    if e:
1560
1561
        return e
1561
1562
    else:
2133
2134
 
2134
2135
class Base64CredentialStore(CredentialStore):
2135
2136
    __doc__ = """Base64 credential store for the authentication.conf file"""
2136
 
 
 
2137
    
2137
2138
    def decode_password(self, credentials):
2138
2139
        """See CredentialStore.decode_password."""
2139
2140
        # GZ 2012-07-28: Will raise binascii.Error if password is not base64,
2159
2160
        for those under repositories.
2160
2161
        """
2161
2162
        if self._config is None:
2162
 
            raise errors.BzrError("Cannot set configuration in %s"
2163
 
                                  % self._bzrdir)
 
2163
            raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
2164
2164
        if value is None:
2165
2165
            self._config.set_option('', 'default_stack_on')
2166
2166
        else:
2314
2314
        :param help: a doc string to explain the option to the user.
2315
2315
 
2316
2316
        :param from_unicode: a callable to convert the unicode string
2317
 
            representing the option value in a store or its default value.
 
2317
            representing the option value in a store. This is not called for
 
2318
            the default value.
2318
2319
 
2319
2320
        :param invalid: the action to be taken when an invalid value is
2320
2321
            encountered in a store. This is called only when from_unicode is
2471
2472
    return float(unicode_str)
2472
2473
 
2473
2474
 
2474
 
# Use an empty dict to initialize an empty configobj avoiding all parsing and
2475
 
# encoding checks
 
2475
# Use a an empty dict to initialize an empty configobj avoiding all
 
2476
# parsing and encoding checks
2476
2477
_list_converter_config = configobj.ConfigObj(
2477
2478
    {}, encoding='utf-8', list_values=True, interpolation=False)
2478
2479
 
2550
2551
        return "".join(ret)
2551
2552
 
2552
2553
 
2553
 
_option_ref_re = lazy_regex.lazy_compile('({[^\d\W](?:\.\w|\w)*})')
2554
 
"""Describes an expandable option reference.
2555
 
 
2556
 
We want to match the most embedded reference first.
2557
 
 
2558
 
I.e. for '{{foo}}' we will get '{foo}',
2559
 
for '{bar{baz}}' we will get '{baz}'
2560
 
"""
2561
 
 
2562
 
def iter_option_refs(string):
2563
 
    # Split isolate refs so every other chunk is a ref
2564
 
    is_ref = False
2565
 
    for chunk  in _option_ref_re.split(string):
2566
 
        yield is_ref, chunk
2567
 
        is_ref = not is_ref
2568
 
 
2569
 
 
2570
2554
class OptionRegistry(registry.Registry):
2571
2555
    """Register config options by their name.
2572
2556
 
2574
2558
    some information from the option object itself.
2575
2559
    """
2576
2560
 
2577
 
    def _check_option_name(self, option_name):
2578
 
        """Ensures an option name is valid.
2579
 
 
2580
 
        :param option_name: The name to validate.
2581
 
        """
2582
 
        if _option_ref_re.match('{%s}' % option_name) is None:
2583
 
            raise errors.IllegalOptionName(option_name)
2584
 
 
2585
2561
    def register(self, option):
2586
2562
        """Register a new option to its name.
2587
2563
 
2588
2564
        :param option: The option to register. Its name is used as the key.
2589
2565
        """
2590
 
        self._check_option_name(option.name)
2591
2566
        super(OptionRegistry, self).register(option.name, option,
2592
2567
                                             help=option.help)
2593
2568
 
2602
2577
        :param member_name: the member of the module to return.  If empty or 
2603
2578
                None, get() will return the module itself.
2604
2579
        """
2605
 
        self._check_option_name(key)
2606
2580
        super(OptionRegistry, self).register_lazy(key,
2607
2581
                                                  module_name, member_name)
2608
2582
 
2827
2801
 
2828
2802
Each function takes branch, rev_id as parameters.
2829
2803
'''))
2830
 
option_registry.register_lazy('progress_bar', 'bzrlib.ui.text',
2831
 
                              'opt_progress_bar')
2832
2804
option_registry.register(
2833
2805
    Option('public_branch',
2834
2806
           default=None,
2971
2943
        self.options[name] = value
2972
2944
 
2973
2945
    def remove(self, name):
2974
 
        if name not in self.orig and name in self.options:
 
2946
        if name not in self.orig:
2975
2947
            self.orig[name] = self.get(name, None)
2976
2948
        del self.options[name]
2977
2949
 
3315
3287
        # anyway.
3316
3288
        return 'In-Process Store, no URL'
3317
3289
 
3318
 
 
3319
3290
class TransportIniFileStore(IniFileStore):
3320
3291
    """IniFileStore that loads files from a transport.
3321
3292
 
3411
3382
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3412
3383
# on a poolie's remark)
3413
3384
class GlobalStore(LockableIniFileStore):
3414
 
    """A config store for global options.
3415
 
 
3416
 
    There is a single GlobalStore for a given process.
3417
 
    """
3418
3385
 
3419
3386
    def __init__(self, possible_transports=None):
3420
3387
        t = transport.get_transport_from_path(
3424
3391
 
3425
3392
 
3426
3393
class LocationStore(LockableIniFileStore):
3427
 
    """A config store for options specific to a location.
3428
 
 
3429
 
    There is a single LocationStore for a given process.
3430
 
    """
3431
3394
 
3432
3395
    def __init__(self, possible_transports=None):
3433
3396
        t = transport.get_transport_from_path(
3437
3400
 
3438
3401
 
3439
3402
class BranchStore(TransportIniFileStore):
3440
 
    """A config store for branch options.
3441
 
 
3442
 
    There is a single BranchStore for a given branch.
3443
 
    """
3444
3403
 
3445
3404
    def __init__(self, branch):
3446
3405
        super(BranchStore, self).__init__(branch.control_transport,
3559
3518
        """
3560
3519
        location_parts = self.location.rstrip('/').split('/')
3561
3520
        store = self.store
 
3521
        sections = []
3562
3522
        # Later sections are more specific, they should be returned first
3563
3523
        for _, section in reversed(list(store.get_sections())):
3564
3524
            if section.id is None:
3646
3606
            yield self.store, section
3647
3607
 
3648
3608
 
3649
 
# FIXME: _shared_stores should be an attribute of a library state once a
3650
 
# library_state object is always available.
3651
 
_shared_stores = {}
3652
 
_shared_stores_at_exit_installed = False
 
3609
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
 
3610
"""Describes an expandable option reference.
 
3611
 
 
3612
We want to match the most embedded reference first.
 
3613
 
 
3614
I.e. for '{{foo}}' we will get '{foo}',
 
3615
for '{bar{baz}}' we will get '{baz}'
 
3616
"""
 
3617
 
 
3618
def iter_option_refs(string):
 
3619
    # Split isolate refs so every other chunk is a ref
 
3620
    is_ref = False
 
3621
    for chunk  in _option_ref_re.split(string):
 
3622
        yield is_ref, chunk
 
3623
        is_ref = not is_ref
 
3624
 
3653
3625
 
3654
3626
class Stack(object):
3655
3627
    """A stack of configurations where an option can be defined"""
3844
3816
        return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3845
3817
 
3846
3818
    def _get_overrides(self):
3847
 
        # FIXME: Hack around library_state.initialize never called
 
3819
        # Hack around library_state.initialize never called
3848
3820
        if bzrlib.global_state is not None:
3849
3821
            return bzrlib.global_state.cmdline_overrides.get_sections()
3850
3822
        return []
3851
3823
 
3852
 
    def get_shared_store(self, store, state=None):
3853
 
        """Get a known shared store.
3854
 
 
3855
 
        Store urls uniquely identify them and are used to ensure a single copy
3856
 
        is shared across all users.
3857
 
 
3858
 
        :param store: The store known to the caller.
3859
 
 
3860
 
        :param state: The library state where the known stores are kept.
3861
 
 
3862
 
        :returns: The store received if it's not a known one, an already known
3863
 
            otherwise.
3864
 
        """
3865
 
        if state is None:
3866
 
            state = bzrlib.global_state
3867
 
        if state is None:
3868
 
            global _shared_stores_at_exit_installed
3869
 
            stores = _shared_stores
3870
 
            def save_config_changes():
3871
 
                for k, store in stores.iteritems():
3872
 
                    store.save_changes()
3873
 
            if not _shared_stores_at_exit_installed:
3874
 
                # FIXME: Ugly hack waiting for library_state to always be
3875
 
                # available. -- vila 20120731
3876
 
                import atexit
3877
 
                atexit.register(save_config_changes)
3878
 
                _shared_stores_at_exit_installed = True
3879
 
        else:
3880
 
            stores = state.config_stores
3881
 
        url = store.external_url()
3882
 
        try:
3883
 
            return stores[url]
3884
 
        except KeyError:
3885
 
            stores[url] = store
3886
 
            return store
3887
 
 
3888
3824
 
3889
3825
class MemoryStack(Stack):
3890
3826
    """A configuration stack defined from a string.
3940
3876
        self.store.save()
3941
3877
 
3942
3878
 
3943
 
class GlobalStack(Stack):
 
3879
class GlobalStack(_CompatibleStack):
3944
3880
    """Global options only stack.
3945
3881
 
3946
3882
    The following sections are queried:
3954
3890
    """
3955
3891
 
3956
3892
    def __init__(self):
3957
 
        gstore = self.get_shared_store(GlobalStore())
 
3893
        gstore = GlobalStore()
3958
3894
        super(GlobalStack, self).__init__(
3959
3895
            [self._get_overrides,
3960
3896
             NameMatcher(gstore, 'DEFAULT').get_sections],
3961
3897
            gstore, mutable_section_id='DEFAULT')
3962
3898
 
3963
3899
 
3964
 
class LocationStack(Stack):
 
3900
class LocationStack(_CompatibleStack):
3965
3901
    """Per-location options falling back to global options stack.
3966
3902
 
3967
3903
 
3983
3919
        """Make a new stack for a location and global configuration.
3984
3920
 
3985
3921
        :param location: A URL prefix to """
3986
 
        lstore = self.get_shared_store(LocationStore())
 
3922
        lstore = LocationStore()
3987
3923
        if location.startswith('file://'):
3988
3924
            location = urlutils.local_path_from_url(location)
3989
 
        gstore = self.get_shared_store(GlobalStore())
 
3925
        gstore = GlobalStore()
3990
3926
        super(LocationStack, self).__init__(
3991
3927
            [self._get_overrides,
3992
3928
             LocationMatcher(lstore, location).get_sections,
4014
3950
    """
4015
3951
 
4016
3952
    def __init__(self, branch):
4017
 
        lstore = self.get_shared_store(LocationStore())
 
3953
        lstore = LocationStore()
4018
3954
        bstore = branch._get_config_store()
4019
 
        gstore = self.get_shared_store(GlobalStore())
 
3955
        gstore = GlobalStore()
4020
3956
        super(BranchStack, self).__init__(
4021
3957
            [self._get_overrides,
4022
3958
             LocationMatcher(lstore, branch.base).get_sections,
4044
3980
        # unlock saves all the changes.
4045
3981
 
4046
3982
 
4047
 
class RemoteControlStack(Stack):
 
3983
class RemoteControlStack(_CompatibleStack):
4048
3984
    """Remote control-only options stack."""
4049
3985
 
4050
3986
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
4095
4031
class cmd_config(commands.Command):
4096
4032
    __doc__ = """Display, set or remove a configuration option.
4097
4033
 
4098
 
    Display the active value for option NAME.
 
4034
    Display the active value for a given option.
4099
4035
 
4100
4036
    If --all is specified, NAME is interpreted as a regular expression and all
4101
 
    matching options are displayed mentioning their scope and without resolving
4102
 
    option references in the value). The active value that bzr will take into
4103
 
    account is the first one displayed for each option.
4104
 
 
4105
 
    If NAME is not given, --all .* is implied (all options are displayed for the
4106
 
    current scope).
4107
 
 
4108
 
    Setting a value is achieved by using NAME=value without spaces. The value
 
4037
    matching options are displayed mentioning their scope. The active value
 
4038
    that bzr will take into account is the first one displayed for each option.
 
4039
 
 
4040
    If no NAME is given, --all .* is implied.
 
4041
 
 
4042
    Setting a value is achieved by using name=value without spaces. The value
4109
4043
    is set in the most relevant scope and can be checked by displaying the
4110
4044
    option again.
4111
 
 
4112
 
    Removing a value is achieved by using --remove NAME.
4113
4045
    """
4114
4046
 
4115
4047
    takes_args = ['name?']
4136
4068
            remove=False):
4137
4069
        if directory is None:
4138
4070
            directory = '.'
4139
 
        directory = directory_service.directories.dereference(directory)
4140
4071
        directory = urlutils.normalize_url(directory)
4141
4072
        if remove and all:
4142
4073
            raise errors.BzrError(
4245
4176
    def _set_config_option(self, name, value, directory, scope):
4246
4177
        conf = self._get_stack(directory, scope, write_access=True)
4247
4178
        conf.set(name, value)
4248
 
        # Explicitly save the changes
4249
 
        conf.store.save_changes()
4250
4179
 
4251
4180
    def _remove_config_option(self, name, directory, scope):
4252
4181
        if name is None:
4255
4184
        conf = self._get_stack(directory, scope, write_access=True)
4256
4185
        try:
4257
4186
            conf.remove(name)
4258
 
            # Explicitly save the changes
4259
 
            conf.store.save_changes()
4260
4187
        except KeyError:
4261
4188
            raise errors.NoSuchConfigOption(name)
4262
4189