~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

(gz) Create working tree at specified revision when doing a local push
 (Martin Packman)

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
from bzrlib.decorators import needs_write_lock
82
82
from bzrlib.lazy_import import lazy_import
83
83
lazy_import(globals(), """
84
 
import base64
85
84
import fnmatch
86
85
import re
87
86
 
89
88
    atomicfile,
90
89
    controldir,
91
90
    debug,
92
 
    directory_service,
93
91
    errors,
94
92
    lazy_regex,
95
93
    library_state,
1488
1486
    """Return per-user configuration directory as unicode string
1489
1487
 
1490
1488
    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,
 
1489
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1492
1490
    that will be used instead.
1493
1491
 
1494
1492
    TODO: Global option --config-dir to override this.
1503
1501
        #                APPDATA, but hard to move. See bug 348640 for more.
1504
1502
        return osutils.pathjoin(base, 'bazaar', '2.0')
1505
1503
    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
 
1504
        # GZ 2012-02-01: What should OSX use instead of XDG if anything?
 
1505
        if sys.platform != 'darwin':
 
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
1514
1514
        base = osutils._get_home_dir()
1515
1515
    return osutils.pathjoin(base, ".bazaar")
1516
1516
 
1555
1555
def xdg_cache_dir():
1556
1556
    # See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1557
1557
    # Possibly this should be different on Windows?
1558
 
    e = os.environ.get('XDG_CACHE_HOME', None)
 
1558
    e = os.environ.get('XDG_CACHE_DIR', None)
1559
1559
    if e:
1560
1560
        return e
1561
1561
    else:
2131
2131
credential_store_registry.default_key = 'plain'
2132
2132
 
2133
2133
 
2134
 
class Base64CredentialStore(CredentialStore):
2135
 
    __doc__ = """Base64 credential store for the authentication.conf file"""
2136
 
 
2137
 
    def decode_password(self, credentials):
2138
 
        """See CredentialStore.decode_password."""
2139
 
        # GZ 2012-07-28: Will raise binascii.Error if password is not base64,
2140
 
        #                should probably propogate as something more useful.
2141
 
        return base64.decodestring(credentials['password'])
2142
 
 
2143
 
credential_store_registry.register('base64', Base64CredentialStore,
2144
 
                                   help=Base64CredentialStore.__doc__)
2145
 
 
2146
 
 
2147
2134
class BzrDirConfig(object):
2148
2135
 
2149
2136
    def __init__(self, bzrdir):
2159
2146
        for those under repositories.
2160
2147
        """
2161
2148
        if self._config is None:
2162
 
            raise errors.BzrError("Cannot set configuration in %s"
2163
 
                                  % self._bzrdir)
 
2149
            raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
2164
2150
        if value is None:
2165
2151
            self._config.set_option('', 'default_stack_on')
2166
2152
        else:
2314
2300
        :param help: a doc string to explain the option to the user.
2315
2301
 
2316
2302
        :param from_unicode: a callable to convert the unicode string
2317
 
            representing the option value in a store or its default value.
 
2303
            representing the option value in a store. This is not called for
 
2304
            the default value.
2318
2305
 
2319
2306
        :param invalid: the action to be taken when an invalid value is
2320
2307
            encountered in a store. This is called only when from_unicode is
2471
2458
    return float(unicode_str)
2472
2459
 
2473
2460
 
2474
 
# Use an empty dict to initialize an empty configobj avoiding all parsing and
2475
 
# encoding checks
 
2461
# Use a an empty dict to initialize an empty configobj avoiding all
 
2462
# parsing and encoding checks
2476
2463
_list_converter_config = configobj.ConfigObj(
2477
2464
    {}, encoding='utf-8', list_values=True, interpolation=False)
2478
2465
 
2550
2537
        return "".join(ret)
2551
2538
 
2552
2539
 
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
2540
class OptionRegistry(registry.Registry):
2571
2541
    """Register config options by their name.
2572
2542
 
2574
2544
    some information from the option object itself.
2575
2545
    """
2576
2546
 
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
2547
    def register(self, option):
2586
2548
        """Register a new option to its name.
2587
2549
 
2588
2550
        :param option: The option to register. Its name is used as the key.
2589
2551
        """
2590
 
        self._check_option_name(option.name)
2591
2552
        super(OptionRegistry, self).register(option.name, option,
2592
2553
                                             help=option.help)
2593
2554
 
2602
2563
        :param member_name: the member of the module to return.  If empty or 
2603
2564
                None, get() will return the module itself.
2604
2565
        """
2605
 
        self._check_option_name(key)
2606
2566
        super(OptionRegistry, self).register_lazy(key,
2607
2567
                                                  module_name, member_name)
2608
2568
 
2827
2787
 
2828
2788
Each function takes branch, rev_id as parameters.
2829
2789
'''))
2830
 
option_registry.register_lazy('progress_bar', 'bzrlib.ui.text',
2831
 
                              'opt_progress_bar')
2832
2790
option_registry.register(
2833
2791
    Option('public_branch',
2834
2792
           default=None,
2971
2929
        self.options[name] = value
2972
2930
 
2973
2931
    def remove(self, name):
2974
 
        if name not in self.orig and name in self.options:
 
2932
        if name not in self.orig:
2975
2933
            self.orig[name] = self.get(name, None)
2976
2934
        del self.options[name]
2977
2935
 
3315
3273
        # anyway.
3316
3274
        return 'In-Process Store, no URL'
3317
3275
 
3318
 
 
3319
3276
class TransportIniFileStore(IniFileStore):
3320
3277
    """IniFileStore that loads files from a transport.
3321
3278
 
3411
3368
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3412
3369
# on a poolie's remark)
3413
3370
class GlobalStore(LockableIniFileStore):
3414
 
    """A config store for global options.
3415
 
 
3416
 
    There is a single GlobalStore for a given process.
3417
 
    """
3418
3371
 
3419
3372
    def __init__(self, possible_transports=None):
3420
3373
        t = transport.get_transport_from_path(
3424
3377
 
3425
3378
 
3426
3379
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
3380
 
3432
3381
    def __init__(self, possible_transports=None):
3433
3382
        t = transport.get_transport_from_path(
3437
3386
 
3438
3387
 
3439
3388
class BranchStore(TransportIniFileStore):
3440
 
    """A config store for branch options.
3441
 
 
3442
 
    There is a single BranchStore for a given branch.
3443
 
    """
3444
3389
 
3445
3390
    def __init__(self, branch):
3446
3391
        super(BranchStore, self).__init__(branch.control_transport,
3559
3504
        """
3560
3505
        location_parts = self.location.rstrip('/').split('/')
3561
3506
        store = self.store
 
3507
        sections = []
3562
3508
        # Later sections are more specific, they should be returned first
3563
3509
        for _, section in reversed(list(store.get_sections())):
3564
3510
            if section.id is None:
3646
3592
            yield self.store, section
3647
3593
 
3648
3594
 
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
 
3595
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
 
3596
"""Describes an expandable option reference.
 
3597
 
 
3598
We want to match the most embedded reference first.
 
3599
 
 
3600
I.e. for '{{foo}}' we will get '{foo}',
 
3601
for '{bar{baz}}' we will get '{baz}'
 
3602
"""
 
3603
 
 
3604
def iter_option_refs(string):
 
3605
    # Split isolate refs so every other chunk is a ref
 
3606
    is_ref = False
 
3607
    for chunk  in _option_ref_re.split(string):
 
3608
        yield is_ref, chunk
 
3609
        is_ref = not is_ref
 
3610
 
3653
3611
 
3654
3612
class Stack(object):
3655
3613
    """A stack of configurations where an option can be defined"""
3844
3802
        return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3845
3803
 
3846
3804
    def _get_overrides(self):
3847
 
        # FIXME: Hack around library_state.initialize never called
 
3805
        # Hack around library_state.initialize never called
3848
3806
        if bzrlib.global_state is not None:
3849
3807
            return bzrlib.global_state.cmdline_overrides.get_sections()
3850
3808
        return []
3851
3809
 
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
3810
 
3889
3811
class MemoryStack(Stack):
3890
3812
    """A configuration stack defined from a string.
3940
3862
        self.store.save()
3941
3863
 
3942
3864
 
3943
 
class GlobalStack(Stack):
 
3865
class GlobalStack(_CompatibleStack):
3944
3866
    """Global options only stack.
3945
3867
 
3946
3868
    The following sections are queried:
3954
3876
    """
3955
3877
 
3956
3878
    def __init__(self):
3957
 
        gstore = self.get_shared_store(GlobalStore())
 
3879
        gstore = GlobalStore()
3958
3880
        super(GlobalStack, self).__init__(
3959
3881
            [self._get_overrides,
3960
3882
             NameMatcher(gstore, 'DEFAULT').get_sections],
3961
3883
            gstore, mutable_section_id='DEFAULT')
3962
3884
 
3963
3885
 
3964
 
class LocationStack(Stack):
 
3886
class LocationStack(_CompatibleStack):
3965
3887
    """Per-location options falling back to global options stack.
3966
3888
 
3967
3889
 
3983
3905
        """Make a new stack for a location and global configuration.
3984
3906
 
3985
3907
        :param location: A URL prefix to """
3986
 
        lstore = self.get_shared_store(LocationStore())
 
3908
        lstore = LocationStore()
3987
3909
        if location.startswith('file://'):
3988
3910
            location = urlutils.local_path_from_url(location)
3989
 
        gstore = self.get_shared_store(GlobalStore())
 
3911
        gstore = GlobalStore()
3990
3912
        super(LocationStack, self).__init__(
3991
3913
            [self._get_overrides,
3992
3914
             LocationMatcher(lstore, location).get_sections,
4014
3936
    """
4015
3937
 
4016
3938
    def __init__(self, branch):
4017
 
        lstore = self.get_shared_store(LocationStore())
 
3939
        lstore = LocationStore()
4018
3940
        bstore = branch._get_config_store()
4019
 
        gstore = self.get_shared_store(GlobalStore())
 
3941
        gstore = GlobalStore()
4020
3942
        super(BranchStack, self).__init__(
4021
3943
            [self._get_overrides,
4022
3944
             LocationMatcher(lstore, branch.base).get_sections,
4044
3966
        # unlock saves all the changes.
4045
3967
 
4046
3968
 
4047
 
class RemoteControlStack(Stack):
 
3969
class RemoteControlStack(_CompatibleStack):
4048
3970
    """Remote control-only options stack."""
4049
3971
 
4050
3972
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
4095
4017
class cmd_config(commands.Command):
4096
4018
    __doc__ = """Display, set or remove a configuration option.
4097
4019
 
4098
 
    Display the active value for option NAME.
 
4020
    Display the active value for a given option.
4099
4021
 
4100
4022
    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
 
4023
    matching options are displayed mentioning their scope. The active value
 
4024
    that bzr will take into account is the first one displayed for each option.
 
4025
 
 
4026
    If no NAME is given, --all .* is implied.
 
4027
 
 
4028
    Setting a value is achieved by using name=value without spaces. The value
4109
4029
    is set in the most relevant scope and can be checked by displaying the
4110
4030
    option again.
4111
 
 
4112
 
    Removing a value is achieved by using --remove NAME.
4113
4031
    """
4114
4032
 
4115
4033
    takes_args = ['name?']
4136
4054
            remove=False):
4137
4055
        if directory is None:
4138
4056
            directory = '.'
4139
 
        directory = directory_service.directories.dereference(directory)
4140
4057
        directory = urlutils.normalize_url(directory)
4141
4058
        if remove and all:
4142
4059
            raise errors.BzrError(
4245
4162
    def _set_config_option(self, name, value, directory, scope):
4246
4163
        conf = self._get_stack(directory, scope, write_access=True)
4247
4164
        conf.set(name, value)
4248
 
        # Explicitly save the changes
4249
 
        conf.store.save_changes()
4250
4165
 
4251
4166
    def _remove_config_option(self, name, directory, scope):
4252
4167
        if name is None:
4255
4170
        conf = self._get_stack(directory, scope, write_access=True)
4256
4171
        try:
4257
4172
            conf.remove(name)
4258
 
            # Explicitly save the changes
4259
 
            conf.store.save_changes()
4260
4173
        except KeyError:
4261
4174
            raise errors.NoSuchConfigOption(name)
4262
4175