~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Patch Queue Manager
  • Date: 2011-10-14 16:54:26 UTC
  • mfrom: (6216.1.1 remove-this-file)
  • Revision ID: pqm@pqm.ubuntu.com-20111014165426-tjix4e6idryf1r2z
(jelmer) Remove an accidentally committed .THIS file. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
72
72
up=pull
73
73
"""
74
74
 
75
 
from __future__ import absolute_import
76
 
from cStringIO import StringIO
77
75
import os
 
76
import string
78
77
import sys
79
78
 
 
79
 
80
80
import bzrlib
81
81
from bzrlib.decorators import needs_write_lock
82
82
from bzrlib.lazy_import import lazy_import
83
83
lazy_import(globals(), """
84
84
import fnmatch
85
85
import re
 
86
from cStringIO import StringIO
86
87
 
87
88
from bzrlib import (
88
89
    atomicfile,
151
152
STORE_GLOBAL = 4
152
153
 
153
154
 
154
 
def signature_policy_from_unicode(signature_string):
155
 
    """Convert a string to a signing policy."""
156
 
    if signature_string.lower() == 'check-available':
157
 
        return CHECK_IF_POSSIBLE
158
 
    if signature_string.lower() == 'ignore':
159
 
        return CHECK_NEVER
160
 
    if signature_string.lower() == 'require':
161
 
        return CHECK_ALWAYS
162
 
    raise ValueError("Invalid signatures policy '%s'"
163
 
                     % signature_string)
164
 
 
165
 
 
166
 
def signing_policy_from_unicode(signature_string):
167
 
    """Convert a string to a signing policy."""
168
 
    if signature_string.lower() == 'when-required':
169
 
        return SIGN_WHEN_REQUIRED
170
 
    if signature_string.lower() == 'never':
171
 
        return SIGN_NEVER
172
 
    if signature_string.lower() == 'always':
173
 
        return SIGN_ALWAYS
174
 
    raise ValueError("Invalid signing policy '%s'"
175
 
                     % signature_string)
176
 
 
177
 
 
178
155
class ConfigObj(configobj.ConfigObj):
179
156
 
180
157
    def __init__(self, infile=None, **kwargs):
440
417
            # add) the final ','
441
418
            l = [l]
442
419
        return l
443
 
 
444
 
    @deprecated_method(deprecated_in((2, 5, 0)))
445
 
    def get_user_option_as_int_from_SI(self, option_name, default=None):
 
420
        
 
421
    def get_user_option_as_int_from_SI(self,  option_name,  default=None):
446
422
        """Get a generic option from a human readable size in SI units, e.g 10MB
447
 
 
 
423
        
448
424
        Accepted suffixes are K,M,G. It is case-insensitive and may be followed
449
425
        by a trailing b (i.e. Kb, MB). This is intended to be practical and not
450
426
        pedantic.
451
 
 
 
427
        
452
428
        :return Integer, expanded to its base-10 value if a proper SI unit is 
453
429
            found. If the option doesn't exist, or isn't a value in 
454
430
            SI units, return default (which defaults to None)
479
455
            except TypeError:
480
456
                val = default
481
457
        return val
 
458
        
482
459
 
483
 
    @deprecated_method(deprecated_in((2, 5, 0)))
484
460
    def gpg_signing_command(self):
485
461
        """What program should be used to sign signatures?"""
486
462
        result = self._gpg_signing_command()
492
468
        """See gpg_signing_command()."""
493
469
        return None
494
470
 
495
 
    @deprecated_method(deprecated_in((2, 5, 0)))
496
471
    def log_format(self):
497
472
        """What log format should be used"""
498
473
        result = self._log_format()
517
492
        """See validate_signatures_in_log()."""
518
493
        return None
519
494
 
520
 
    @deprecated_method(deprecated_in((2, 5, 0)))
521
495
    def acceptable_keys(self):
522
496
        """Comma separated list of key patterns acceptable to 
523
497
        verify-signatures command"""
528
502
        """See acceptable_keys()."""
529
503
        return None
530
504
 
531
 
    @deprecated_method(deprecated_in((2, 5, 0)))
532
505
    def post_commit(self):
533
506
        """An ordered list of python functions to call.
534
507
 
560
533
        v = self._get_user_id()
561
534
        if v:
562
535
            return v
563
 
        return default_email()
 
536
        v = os.environ.get('EMAIL')
 
537
        if v:
 
538
            return v.decode(osutils.get_user_encoding())
 
539
        name, email = _auto_user_id()
 
540
        if name and email:
 
541
            return '%s <%s>' % (name, email)
 
542
        elif email:
 
543
            return email
 
544
        raise errors.NoWhoami()
564
545
 
565
546
    def ensure_username(self):
566
547
        """Raise errors.NoWhoami if username is not set.
569
550
        """
570
551
        self.username()
571
552
 
572
 
    @deprecated_method(deprecated_in((2, 5, 0)))
573
553
    def signature_checking(self):
574
554
        """What is the current policy for signature checking?."""
575
555
        policy = self._get_signature_checking()
577
557
            return policy
578
558
        return CHECK_IF_POSSIBLE
579
559
 
580
 
    @deprecated_method(deprecated_in((2, 5, 0)))
581
560
    def signing_policy(self):
582
561
        """What is the current policy for signature checking?."""
583
562
        policy = self._get_signing_policy()
585
564
            return policy
586
565
        return SIGN_WHEN_REQUIRED
587
566
 
588
 
    @deprecated_method(deprecated_in((2, 5, 0)))
589
567
    def signature_needed(self):
590
568
        """Is a signature needed when committing ?."""
591
569
        policy = self._get_signing_policy()
600
578
            return True
601
579
        return False
602
580
 
603
 
    @deprecated_method(deprecated_in((2, 5, 0)))
604
581
    def gpg_signing_key(self):
605
582
        """GPG user-id to sign commits"""
606
583
        key = self.get_user_option('gpg_signing_key')
891
868
        """See Config._get_signature_checking."""
892
869
        policy = self._get_user_option('check_signatures')
893
870
        if policy:
894
 
            return signature_policy_from_unicode(policy)
 
871
            return self._string_to_signature_policy(policy)
895
872
 
896
873
    def _get_signing_policy(self):
897
874
        """See Config._get_signing_policy"""
898
875
        policy = self._get_user_option('create_signatures')
899
876
        if policy:
900
 
            return signing_policy_from_unicode(policy)
 
877
            return self._string_to_signing_policy(policy)
901
878
 
902
879
    def _get_user_id(self):
903
880
        """Get the user id from the 'email' key in the current section."""
948
925
        """See Config.post_commit."""
949
926
        return self._get_user_option('post_commit')
950
927
 
 
928
    def _string_to_signature_policy(self, signature_string):
 
929
        """Convert a string to a signing policy."""
 
930
        if signature_string.lower() == 'check-available':
 
931
            return CHECK_IF_POSSIBLE
 
932
        if signature_string.lower() == 'ignore':
 
933
            return CHECK_NEVER
 
934
        if signature_string.lower() == 'require':
 
935
            return CHECK_ALWAYS
 
936
        raise errors.BzrError("Invalid signatures policy '%s'"
 
937
                              % signature_string)
 
938
 
 
939
    def _string_to_signing_policy(self, signature_string):
 
940
        """Convert a string to a signing policy."""
 
941
        if signature_string.lower() == 'when-required':
 
942
            return SIGN_WHEN_REQUIRED
 
943
        if signature_string.lower() == 'never':
 
944
            return SIGN_NEVER
 
945
        if signature_string.lower() == 'always':
 
946
            return SIGN_ALWAYS
 
947
        raise errors.BzrError("Invalid signing policy '%s'"
 
948
                              % signature_string)
 
949
 
951
950
    def _get_alias(self, value):
952
951
        try:
953
952
            return self._get_parser().get_value("ALIASES",
1397
1396
        e.g. "John Hacker <jhacker@example.com>"
1398
1397
        This is looked up in the email controlfile for the branch.
1399
1398
        """
 
1399
        try:
 
1400
            return (self.branch._transport.get_bytes("email")
 
1401
                    .decode(osutils.get_user_encoding())
 
1402
                    .rstrip("\r\n"))
 
1403
        except (errors.NoSuchFile, errors.PermissionDenied), e:
 
1404
            pass
 
1405
 
1400
1406
        return self._get_best_value('_get_user_id')
1401
1407
 
1402
1408
    def _get_change_editor(self):
1482
1488
        value = self._get_explicit_nickname()
1483
1489
        if value is not None:
1484
1490
            return value
1485
 
        if self.branch.name:
1486
 
            return self.branch.name
1487
1491
        return urlutils.unescape(self.branch.base.split('/')[-2])
1488
1492
 
1489
1493
    def has_explicit_nickname(self):
1526
1530
 
1527
1531
 
1528
1532
def config_dir():
1529
 
    """Return per-user configuration directory as unicode string
 
1533
    """Return per-user configuration directory.
1530
1534
 
1531
1535
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1532
1536
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1534
1538
 
1535
1539
    TODO: Global option --config-dir to override this.
1536
1540
    """
1537
 
    base = osutils.path_from_environ('BZR_HOME')
 
1541
    base = os.environ.get('BZR_HOME', None)
1538
1542
    if sys.platform == 'win32':
1539
 
        if base is None:
1540
 
            base = win32utils.get_appdata_location()
1541
 
        if base is None:
1542
 
            base = win32utils.get_home_location()
1543
 
        # GZ 2012-02-01: Really the two level subdirs only make sense inside
1544
 
        #                APPDATA, but hard to move. See bug 348640 for more.
 
1543
        # environ variables on Windows are in user encoding/mbcs. So decode
 
1544
        # before using one
 
1545
        if base is not None:
 
1546
            base = base.decode('mbcs')
 
1547
        if base is None:
 
1548
            base = win32utils.get_appdata_location_unicode()
 
1549
        if base is None:
 
1550
            base = os.environ.get('HOME', None)
 
1551
            if base is not None:
 
1552
                base = base.decode('mbcs')
 
1553
        if base is None:
 
1554
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
 
1555
                                  ' or HOME set')
1545
1556
        return osutils.pathjoin(base, 'bazaar', '2.0')
1546
 
    if base is None:
1547
 
        # GZ 2012-02-01: What should OSX use instead of XDG if anything?
1548
 
        if sys.platform != 'darwin':
1549
 
            xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
 
1557
    else:
 
1558
        if base is not None:
 
1559
            base = base.decode(osutils._fs_enc)
 
1560
    if sys.platform == 'darwin':
 
1561
        if base is None:
 
1562
            # this takes into account $HOME
 
1563
            base = os.path.expanduser("~")
 
1564
        return osutils.pathjoin(base, '.bazaar')
 
1565
    else:
 
1566
        if base is None:
 
1567
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1550
1568
            if xdg_dir is None:
1551
 
                xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
 
1569
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1552
1570
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1553
1571
            if osutils.isdir(xdg_dir):
1554
1572
                trace.mutter(
1555
1573
                    "Using configuration in XDG directory %s." % xdg_dir)
1556
1574
                return xdg_dir
1557
 
        base = osutils._get_home_dir()
1558
 
    return osutils.pathjoin(base, ".bazaar")
 
1575
            base = os.path.expanduser("~")
 
1576
        return osutils.pathjoin(base, ".bazaar")
1559
1577
 
1560
1578
 
1561
1579
def config_filename():
1624
1642
        f.close()
1625
1643
 
1626
1644
 
1627
 
def default_email():
1628
 
    v = os.environ.get('BZR_EMAIL')
1629
 
    if v:
1630
 
        return v.decode(osutils.get_user_encoding())
1631
 
    v = os.environ.get('EMAIL')
1632
 
    if v:
1633
 
        return v.decode(osutils.get_user_encoding())
1634
 
    name, email = _auto_user_id()
1635
 
    if name and email:
1636
 
        return u'%s <%s>' % (name, email)
1637
 
    elif email:
1638
 
        return email
1639
 
    raise errors.NoWhoami()
1640
 
 
1641
 
 
1642
1645
def _auto_user_id():
1643
1646
    """Calculate automatic user identification.
1644
1647
 
1833
1836
        :param user: login (optional)
1834
1837
 
1835
1838
        :param path: the absolute path on the server (optional)
1836
 
 
 
1839
        
1837
1840
        :param realm: the http authentication realm (optional)
1838
1841
 
1839
1842
        :return: A dict containing the matching credentials or None.
2319
2322
    encoutered, in which config files it can be stored.
2320
2323
    """
2321
2324
 
2322
 
    def __init__(self, name, override_from_env=None,
2323
 
                 default=None, default_from_env=None,
2324
 
                 help=None, from_unicode=None, invalid=None, unquote=True):
 
2325
    def __init__(self, name, default=None, default_from_env=None,
 
2326
                 help=None,
 
2327
                 from_unicode=None, invalid=None):
2325
2328
        """Build an option definition.
2326
2329
 
2327
2330
        :param name: the name used to refer to the option.
2328
2331
 
2329
 
        :param override_from_env: A list of environment variables which can
2330
 
           provide override any configuration setting.
2331
 
 
2332
2332
        :param default: the default value to use when none exist in the config
2333
2333
            stores. This is either a string that ``from_unicode`` will convert
2334
 
            into the proper type, a callable returning a unicode string so that
2335
 
            ``from_unicode`` can be used on the return value, or a python
2336
 
            object that can be stringified (so only the empty list is supported
2337
 
            for example).
 
2334
            into the proper type or a python object that can be stringified (so
 
2335
            only the empty list is supported for example).
2338
2336
 
2339
2337
        :param default_from_env: A list of environment variables which can
2340
2338
           provide a default value. 'default' will be used only if none of the
2352
2350
            TypeError. Accepted values are: None (ignore invalid values),
2353
2351
            'warning' (emit a warning), 'error' (emit an error message and
2354
2352
            terminates).
2355
 
 
2356
 
        :param unquote: should the unicode value be unquoted before conversion.
2357
 
           This should be used only when the store providing the values cannot
2358
 
           safely unquote them (see http://pad.lv/906897). It is provided so
2359
 
           daughter classes can handle the quoting themselves.
2360
2353
        """
2361
 
        if override_from_env is None:
2362
 
            override_from_env = []
2363
2354
        if default_from_env is None:
2364
2355
            default_from_env = []
2365
2356
        self.name = name
2366
 
        self.override_from_env = override_from_env
2367
2357
        # Convert the default value to a unicode string so all values are
2368
2358
        # strings internally before conversion (via from_unicode) is attempted.
2369
2359
        if default is None:
2377
2367
        elif isinstance(default, (str, unicode, bool, int, float)):
2378
2368
            # Rely on python to convert strings, booleans and integers
2379
2369
            self.default = u'%s' % (default,)
2380
 
        elif callable(default):
2381
 
            self.default = default
2382
2370
        else:
2383
2371
            # other python objects are not expected
2384
2372
            raise AssertionError('%r is not supported as a default value'
2386
2374
        self.default_from_env = default_from_env
2387
2375
        self.help = help
2388
2376
        self.from_unicode = from_unicode
2389
 
        self.unquote = unquote
2390
2377
        if invalid and invalid not in ('warning', 'error'):
2391
2378
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2392
2379
        self.invalid = invalid
2393
2380
 
2394
 
    def convert_from_unicode(self, store, unicode_value):
2395
 
        if self.unquote and store is not None and unicode_value is not None:
2396
 
            unicode_value = store.unquote(unicode_value)
 
2381
    def convert_from_unicode(self, unicode_value):
2397
2382
        if self.from_unicode is None or unicode_value is None:
2398
2383
            # Don't convert or nothing to convert
2399
2384
            return unicode_value
2411
2396
                raise errors.ConfigOptionValueError(self.name, unicode_value)
2412
2397
        return converted
2413
2398
 
2414
 
    def get_override(self):
2415
 
        value = None
2416
 
        for var in self.override_from_env:
2417
 
            try:
2418
 
                # If the env variable is defined, its value takes precedence
2419
 
                value = os.environ[var].decode(osutils.get_user_encoding())
2420
 
                break
2421
 
            except KeyError:
2422
 
                continue
2423
 
        return value
2424
 
 
2425
2399
    def get_default(self):
2426
2400
        value = None
2427
2401
        for var in self.default_from_env:
2428
2402
            try:
2429
2403
                # If the env variable is defined, its value is the default one
2430
 
                value = os.environ[var].decode(osutils.get_user_encoding())
 
2404
                value = os.environ[var]
2431
2405
                break
2432
2406
            except KeyError:
2433
2407
                continue
2434
2408
        if value is None:
2435
2409
            # Otherwise, fallback to the value defined at registration
2436
 
            if callable(self.default):
2437
 
                value = self.default()
2438
 
                if not isinstance(value, unicode):
2439
 
                    raise AssertionError(
2440
 
                    'Callable default values should be unicode')
2441
 
            else:
2442
 
                value = self.default
 
2410
            value = self.default
2443
2411
        return value
2444
2412
 
2445
2413
    def get_help_text(self, additional_see_also=None, plain=True):
2461
2429
    return int(unicode_str)
2462
2430
 
2463
2431
 
2464
 
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2465
 
 
2466
 
def int_SI_from_store(unicode_str):
2467
 
    """Convert a human readable size in SI units, e.g 10MB into an integer.
2468
 
 
2469
 
    Accepted suffixes are K,M,G. It is case-insensitive and may be followed
2470
 
    by a trailing b (i.e. Kb, MB). This is intended to be practical and not
2471
 
    pedantic.
2472
 
 
2473
 
    :return Integer, expanded to its base-10 value if a proper SI unit is 
2474
 
        found, None otherwise.
2475
 
    """
2476
 
    regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
2477
 
    p = re.compile(regexp, re.IGNORECASE)
2478
 
    m = p.match(unicode_str)
2479
 
    val = None
2480
 
    if m is not None:
2481
 
        val, _, unit = m.groups()
2482
 
        val = int(val)
2483
 
        if unit:
2484
 
            try:
2485
 
                coeff = _unit_suffixes[unit.upper()]
2486
 
            except KeyError:
2487
 
                raise ValueError(gettext('{0} is not an SI unit.').format(unit))
2488
 
            val *= coeff
2489
 
    return val
2490
 
 
2491
 
 
2492
2432
def float_from_store(unicode_str):
2493
2433
    return float(unicode_str)
2494
2434
 
2495
2435
 
 
2436
 
2496
2437
# Use a an empty dict to initialize an empty configobj avoiding all
2497
2438
# parsing and encoding checks
2498
2439
_list_converter_config = configobj.ConfigObj(
2499
2440
    {}, encoding='utf-8', list_values=True, interpolation=False)
2500
2441
 
2501
2442
 
2502
 
class ListOption(Option):
2503
 
 
2504
 
    def __init__(self, name, default=None, default_from_env=None,
2505
 
                 help=None, invalid=None):
2506
 
        """A list Option definition.
2507
 
 
2508
 
        This overrides the base class so the conversion from a unicode string
2509
 
        can take quoting into account.
2510
 
        """
2511
 
        super(ListOption, self).__init__(
2512
 
            name, default=default, default_from_env=default_from_env,
2513
 
            from_unicode=self.from_unicode, help=help,
2514
 
            invalid=invalid, unquote=False)
2515
 
 
2516
 
    def from_unicode(self, unicode_str):
2517
 
        if not isinstance(unicode_str, basestring):
2518
 
            raise TypeError
2519
 
        # Now inject our string directly as unicode. All callers got their
2520
 
        # value from configobj, so values that need to be quoted are already
2521
 
        # properly quoted.
2522
 
        _list_converter_config.reset()
2523
 
        _list_converter_config._parse([u"list=%s" % (unicode_str,)])
2524
 
        maybe_list = _list_converter_config['list']
2525
 
        if isinstance(maybe_list, basestring):
2526
 
            if maybe_list:
2527
 
                # A single value, most probably the user forgot (or didn't care
2528
 
                # to add) the final ','
2529
 
                l = [maybe_list]
2530
 
            else:
2531
 
                # The empty string, convert to empty list
2532
 
                l = []
 
2443
def list_from_store(unicode_str):
 
2444
    if not isinstance(unicode_str, basestring):
 
2445
        raise TypeError
 
2446
    # Now inject our string directly as unicode. All callers got their value
 
2447
    # from configobj, so values that need to be quoted are already properly
 
2448
    # quoted.
 
2449
    _list_converter_config.reset()
 
2450
    _list_converter_config._parse([u"list=%s" % (unicode_str,)])
 
2451
    maybe_list = _list_converter_config['list']
 
2452
    # ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
 
2453
    if isinstance(maybe_list, basestring):
 
2454
        if maybe_list:
 
2455
            # A single value, most probably the user forgot (or didn't care to
 
2456
            # add) the final ','
 
2457
            l = [maybe_list]
2533
2458
        else:
2534
 
            # We rely on ConfigObj providing us with a list already
2535
 
            l = maybe_list
2536
 
        return l
 
2459
            # The empty string, convert to empty list
 
2460
            l = []
 
2461
    else:
 
2462
        # We rely on ConfigObj providing us with a list already
 
2463
        l = maybe_list
 
2464
    return l
2537
2465
 
2538
2466
 
2539
2467
class OptionRegistry(registry.Registry):
2580
2508
# Registered options in lexicographical order
2581
2509
 
2582
2510
option_registry.register(
2583
 
    Option('append_revisions_only',
2584
 
           default=None, from_unicode=bool_from_store, invalid='warning',
2585
 
           help='''\
2586
 
Whether to only append revisions to the mainline.
2587
 
 
2588
 
If this is set to true, then it is not possible to change the
2589
 
existing mainline of the branch.
2590
 
'''))
2591
 
option_registry.register(
2592
 
    ListOption('acceptable_keys',
2593
 
           default=None,
2594
 
           help="""\
2595
 
List of GPG key patterns which are acceptable for verification.
2596
 
"""))
2597
 
option_registry.register(
2598
 
    Option('add.maximum_file_size',
2599
 
           default=u'20MB', from_unicode=int_SI_from_store,
2600
 
           help="""\
2601
 
Size above which files should be added manually.
2602
 
 
2603
 
Files below this size are added automatically when using ``bzr add`` without
2604
 
arguments.
2605
 
 
2606
 
A negative value means disable the size check.
2607
 
"""))
2608
 
option_registry.register(
2609
 
    Option('bound',
2610
 
           default=None, from_unicode=bool_from_store,
2611
 
           help="""\
2612
 
Is the branch bound to ``bound_location``.
2613
 
 
2614
 
If set to "True", the branch should act as a checkout, and push each commit to
2615
 
the bound_location.  This option is normally set by ``bind``/``unbind``.
2616
 
 
2617
 
See also: bound_location.
2618
 
"""))
2619
 
option_registry.register(
2620
 
    Option('bound_location',
2621
 
           default=None,
2622
 
           help="""\
2623
 
The location that commits should go to when acting as a checkout.
2624
 
 
2625
 
This option is normally set by ``bind``.
2626
 
 
2627
 
See also: bound.
2628
 
"""))
2629
 
option_registry.register(
2630
 
    Option('branch.fetch_tags', default=False,  from_unicode=bool_from_store,
2631
 
           help="""\
2632
 
Whether revisions associated with tags should be fetched.
2633
 
"""))
2634
 
option_registry.register(
2635
2511
    Option('bzr.workingtree.worth_saving_limit', default=10,
2636
2512
           from_unicode=int_from_store,  invalid='warning',
2637
2513
           help='''\
2644
2520
a file has been touched.
2645
2521
'''))
2646
2522
option_registry.register(
2647
 
    Option('check_signatures', default=CHECK_IF_POSSIBLE,
2648
 
           from_unicode=signature_policy_from_unicode,
2649
 
           help='''\
2650
 
GPG checking policy.
2651
 
 
2652
 
Possible values: require, ignore, check-available (default)
2653
 
 
2654
 
this option will control whether bzr will require good gpg
2655
 
signatures, ignore them, or check them if they are
2656
 
present.
2657
 
'''))
2658
 
option_registry.register(
2659
 
    Option('child_submit_format',
2660
 
           help='''The preferred format of submissions to this branch.'''))
2661
 
option_registry.register(
2662
 
    Option('child_submit_to',
2663
 
           help='''Where submissions to this branch are mailed to.'''))
2664
 
option_registry.register(
2665
 
    Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2666
 
           from_unicode=signing_policy_from_unicode,
2667
 
           help='''\
2668
 
GPG Signing policy.
2669
 
 
2670
 
Possible values: always, never, when-required (default)
2671
 
 
2672
 
This option controls whether bzr will always create
2673
 
gpg signatures or not on commits.
2674
 
'''))
2675
 
option_registry.register(
2676
2523
    Option('dirstate.fdatasync', default=True,
2677
2524
           from_unicode=bool_from_store,
2678
2525
           help='''\
2683
2530
should not be lost if the machine crashes.  See also repository.fdatasync.
2684
2531
'''))
2685
2532
option_registry.register(
2686
 
    ListOption('debug_flags', default=[],
 
2533
    Option('debug_flags', default=[], from_unicode=list_from_store,
2687
2534
           help='Debug flags to activate.'))
2688
2535
option_registry.register(
2689
2536
    Option('default_format', default='2a',
2702
2549
    Option('editor',
2703
2550
           help='The command called to launch an editor to enter a message.'))
2704
2551
option_registry.register(
2705
 
    Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2706
 
           help='The users identity'))
2707
 
option_registry.register(
2708
 
    Option('gpg_signing_command',
2709
 
           default='gpg',
2710
 
           help="""\
2711
 
Program to use use for creating signatures.
2712
 
 
2713
 
This should support at least the -u and --clearsign options.
2714
 
"""))
2715
 
option_registry.register(
2716
 
    Option('gpg_signing_key',
2717
 
           default=None,
2718
 
           help="""\
2719
 
GPG key to use for signing.
2720
 
 
2721
 
This defaults to the first key associated with the users email.
2722
 
"""))
2723
 
option_registry.register(
2724
2552
    Option('ignore_missing_extensions', default=False,
2725
2553
           from_unicode=bool_from_store,
2726
2554
           help='''\
2756
2584
           help= 'Unicode encoding for output'
2757
2585
           ' (terminal encoding if not specified).'))
2758
2586
option_registry.register(
2759
 
    Option('parent_location',
2760
 
           default=None,
2761
 
           help="""\
2762
 
The location of the default branch for pull or merge.
2763
 
 
2764
 
This option is normally set when creating a branch, the first ``pull`` or by
2765
 
``pull --remember``.
2766
 
"""))
2767
 
option_registry.register(
2768
 
    Option('post_commit', default=None,
2769
 
           help='''\
2770
 
Post commit functions.
2771
 
 
2772
 
An ordered list of python functions to call, separated by spaces.
2773
 
 
2774
 
Each function takes branch, rev_id as parameters.
2775
 
'''))
2776
 
option_registry.register(
2777
 
    Option('public_branch',
2778
 
           default=None,
2779
 
           help="""\
2780
 
A publically-accessible version of this branch.
2781
 
 
2782
 
This implies that the branch setting this option is not publically-accessible.
2783
 
Used and set by ``bzr send``.
2784
 
"""))
2785
 
option_registry.register(
2786
 
    Option('push_location',
2787
 
           default=None,
2788
 
           help="""\
2789
 
The location of the default branch for push.
2790
 
 
2791
 
This option is normally set by the first ``push`` or ``push --remember``.
2792
 
"""))
2793
 
option_registry.register(
2794
2587
    Option('push_strict', default=None,
2795
2588
           from_unicode=bool_from_store,
2796
2589
           help='''\
2809
2602
to physical disk.  This is somewhat slower, but means data should not be
2810
2603
lost if the machine crashes.  See also dirstate.fdatasync.
2811
2604
'''))
2812
 
option_registry.register_lazy('smtp_server',
2813
 
    'bzrlib.smtp_connection', 'smtp_server')
2814
 
option_registry.register_lazy('smtp_password',
2815
 
    'bzrlib.smtp_connection', 'smtp_password')
2816
 
option_registry.register_lazy('smtp_username',
2817
 
    'bzrlib.smtp_connection', 'smtp_username')
2818
 
option_registry.register(
2819
 
    Option('selftest.timeout',
2820
 
        default='600',
2821
 
        from_unicode=int_from_store,
2822
 
        help='Abort selftest if one test takes longer than this many seconds',
2823
 
        ))
2824
 
 
2825
2605
option_registry.register(
2826
2606
    Option('send_strict', default=None,
2827
2607
           from_unicode=bool_from_store,
2829
2609
The default value for ``send --strict``.
2830
2610
 
2831
2611
If present, defines the ``--strict`` option default value for checking
2832
 
uncommitted changes before sending a bundle.
 
2612
uncommitted changes before pushing.
2833
2613
'''))
2834
2614
 
2835
2615
option_registry.register(
2837
2617
           default=300.0, from_unicode=float_from_store,
2838
2618
           help="If we wait for a new request from a client for more than"
2839
2619
                " X seconds, consider the client idle, and hangup."))
2840
 
option_registry.register(
2841
 
    Option('stacked_on_location',
2842
 
           default=None,
2843
 
           help="""The location where this branch is stacked on."""))
2844
 
option_registry.register(
2845
 
    Option('submit_branch',
2846
 
           default=None,
2847
 
           help="""\
2848
 
The branch you intend to submit your current work to.
2849
 
 
2850
 
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2851
 
by the ``submit:`` revision spec.
2852
 
"""))
2853
 
option_registry.register(
2854
 
    Option('submit_to',
2855
 
           help='''Where submissions from this branch are mailed to.'''))
2856
 
 
2857
 
option_registry.register_lazy('ssl.ca_certs',
2858
 
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2859
 
 
2860
 
option_registry.register_lazy('ssl.cert_reqs',
2861
 
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2862
 
 
2863
2620
 
2864
2621
 
2865
2622
class Section(object):
2875
2632
        # We re-use the dict-like object received
2876
2633
        self.options = options
2877
2634
 
2878
 
    def get(self, name, default=None, expand=True):
 
2635
    def get(self, name, default=None):
2879
2636
        return self.options.get(name, default)
2880
2637
 
2881
 
    def iter_option_names(self):
2882
 
        for k in self.options.iterkeys():
2883
 
            yield k
2884
 
 
2885
2638
    def __repr__(self):
2886
2639
        # Mostly for debugging use
2887
2640
        return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2889
2642
 
2890
2643
_NewlyCreatedOption = object()
2891
2644
"""Was the option created during the MutableSection lifetime"""
2892
 
_DeletedOption = object()
2893
 
"""Was the option deleted during the MutableSection lifetime"""
2894
2645
 
2895
2646
 
2896
2647
class MutableSection(Section):
2898
2649
 
2899
2650
    def __init__(self, section_id, options):
2900
2651
        super(MutableSection, self).__init__(section_id, options)
2901
 
        self.reset_changes()
 
2652
        self.orig = {}
2902
2653
 
2903
2654
    def set(self, name, value):
2904
2655
        if name not in self.options:
2913
2664
            self.orig[name] = self.get(name, None)
2914
2665
        del self.options[name]
2915
2666
 
2916
 
    def reset_changes(self):
2917
 
        self.orig = {}
2918
 
 
2919
 
    def apply_changes(self, dirty, store):
2920
 
        """Apply option value changes.
2921
 
 
2922
 
        ``self`` has been reloaded from the persistent storage. ``dirty``
2923
 
        contains the changes made since the previous loading.
2924
 
 
2925
 
        :param dirty: the mutable section containing the changes.
2926
 
 
2927
 
        :param store: the store containing the section
2928
 
        """
2929
 
        for k, expected in dirty.orig.iteritems():
2930
 
            actual = dirty.get(k, _DeletedOption)
2931
 
            reloaded = self.get(k, _NewlyCreatedOption)
2932
 
            if actual is _DeletedOption:
2933
 
                if k in self.options:
2934
 
                    self.remove(k)
2935
 
            else:
2936
 
                self.set(k, actual)
2937
 
            # Report concurrent updates in an ad-hoc way. This should only
2938
 
            # occurs when different processes try to update the same option
2939
 
            # which is not supported (as in: the config framework is not meant
2940
 
            # to be used a sharing mechanism).
2941
 
            if expected != reloaded:
2942
 
                if actual is _DeletedOption:
2943
 
                    actual = '<DELETED>'
2944
 
                if reloaded is _NewlyCreatedOption:
2945
 
                    reloaded = '<CREATED>'
2946
 
                if expected is _NewlyCreatedOption:
2947
 
                    expected = '<CREATED>'
2948
 
                # Someone changed the value since we get it from the persistent
2949
 
                # storage.
2950
 
                trace.warning(gettext(
2951
 
                        "Option {0} in section {1} of {2} was changed"
2952
 
                        " from {3} to {4}. The {5} value will be saved.".format(
2953
 
                            k, self.id, store.external_url(), expected,
2954
 
                            reloaded, actual)))
2955
 
        # No need to keep track of these changes
2956
 
        self.reset_changes()
 
2667
 
 
2668
class CommandLineSection(MutableSection):
 
2669
    """A section used to carry command line overrides for the config options."""
 
2670
 
 
2671
    def __init__(self, opts=None):
 
2672
        if opts is None:
 
2673
            opts = {}
 
2674
        super(CommandLineSection, self).__init__('cmdline-overrides', opts)
 
2675
 
 
2676
    def _reset(self):
 
2677
        # The dict should be cleared but not replaced so it can be shared.
 
2678
        self.options.clear()
 
2679
 
 
2680
    def _from_cmdline(self, overrides):
 
2681
        # Reset before accepting new definitions
 
2682
        self._reset()
 
2683
        for over in overrides:
 
2684
            try:
 
2685
                name, value = over.split('=', 1)
 
2686
            except ValueError:
 
2687
                raise errors.BzrCommandError(
 
2688
                    gettext("Invalid '%s', should be of the form 'name=value'")
 
2689
                    % (over,))
 
2690
            self.set(name, value)
2957
2691
 
2958
2692
 
2959
2693
class Store(object):
2962
2696
    readonly_section_class = Section
2963
2697
    mutable_section_class = MutableSection
2964
2698
 
2965
 
    def __init__(self):
2966
 
        # Which sections need to be saved
2967
 
        self.dirty_sections = []
2968
 
 
2969
2699
    def is_loaded(self):
2970
2700
        """Returns True if the Store has been loaded.
2971
2701
 
2994
2724
        """
2995
2725
        raise NotImplementedError(self.unload)
2996
2726
 
2997
 
    def quote(self, value):
2998
 
        """Quote a configuration option value for storing purposes.
2999
 
 
3000
 
        This allows Stacks to present values as they will be stored.
3001
 
        """
3002
 
        return value
3003
 
 
3004
 
    def unquote(self, value):
3005
 
        """Unquote a configuration option value into unicode.
3006
 
 
3007
 
        The received value is quoted as stored.
3008
 
        """
3009
 
        return value
3010
 
 
3011
2727
    def save(self):
3012
2728
        """Saves the Store to persistent storage."""
3013
2729
        raise NotImplementedError(self.save)
3014
2730
 
3015
 
    def _need_saving(self):
3016
 
        for s in self.dirty_sections:
3017
 
            if s.orig:
3018
 
                # At least one dirty section contains a modification
3019
 
                return True
3020
 
        return False
3021
 
 
3022
 
    def apply_changes(self, dirty_sections):
3023
 
        """Apply changes from dirty sections while checking for coherency.
3024
 
 
3025
 
        The Store content is discarded and reloaded from persistent storage to
3026
 
        acquire up-to-date values.
3027
 
 
3028
 
        Dirty sections are MutableSection which kept track of the value they
3029
 
        are expected to update.
3030
 
        """
3031
 
        # We need an up-to-date version from the persistent storage, unload the
3032
 
        # store. The reload will occur when needed (triggered by the first
3033
 
        # get_mutable_section() call below.
3034
 
        self.unload()
3035
 
        # Apply the changes from the preserved dirty sections
3036
 
        for dirty in dirty_sections:
3037
 
            clean = self.get_mutable_section(dirty.id)
3038
 
            clean.apply_changes(dirty, self)
3039
 
        # Everything is clean now
3040
 
        self.dirty_sections = []
3041
 
 
3042
 
    def save_changes(self):
3043
 
        """Saves the Store to persistent storage if changes occurred.
3044
 
 
3045
 
        Apply the changes recorded in the mutable sections to a store content
3046
 
        refreshed from persistent storage.
3047
 
        """
3048
 
        raise NotImplementedError(self.save_changes)
3049
 
 
3050
2731
    def external_url(self):
3051
2732
        raise NotImplementedError(self.external_url)
3052
2733
 
3053
2734
    def get_sections(self):
3054
2735
        """Returns an ordered iterable of existing sections.
3055
2736
 
3056
 
        :returns: An iterable of (store, section).
 
2737
        :returns: An iterable of (name, dict).
3057
2738
        """
3058
2739
        raise NotImplementedError(self.get_sections)
3059
2740
 
3060
 
    def get_mutable_section(self, section_id=None):
 
2741
    def get_mutable_section(self, section_name=None):
3061
2742
        """Returns the specified mutable section.
3062
2743
 
3063
 
        :param section_id: The section identifier
 
2744
        :param section_name: The section identifier
3064
2745
        """
3065
2746
        raise NotImplementedError(self.get_mutable_section)
3066
2747
 
3070
2751
                                    self.external_url())
3071
2752
 
3072
2753
 
3073
 
class CommandLineStore(Store):
3074
 
    "A store to carry command line overrides for the config options."""
3075
 
 
3076
 
    def __init__(self, opts=None):
3077
 
        super(CommandLineStore, self).__init__()
3078
 
        if opts is None:
3079
 
            opts = {}
3080
 
        self.options = {}
3081
 
        self.id = 'cmdline'
3082
 
 
3083
 
    def _reset(self):
3084
 
        # The dict should be cleared but not replaced so it can be shared.
3085
 
        self.options.clear()
3086
 
 
3087
 
    def _from_cmdline(self, overrides):
3088
 
        # Reset before accepting new definitions
3089
 
        self._reset()
3090
 
        for over in overrides:
3091
 
            try:
3092
 
                name, value = over.split('=', 1)
3093
 
            except ValueError:
3094
 
                raise errors.BzrCommandError(
3095
 
                    gettext("Invalid '%s', should be of the form 'name=value'")
3096
 
                    % (over,))
3097
 
            self.options[name] = value
3098
 
 
3099
 
    def external_url(self):
3100
 
        # Not an url but it makes debugging easier and is never needed
3101
 
        # otherwise
3102
 
        return 'cmdline'
3103
 
 
3104
 
    def get_sections(self):
3105
 
        yield self,  self.readonly_section_class(None, self.options)
3106
 
 
3107
 
 
3108
2754
class IniFileStore(Store):
3109
2755
    """A config Store using ConfigObj for storage.
3110
2756
 
 
2757
    :ivar transport: The transport object where the config file is located.
 
2758
 
 
2759
    :ivar file_name: The config file basename in the transport directory.
 
2760
 
3111
2761
    :ivar _config_obj: Private member to hold the ConfigObj instance used to
3112
2762
        serialize/deserialize the config file.
3113
2763
    """
3114
2764
 
3115
 
    def __init__(self):
 
2765
    def __init__(self, transport, file_name):
3116
2766
        """A config Store using ConfigObj for storage.
 
2767
 
 
2768
        :param transport: The transport object where the config file is located.
 
2769
 
 
2770
        :param file_name: The config file basename in the transport directory.
3117
2771
        """
3118
2772
        super(IniFileStore, self).__init__()
 
2773
        self.transport = transport
 
2774
        self.file_name = file_name
3119
2775
        self._config_obj = None
3120
2776
 
3121
2777
    def is_loaded(self):
3123
2779
 
3124
2780
    def unload(self):
3125
2781
        self._config_obj = None
3126
 
        self.dirty_sections = []
3127
 
 
3128
 
    def _load_content(self):
3129
 
        """Load the config file bytes.
3130
 
 
3131
 
        This should be provided by subclasses
3132
 
 
3133
 
        :return: Byte string
3134
 
        """
3135
 
        raise NotImplementedError(self._load_content)
3136
 
 
3137
 
    def _save_content(self, content):
3138
 
        """Save the config file bytes.
3139
 
 
3140
 
        This should be provided by subclasses
3141
 
 
3142
 
        :param content: Config file bytes to write
3143
 
        """
3144
 
        raise NotImplementedError(self._save_content)
3145
2782
 
3146
2783
    def load(self):
3147
2784
        """Load the store from the associated file."""
3148
2785
        if self.is_loaded():
3149
2786
            return
3150
 
        content = self._load_content()
 
2787
        try:
 
2788
            content = self.transport.get_bytes(self.file_name)
 
2789
        except errors.PermissionDenied:
 
2790
            trace.warning("Permission denied while trying to load "
 
2791
                          "configuration store %s.", self.external_url())
 
2792
            raise
3151
2793
        self._load_from_string(content)
3152
2794
        for hook in ConfigHooks['load']:
3153
2795
            hook(self)
3170
2812
        except UnicodeDecodeError:
3171
2813
            raise errors.ConfigContentError(self.external_url())
3172
2814
 
3173
 
    def save_changes(self):
3174
 
        if not self.is_loaded():
3175
 
            # Nothing to save
3176
 
            return
3177
 
        if not self._need_saving():
3178
 
            return
3179
 
        # Preserve the current version
3180
 
        current = self._config_obj
3181
 
        dirty_sections = list(self.dirty_sections)
3182
 
        self.apply_changes(dirty_sections)
3183
 
        # Save to the persistent storage
3184
 
        self.save()
3185
 
 
3186
2815
    def save(self):
3187
2816
        if not self.is_loaded():
3188
2817
            # Nothing to save
3189
2818
            return
3190
2819
        out = StringIO()
3191
2820
        self._config_obj.write(out)
3192
 
        self._save_content(out.getvalue())
 
2821
        self.transport.put_bytes(self.file_name, out.getvalue())
3193
2822
        for hook in ConfigHooks['save']:
3194
2823
            hook(self)
3195
2824
 
 
2825
    def external_url(self):
 
2826
        # FIXME: external_url should really accepts an optional relpath
 
2827
        # parameter (bug #750169) :-/ -- vila 2011-04-04
 
2828
        # The following will do in the interim but maybe we don't want to
 
2829
        # expose a path here but rather a config ID and its associated
 
2830
        # object </hand wawe>.
 
2831
        return urlutils.join(self.transport.external_url(), self.file_name)
 
2832
 
3196
2833
    def get_sections(self):
3197
2834
        """Get the configobj section in the file order.
3198
2835
 
3199
 
        :returns: An iterable of (store, section).
 
2836
        :returns: An iterable of (name, dict).
3200
2837
        """
3201
2838
        # We need a loaded store
3202
2839
        try:
3206
2843
            return
3207
2844
        cobj = self._config_obj
3208
2845
        if cobj.scalars:
3209
 
            yield self, self.readonly_section_class(None, cobj)
 
2846
            yield self.readonly_section_class(None, cobj)
3210
2847
        for section_name in cobj.sections:
3211
 
            yield (self,
3212
 
                   self.readonly_section_class(section_name,
3213
 
                                               cobj[section_name]))
 
2848
            yield self.readonly_section_class(section_name, cobj[section_name])
3214
2849
 
3215
 
    def get_mutable_section(self, section_id=None):
 
2850
    def get_mutable_section(self, section_name=None):
3216
2851
        # We need a loaded store
3217
2852
        try:
3218
2853
            self.load()
3219
2854
        except errors.NoSuchFile:
3220
2855
            # The file doesn't exist, let's pretend it was empty
3221
2856
            self._load_from_string('')
3222
 
        if section_id is None:
 
2857
        if section_name is None:
3223
2858
            section = self._config_obj
3224
2859
        else:
3225
 
            section = self._config_obj.setdefault(section_id, {})
3226
 
        mutable_section = self.mutable_section_class(section_id, section)
3227
 
        # All mutable sections can become dirty
3228
 
        self.dirty_sections.append(mutable_section)
3229
 
        return mutable_section
3230
 
 
3231
 
    def quote(self, value):
3232
 
        try:
3233
 
            # configobj conflates automagical list values and quoting
3234
 
            self._config_obj.list_values = True
3235
 
            return self._config_obj._quote(value)
3236
 
        finally:
3237
 
            self._config_obj.list_values = False
3238
 
 
3239
 
    def unquote(self, value):
3240
 
        if value and isinstance(value, basestring):
3241
 
            # _unquote doesn't handle None nor empty strings nor anything that
3242
 
            # is not a string, really.
3243
 
            value = self._config_obj._unquote(value)
3244
 
        return value
3245
 
 
3246
 
    def external_url(self):
3247
 
        # Since an IniFileStore can be used without a file (at least in tests),
3248
 
        # it's better to provide something than raising a NotImplementedError.
3249
 
        # All daughter classes are supposed to provide an implementation
3250
 
        # anyway.
3251
 
        return 'In-Process Store, no URL'
3252
 
 
3253
 
class TransportIniFileStore(IniFileStore):
3254
 
    """IniFileStore that loads files from a transport.
3255
 
 
3256
 
    :ivar transport: The transport object where the config file is located.
3257
 
 
3258
 
    :ivar file_name: The config file basename in the transport directory.
3259
 
    """
3260
 
 
3261
 
    def __init__(self, transport, file_name):
3262
 
        """A Store using a ini file on a Transport
3263
 
 
3264
 
        :param transport: The transport object where the config file is located.
3265
 
        :param file_name: The config file basename in the transport directory.
3266
 
        """
3267
 
        super(TransportIniFileStore, self).__init__()
3268
 
        self.transport = transport
3269
 
        self.file_name = file_name
3270
 
 
3271
 
    def _load_content(self):
3272
 
        try:
3273
 
            return self.transport.get_bytes(self.file_name)
3274
 
        except errors.PermissionDenied:
3275
 
            trace.warning("Permission denied while trying to load "
3276
 
                          "configuration store %s.", self.external_url())
3277
 
            raise
3278
 
 
3279
 
    def _save_content(self, content):
3280
 
        self.transport.put_bytes(self.file_name, content)
3281
 
 
3282
 
    def external_url(self):
3283
 
        # FIXME: external_url should really accepts an optional relpath
3284
 
        # parameter (bug #750169) :-/ -- vila 2011-04-04
3285
 
        # The following will do in the interim but maybe we don't want to
3286
 
        # expose a path here but rather a config ID and its associated
3287
 
        # object </hand wawe>.
3288
 
        return urlutils.join(self.transport.external_url(), self.file_name)
 
2860
            section = self._config_obj.setdefault(section_name, {})
 
2861
        return self.mutable_section_class(section_name, section)
3289
2862
 
3290
2863
 
3291
2864
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
3294
2867
# they may face the same issue.
3295
2868
 
3296
2869
 
3297
 
class LockableIniFileStore(TransportIniFileStore):
 
2870
class LockableIniFileStore(IniFileStore):
3298
2871
    """A ConfigObjStore using locks on save to ensure store integrity."""
3299
2872
 
3300
2873
    def __init__(self, transport, file_name, lock_dir_name=None):
3350
2923
        t = transport.get_transport_from_path(
3351
2924
            config_dir(), possible_transports=possible_transports)
3352
2925
        super(GlobalStore, self).__init__(t, 'bazaar.conf')
3353
 
        self.id = 'bazaar'
3354
2926
 
3355
2927
 
3356
2928
class LocationStore(LockableIniFileStore):
3359
2931
        t = transport.get_transport_from_path(
3360
2932
            config_dir(), possible_transports=possible_transports)
3361
2933
        super(LocationStore, self).__init__(t, 'locations.conf')
3362
 
        self.id = 'locations'
3363
 
 
3364
 
 
3365
 
class BranchStore(TransportIniFileStore):
 
2934
 
 
2935
 
 
2936
class BranchStore(IniFileStore):
3366
2937
 
3367
2938
    def __init__(self, branch):
3368
2939
        super(BranchStore, self).__init__(branch.control_transport,
3369
2940
                                          'branch.conf')
3370
2941
        self.branch = branch
3371
 
        self.id = 'branch'
3372
2942
 
3373
2943
    def lock_write(self, token=None):
3374
2944
        return self.branch.lock_write(token)
3391
2961
        super(ControlStore, self).__init__(bzrdir.transport,
3392
2962
                                          'control.conf',
3393
2963
                                           lock_dir_name='branch_lock')
3394
 
        self.id = 'control'
3395
2964
 
3396
2965
 
3397
2966
class SectionMatcher(object):
3409
2978
        # sections.
3410
2979
        sections = self.store.get_sections()
3411
2980
        # Walk the revisions in the order provided
3412
 
        for store, s in sections:
 
2981
        for s in sections:
3413
2982
            if self.match(s):
3414
 
                yield store, s
 
2983
                yield s
3415
2984
 
3416
2985
    def match(self, section):
3417
2986
        """Does the proposed section match.
3435
3004
 
3436
3005
class LocationSection(Section):
3437
3006
 
3438
 
    def __init__(self, section, extra_path):
 
3007
    def __init__(self, section, length, extra_path):
3439
3008
        super(LocationSection, self).__init__(section.id, section.options)
 
3009
        self.length = length
3440
3010
        self.extra_path = extra_path
3441
 
        self.locals = {'relpath': extra_path,
3442
 
                       'basename': urlutils.basename(extra_path)}
3443
3011
 
3444
 
    def get(self, name, default=None, expand=True):
 
3012
    def get(self, name, default=None):
3445
3013
        value = super(LocationSection, self).get(name, default)
3446
 
        if value is not None and expand:
 
3014
        if value is not None:
3447
3015
            policy_name = self.get(name + ':policy', None)
3448
3016
            policy = _policy_value.get(policy_name, POLICY_NONE)
3449
3017
            if policy == POLICY_APPENDPATH:
3450
3018
                value = urlutils.join(value, self.extra_path)
3451
 
            # expand section local options right now (since POLICY_APPENDPATH
3452
 
            # will never add options references, it's ok to expand after it).
3453
 
            chunks = []
3454
 
            for is_ref, chunk in iter_option_refs(value):
3455
 
                if not is_ref:
3456
 
                    chunks.append(chunk)
3457
 
                else:
3458
 
                    ref = chunk[1:-1]
3459
 
                    if ref in self.locals:
3460
 
                        chunks.append(self.locals[ref])
3461
 
                    else:
3462
 
                        chunks.append(chunk)
3463
 
            value = ''.join(chunks)
3464
3019
        return value
3465
3020
 
3466
3021
 
3467
 
class StartingPathMatcher(SectionMatcher):
3468
 
    """Select sections for a given location respecting the Store order."""
3469
 
 
3470
 
    # FIXME: Both local paths and urls can be used for section names as well as
3471
 
    # ``location`` to stay consistent with ``LocationMatcher`` which itself
3472
 
    # inherited the fuzziness from the previous ``LocationConfig``
3473
 
    # implementation. We probably need to revisit which encoding is allowed for
3474
 
    # both ``location`` and section names and how we normalize
3475
 
    # them. http://pad.lv/85479, http://pad.lv/437009 and http://359320 are
3476
 
    # related too. -- vila 2012-01-04
3477
 
 
3478
 
    def __init__(self, store, location):
3479
 
        super(StartingPathMatcher, self).__init__(store)
3480
 
        if location.startswith('file://'):
3481
 
            location = urlutils.local_path_from_url(location)
3482
 
        self.location = location
3483
 
 
3484
 
    def get_sections(self):
3485
 
        """Get all sections matching ``location`` in the store.
3486
 
 
3487
 
        The most generic sections are described first in the store, then more
3488
 
        specific ones can be provided for reduced scopes.
3489
 
 
3490
 
        The returned section are therefore returned in the reversed order so
3491
 
        the most specific ones can be found first.
3492
 
        """
3493
 
        location_parts = self.location.rstrip('/').split('/')
3494
 
        store = self.store
3495
 
        sections = []
3496
 
        # Later sections are more specific, they should be returned first
3497
 
        for _, section in reversed(list(store.get_sections())):
3498
 
            if section.id is None:
3499
 
                # The no-name section is always included if present
3500
 
                yield store, LocationSection(section, self.location)
3501
 
                continue
3502
 
            section_path = section.id
3503
 
            if section_path.startswith('file://'):
3504
 
                # the location is already a local path or URL, convert the
3505
 
                # section id to the same format
3506
 
                section_path = urlutils.local_path_from_url(section_path)
3507
 
            if (self.location.startswith(section_path)
3508
 
                or fnmatch.fnmatch(self.location, section_path)):
3509
 
                section_parts = section_path.rstrip('/').split('/')
3510
 
                extra_path = '/'.join(location_parts[len(section_parts):])
3511
 
                yield store, LocationSection(section, extra_path)
3512
 
 
3513
 
 
3514
3022
class LocationMatcher(SectionMatcher):
3515
3023
 
3516
3024
    def __init__(self, store, location):
3527
3035
        all_sections = []
3528
3036
        # Filter out the no_name_section so _iter_for_location_by_parts can be
3529
3037
        # used (it assumes all sections have a name).
3530
 
        for _, section in self.store.get_sections():
 
3038
        for section in self.store.get_sections():
3531
3039
            if section.id is None:
3532
3040
                no_name_section = section
3533
3041
            else:
3540
3048
        matching_sections = []
3541
3049
        if no_name_section is not None:
3542
3050
            matching_sections.append(
3543
 
                (0, LocationSection(no_name_section, self.location)))
 
3051
                LocationSection(no_name_section, 0, self.location))
3544
3052
        for section_id, extra_path, length in filtered_sections:
3545
3053
            # a section id is unique for a given store so it's safe to take the
3546
3054
            # first matching section while iterating. Also, all filtered
3550
3058
                section = iter_all_sections.next()
3551
3059
                if section_id == section.id:
3552
3060
                    matching_sections.append(
3553
 
                        (length, LocationSection(section, extra_path)))
 
3061
                        LocationSection(section, length, extra_path))
3554
3062
                    break
3555
3063
        return matching_sections
3556
3064
 
3559
3067
        matching_sections = self._get_matching_sections()
3560
3068
        # We want the longest (aka more specific) locations first
3561
3069
        sections = sorted(matching_sections,
3562
 
                          key=lambda (length, section): (length, section.id),
 
3070
                          key=lambda section: (section.length, section.id),
3563
3071
                          reverse=True)
3564
3072
        # Sections mentioning 'ignore_parents' restrict the selection
3565
 
        for _, section in sections:
 
3073
        for section in sections:
3566
3074
            # FIXME: We really want to use as_bool below -- vila 2011-04-07
3567
3075
            ignore = section.get('ignore_parents', None)
3568
3076
            if ignore is not None:
3570
3078
            if ignore:
3571
3079
                break
3572
3080
            # Finally, we have a valid section
3573
 
            yield self.store, section
3574
 
 
3575
 
 
3576
 
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
3577
 
"""Describes an expandable option reference.
3578
 
 
3579
 
We want to match the most embedded reference first.
3580
 
 
3581
 
I.e. for '{{foo}}' we will get '{foo}',
3582
 
for '{bar{baz}}' we will get '{baz}'
3583
 
"""
3584
 
 
3585
 
def iter_option_refs(string):
3586
 
    # Split isolate refs so every other chunk is a ref
3587
 
    is_ref = False
3588
 
    for chunk  in _option_ref_re.split(string):
3589
 
        yield is_ref, chunk
3590
 
        is_ref = not is_ref
 
3081
            yield section
3591
3082
 
3592
3083
 
3593
3084
class Stack(object):
3594
3085
    """A stack of configurations where an option can be defined"""
3595
3086
 
3596
 
    def __init__(self, sections_def, store=None, mutable_section_id=None):
 
3087
    _option_ref_re = lazy_regex.lazy_compile('({[^{}]+})')
 
3088
    """Describes an exandable option reference.
 
3089
 
 
3090
    We want to match the most embedded reference first.
 
3091
 
 
3092
    I.e. for '{{foo}}' we will get '{foo}',
 
3093
    for '{bar{baz}}' we will get '{baz}'
 
3094
    """
 
3095
 
 
3096
    def __init__(self, sections_def, store=None, mutable_section_name=None):
3597
3097
        """Creates a stack of sections with an optional store for changes.
3598
3098
 
3599
3099
        :param sections_def: A list of Section or callables that returns an
3603
3103
        :param store: The optional Store where modifications will be
3604
3104
            recorded. If none is specified, no modifications can be done.
3605
3105
 
3606
 
        :param mutable_section_id: The id of the MutableSection where changes
3607
 
            are recorded. This requires the ``store`` parameter to be
 
3106
        :param mutable_section_name: The name of the MutableSection where
 
3107
            changes are recorded. This requires the ``store`` parameter to be
3608
3108
            specified.
3609
3109
        """
3610
3110
        self.sections_def = sections_def
3611
3111
        self.store = store
3612
 
        self.mutable_section_id = mutable_section_id
 
3112
        self.mutable_section_name = mutable_section_name
3613
3113
 
3614
3114
    def get(self, name, expand=None):
3615
3115
        """Return the *first* option value found in the sections.
3630
3130
        if expand is None:
3631
3131
            expand = _get_expand_default_value()
3632
3132
        value = None
3633
 
        found_store = None # Where the option value has been found
 
3133
        # Ensuring lazy loading is achieved by delaying section matching (which
 
3134
        # implies querying the persistent storage) until it can't be avoided
 
3135
        # anymore by using callables to describe (possibly empty) section
 
3136
        # lists.
 
3137
        for section_or_callable in self.sections_def:
 
3138
            # Each section can expand to multiple ones when a callable is used
 
3139
            if callable(section_or_callable):
 
3140
                sections = section_or_callable()
 
3141
            else:
 
3142
                sections = [section_or_callable]
 
3143
            for section in sections:
 
3144
                value = section.get(name)
 
3145
                if value is not None:
 
3146
                    break
 
3147
            if value is not None:
 
3148
                break
3634
3149
        # If the option is registered, it may provide additional info about
3635
3150
        # value handling
3636
3151
        try:
3638
3153
        except KeyError:
3639
3154
            # Not registered
3640
3155
            opt = None
3641
 
 
3642
3156
        def expand_and_convert(val):
3643
 
            # This may need to be called in different contexts if the value is
3644
 
            # None or ends up being None during expansion or conversion.
 
3157
            # This may need to be called twice if the value is None or ends up
 
3158
            # being None during expansion or conversion.
3645
3159
            if val is not None:
3646
3160
                if expand:
3647
3161
                    if isinstance(val, basestring):
3650
3164
                        trace.warning('Cannot expand "%s":'
3651
3165
                                      ' %s does not support option expansion'
3652
3166
                                      % (name, type(val)))
3653
 
                if opt is None:
3654
 
                    val = found_store.unquote(val)
3655
 
                else:
3656
 
                    val = opt.convert_from_unicode(found_store, val)
 
3167
                if opt is not None:
 
3168
                    val = opt.convert_from_unicode(val)
3657
3169
            return val
3658
 
 
3659
 
        # First of all, check if the environment can override the configuration
3660
 
        # value
3661
 
        if opt is not None and opt.override_from_env:
3662
 
            value = opt.get_override()
3663
 
            value = expand_and_convert(value)
3664
 
        if value is None:
3665
 
            # Ensuring lazy loading is achieved by delaying section matching
3666
 
            # (which implies querying the persistent storage) until it can't be
3667
 
            # avoided anymore by using callables to describe (possibly empty)
3668
 
            # section lists.
3669
 
            for sections in self.sections_def:
3670
 
                for store, section in sections():
3671
 
                    value = section.get(name)
3672
 
                    if value is not None:
3673
 
                        found_store = store
3674
 
                        break
3675
 
                if value is not None:
3676
 
                    break
3677
 
            value = expand_and_convert(value)
3678
 
            if opt is not None and value is None:
3679
 
                # If the option is registered, it may provide a default value
3680
 
                value = opt.get_default()
3681
 
                value = expand_and_convert(value)
 
3170
        value = expand_and_convert(value)
 
3171
        if opt is not None and value is None:
 
3172
            # If the option is registered, it may provide a default value
 
3173
            value = opt.get_default()
 
3174
            value = expand_and_convert(value)
3682
3175
        for hook in ConfigHooks['get']:
3683
3176
            hook(self, name, value)
3684
3177
        return value
3717
3210
        result = string
3718
3211
        # We need to iterate until no more refs appear ({{foo}} will need two
3719
3212
        # iterations for example).
3720
 
        expanded = True
3721
 
        while expanded:
3722
 
            expanded = False
 
3213
        while True:
 
3214
            raw_chunks = Stack._option_ref_re.split(result)
 
3215
            if len(raw_chunks) == 1:
 
3216
                # Shorcut the trivial case: no refs
 
3217
                return result
3723
3218
            chunks = []
3724
 
            for is_ref, chunk in iter_option_refs(result):
3725
 
                if not is_ref:
 
3219
            # Split will isolate refs so that every other chunk is a ref
 
3220
            chunk_is_ref = False
 
3221
            for chunk in raw_chunks:
 
3222
                if not chunk_is_ref:
3726
3223
                    chunks.append(chunk)
 
3224
                    chunk_is_ref = True
3727
3225
                else:
3728
 
                    expanded = True
3729
3226
                    name = chunk[1:-1]
3730
3227
                    if name in _refs:
3731
3228
                        raise errors.OptionExpansionLoop(string, _refs)
3735
3232
                        raise errors.ExpandingUnknownOption(name, string)
3736
3233
                    chunks.append(value)
3737
3234
                    _refs.pop()
 
3235
                    chunk_is_ref = False
3738
3236
            result = ''.join(chunks)
3739
3237
        return result
3740
3238
 
3744
3242
            # anything else
3745
3243
            value = env[name]
3746
3244
        else:
 
3245
            # FIXME: This is a limited implementation, what we really need is a
 
3246
            # way to query the bzr config for the value of an option,
 
3247
            # respecting the scope rules (That is, once we implement fallback
 
3248
            # configs, getting the option value should restart from the top
 
3249
            # config, not the current one) -- vila 20101222
3747
3250
            value = self.get(name, expand=False)
3748
3251
            value = self._expand_options_in_string(value, env, _refs)
3749
3252
        return value
3754
3257
        This is where we guarantee that the mutable section is lazily loaded:
3755
3258
        this means we won't load the corresponding store before setting a value
3756
3259
        or deleting an option. In practice the store will often be loaded but
3757
 
        this helps catching some programming errors.
 
3260
        this allows helps catching some programming errors.
3758
3261
        """
3759
 
        store = self.store
3760
 
        section = store.get_mutable_section(self.mutable_section_id)
3761
 
        return store, section
 
3262
        section = self.store.get_mutable_section(self.mutable_section_name)
 
3263
        return section
3762
3264
 
3763
3265
    def set(self, name, value):
3764
3266
        """Set a new value for the option."""
3765
 
        store, section = self._get_mutable_section()
3766
 
        section.set(name, store.quote(value))
 
3267
        section = self._get_mutable_section()
 
3268
        section.set(name, value)
3767
3269
        for hook in ConfigHooks['set']:
3768
3270
            hook(self, name, value)
3769
3271
 
3770
3272
    def remove(self, name):
3771
3273
        """Remove an existing option."""
3772
 
        _, section = self._get_mutable_section()
 
3274
        section = self._get_mutable_section()
3773
3275
        section.remove(name)
3774
3276
        for hook in ConfigHooks['remove']:
3775
3277
            hook(self, name)
3781
3283
    def _get_overrides(self):
3782
3284
        # Hack around library_state.initialize never called
3783
3285
        if bzrlib.global_state is not None:
3784
 
            return bzrlib.global_state.cmdline_overrides.get_sections()
 
3286
            return [bzrlib.global_state.cmdline_overrides]
3785
3287
        return []
3786
3288
 
3787
3289
 
3788
 
class MemoryStack(Stack):
3789
 
    """A configuration stack defined from a string.
3790
 
 
3791
 
    This is mainly intended for tests and requires no disk resources.
3792
 
    """
3793
 
 
3794
 
    def __init__(self, content=None):
3795
 
        """Create an in-memory stack from a given content.
3796
 
 
3797
 
        It uses a single store based on configobj and support reading and
3798
 
        writing options.
3799
 
 
3800
 
        :param content: The initial content of the store. If None, the store is
3801
 
            not loaded and ``_load_from_string`` can and should be used if
3802
 
            needed.
3803
 
        """
3804
 
        store = IniFileStore()
3805
 
        if content is not None:
3806
 
            store._load_from_string(content)
3807
 
        super(MemoryStack, self).__init__(
3808
 
            [store.get_sections], store)
3809
 
 
3810
 
 
3811
3290
class _CompatibleStack(Stack):
3812
3291
    """Place holder for compatibility with previous design.
3813
3292
 
3817
3296
    One assumption made here is that the daughter classes will all use Stores
3818
3297
    derived from LockableIniFileStore).
3819
3298
 
3820
 
    It implements set() and remove () by re-loading the store before applying
3821
 
    the modification and saving it.
 
3299
    It implements set() by re-loading the store before applying the
 
3300
    modification and saving it.
3822
3301
 
3823
3302
    The long term plan being to implement a single write by store to save
3824
3303
    all modifications, this class should not be used in the interim.
3831
3310
        # Force a write to persistent storage
3832
3311
        self.store.save()
3833
3312
 
3834
 
    def remove(self, name):
3835
 
        # Force a reload
3836
 
        self.store.unload()
3837
 
        super(_CompatibleStack, self).remove(name)
3838
 
        # Force a write to persistent storage
3839
 
        self.store.save()
3840
 
 
3841
3313
 
3842
3314
class GlobalStack(_CompatibleStack):
3843
 
    """Global options only stack.
3844
 
 
3845
 
    The following sections are queried:
3846
 
 
3847
 
    * command-line overrides,
3848
 
 
3849
 
    * the 'DEFAULT' section in bazaar.conf
3850
 
 
3851
 
    This stack will use the ``DEFAULT`` section in bazaar.conf as its
3852
 
    MutableSection.
3853
 
    """
 
3315
    """Global options only stack."""
3854
3316
 
3855
3317
    def __init__(self):
 
3318
        # Get a GlobalStore
3856
3319
        gstore = GlobalStore()
3857
3320
        super(GlobalStack, self).__init__(
3858
 
            [self._get_overrides,
3859
 
             NameMatcher(gstore, 'DEFAULT').get_sections],
3860
 
            gstore, mutable_section_id='DEFAULT')
 
3321
            [self._get_overrides, gstore.get_sections],
 
3322
            gstore)
3861
3323
 
3862
3324
 
3863
3325
class LocationStack(_CompatibleStack):
3864
 
    """Per-location options falling back to global options stack.
3865
 
 
3866
 
 
3867
 
    The following sections are queried:
3868
 
 
3869
 
    * command-line overrides,
3870
 
 
3871
 
    * the sections matching ``location`` in ``locations.conf``, the order being
3872
 
      defined by the number of path components in the section glob, higher
3873
 
      numbers first (from most specific section to most generic).
3874
 
 
3875
 
    * the 'DEFAULT' section in bazaar.conf
3876
 
 
3877
 
    This stack will use the ``location`` section in locations.conf as its
3878
 
    MutableSection.
3879
 
    """
 
3326
    """Per-location options falling back to global options stack."""
3880
3327
 
3881
3328
    def __init__(self, location):
3882
3329
        """Make a new stack for a location and global configuration.
3883
 
 
 
3330
        
3884
3331
        :param location: A URL prefix to """
3885
3332
        lstore = LocationStore()
3886
 
        if location.startswith('file://'):
3887
 
            location = urlutils.local_path_from_url(location)
 
3333
        matcher = LocationMatcher(lstore, location)
3888
3334
        gstore = GlobalStore()
3889
3335
        super(LocationStack, self).__init__(
3890
3336
            [self._get_overrides,
3891
 
             LocationMatcher(lstore, location).get_sections,
3892
 
             NameMatcher(gstore, 'DEFAULT').get_sections],
3893
 
            lstore, mutable_section_id=location)
 
3337
             matcher.get_sections, gstore.get_sections],
 
3338
            lstore)
3894
3339
 
3895
3340
 
3896
3341
class BranchStack(_CompatibleStack):
3897
 
    """Per-location options falling back to branch then global options stack.
3898
 
 
3899
 
    The following sections are queried:
3900
 
 
3901
 
    * command-line overrides,
3902
 
 
3903
 
    * the sections matching ``location`` in ``locations.conf``, the order being
3904
 
      defined by the number of path components in the section glob, higher
3905
 
      numbers first (from most specific section to most generic),
3906
 
 
3907
 
    * the no-name section in branch.conf,
3908
 
 
3909
 
    * the ``DEFAULT`` section in ``bazaar.conf``.
3910
 
 
3911
 
    This stack will use the no-name section in ``branch.conf`` as its
3912
 
    MutableSection.
3913
 
    """
 
3342
    """Per-location options falling back to branch then global options stack."""
3914
3343
 
3915
3344
    def __init__(self, branch):
 
3345
        bstore = BranchStore(branch)
3916
3346
        lstore = LocationStore()
3917
 
        bstore = branch._get_config_store()
 
3347
        matcher = LocationMatcher(lstore, branch.base)
3918
3348
        gstore = GlobalStore()
3919
3349
        super(BranchStack, self).__init__(
3920
3350
            [self._get_overrides,
3921
 
             LocationMatcher(lstore, branch.base).get_sections,
3922
 
             NameMatcher(bstore, None).get_sections,
3923
 
             NameMatcher(gstore, 'DEFAULT').get_sections],
 
3351
             matcher.get_sections, bstore.get_sections, gstore.get_sections],
3924
3352
            bstore)
3925
3353
        self.branch = branch
3926
3354
 
3928
3356
class RemoteControlStack(_CompatibleStack):
3929
3357
    """Remote control-only options stack."""
3930
3358
 
3931
 
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3932
 
    # with the stack used for remote bzr dirs. RemoteControlStack only uses
3933
 
    # control.conf and is used only for stack options.
3934
 
 
3935
3359
    def __init__(self, bzrdir):
3936
 
        cstore = bzrdir._get_config_store()
 
3360
        cstore = ControlStore(bzrdir)
3937
3361
        super(RemoteControlStack, self).__init__(
3938
 
            [NameMatcher(cstore, None).get_sections],
 
3362
            [cstore.get_sections],
3939
3363
            cstore)
3940
3364
        self.bzrdir = bzrdir
3941
3365
 
3942
3366
 
3943
 
class BranchOnlyStack(_CompatibleStack):
3944
 
    """Branch-only options stack."""
3945
 
 
3946
 
    # FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
3947
 
    # stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
3948
 
    # -- vila 2011-12-16
 
3367
class RemoteBranchStack(_CompatibleStack):
 
3368
    """Remote branch-only options stack."""
3949
3369
 
3950
3370
    def __init__(self, branch):
3951
 
        bstore = branch._get_config_store()
3952
 
        super(BranchOnlyStack, self).__init__(
3953
 
            [NameMatcher(bstore, None).get_sections],
 
3371
        bstore = BranchStore(branch)
 
3372
        super(RemoteBranchStack, self).__init__(
 
3373
            [bstore.get_sections],
3954
3374
            bstore)
3955
3375
        self.branch = branch
3956
3376
 
3957
3377
 
3958
 
# Use a an empty dict to initialize an empty configobj avoiding all
3959
 
# parsing and encoding checks
3960
 
_quoting_config = configobj.ConfigObj(
3961
 
    {}, encoding='utf-8', interpolation=False, list_values=True)
3962
 
 
3963
3378
class cmd_config(commands.Command):
3964
3379
    __doc__ = """Display, set or remove a configuration option.
3965
3380
 
3981
3396
    takes_options = [
3982
3397
        'directory',
3983
3398
        # FIXME: This should be a registry option so that plugins can register
3984
 
        # their own config files (or not) and will also address
3985
 
        # http://pad.lv/788991 -- vila 20101115
 
3399
        # their own config files (or not) -- vila 20101002
3986
3400
        commands.Option('scope', help='Reduce the scope to the specified'
3987
 
                        ' configuration file.',
 
3401
                        ' configuration file',
3988
3402
                        type=unicode),
3989
3403
        commands.Option('all',
3990
3404
            help='Display all the defined values for the matching options.',
3991
3405
            ),
3992
3406
        commands.Option('remove', help='Remove the option from'
3993
 
                        ' the configuration file.'),
 
3407
                        ' the configuration file'),
3994
3408
        ]
3995
3409
 
3996
3410
    _see_also = ['configuration']
4026
3440
                # Set the option value
4027
3441
                self._set_config_option(name, value, directory, scope)
4028
3442
 
4029
 
    def _get_stack(self, directory, scope=None):
4030
 
        """Get the configuration stack specified by ``directory`` and ``scope``.
 
3443
    def _get_configs(self, directory, scope=None):
 
3444
        """Iterate the configurations specified by ``directory`` and ``scope``.
4031
3445
 
4032
3446
        :param directory: Where the configurations are derived from.
4033
3447
 
4034
3448
        :param scope: A specific config to start from.
4035
3449
        """
4036
 
        # FIXME: scope should allow access to plugin-specific stacks (even
4037
 
        # reduced to the plugin-specific store), related to
4038
 
        # http://pad.lv/788991 -- vila 2011-11-15
4039
3450
        if scope is not None:
4040
3451
            if scope == 'bazaar':
4041
 
                return GlobalStack()
 
3452
                yield GlobalConfig()
4042
3453
            elif scope == 'locations':
4043
 
                return LocationStack(directory)
 
3454
                yield LocationConfig(directory)
4044
3455
            elif scope == 'branch':
4045
3456
                (_, br, _) = (
4046
3457
                    controldir.ControlDir.open_containing_tree_or_branch(
4047
3458
                        directory))
4048
 
                return br.get_config_stack()
4049
 
            raise errors.NoSuchConfig(scope)
 
3459
                yield br.get_config()
4050
3460
        else:
4051
3461
            try:
4052
3462
                (_, br, _) = (
4053
3463
                    controldir.ControlDir.open_containing_tree_or_branch(
4054
3464
                        directory))
4055
 
                return br.get_config_stack()
 
3465
                yield br.get_config()
4056
3466
            except errors.NotBranchError:
4057
 
                return LocationStack(directory)
 
3467
                yield LocationConfig(directory)
 
3468
                yield GlobalConfig()
4058
3469
 
4059
3470
    def _show_value(self, name, directory, scope):
4060
 
        conf = self._get_stack(directory, scope)
4061
 
        value = conf.get(name, expand=True)
4062
 
        if value is not None:
4063
 
            # Quote the value appropriately
4064
 
            value = _quoting_config._quote(value)
4065
 
            self.outf.write('%s\n' % (value,))
4066
 
        else:
 
3471
        displayed = False
 
3472
        for c in self._get_configs(directory, scope):
 
3473
            if displayed:
 
3474
                break
 
3475
            for (oname, value, section, conf_id, parser) in c._get_options():
 
3476
                if name == oname:
 
3477
                    # Display only the first value and exit
 
3478
 
 
3479
                    # FIXME: We need to use get_user_option to take policies
 
3480
                    # into account and we need to make sure the option exists
 
3481
                    # too (hence the two for loops), this needs a better API
 
3482
                    # -- vila 20101117
 
3483
                    value = c.get_user_option(name)
 
3484
                    # Quote the value appropriately
 
3485
                    value = parser._quote(value)
 
3486
                    self.outf.write('%s\n' % (value,))
 
3487
                    displayed = True
 
3488
                    break
 
3489
        if not displayed:
4067
3490
            raise errors.NoSuchConfigOption(name)
4068
3491
 
4069
3492
    def _show_matching_options(self, name, directory, scope):
4072
3495
        # avoid the delay introduced by the lazy regexp.  But, we still do
4073
3496
        # want the nicer errors raised by lazy_regex.
4074
3497
        name._compile_and_collapse()
4075
 
        cur_store_id = None
 
3498
        cur_conf_id = None
4076
3499
        cur_section = None
4077
 
        conf = self._get_stack(directory, scope)
4078
 
        for sections in conf.sections_def:
4079
 
            for store, section in sections():
4080
 
                for oname in section.iter_option_names():
4081
 
                    if name.search(oname):
4082
 
                        if cur_store_id != store.id:
4083
 
                            # Explain where the options are defined
4084
 
                            self.outf.write('%s:\n' % (store.id,))
4085
 
                            cur_store_id = store.id
4086
 
                            cur_section = None
4087
 
                        if (section.id is not None
4088
 
                            and cur_section != section.id):
4089
 
                            # Display the section id as it appears in the store
4090
 
                            # (None doesn't appear by definition)
4091
 
                            self.outf.write('  [%s]\n' % (section.id,))
4092
 
                            cur_section = section.id
4093
 
                        value = section.get(oname, expand=False)
4094
 
                        # Since we don't use the stack, we need to restore a
4095
 
                        # proper quoting.
4096
 
                        try:
4097
 
                            opt = option_registry.get(oname)
4098
 
                            value = opt.convert_from_unicode(store, value)
4099
 
                        except KeyError:
4100
 
                            value = store.unquote(value)
4101
 
                        value = _quoting_config._quote(value)
4102
 
                        self.outf.write('  %s = %s\n' % (oname, value))
 
3500
        for c in self._get_configs(directory, scope):
 
3501
            for (oname, value, section, conf_id, parser) in c._get_options():
 
3502
                if name.search(oname):
 
3503
                    if cur_conf_id != conf_id:
 
3504
                        # Explain where the options are defined
 
3505
                        self.outf.write('%s:\n' % (conf_id,))
 
3506
                        cur_conf_id = conf_id
 
3507
                        cur_section = None
 
3508
                    if (section not in (None, 'DEFAULT')
 
3509
                        and cur_section != section):
 
3510
                        # Display the section if it's not the default (or only)
 
3511
                        # one.
 
3512
                        self.outf.write('  [%s]\n' % (section,))
 
3513
                        cur_section = section
 
3514
                    self.outf.write('  %s = %s\n' % (oname, value))
4103
3515
 
4104
3516
    def _set_config_option(self, name, value, directory, scope):
4105
 
        conf = self._get_stack(directory, scope)
4106
 
        conf.set(name, value)
 
3517
        for conf in self._get_configs(directory, scope):
 
3518
            conf.set_user_option(name, value)
 
3519
            break
 
3520
        else:
 
3521
            raise errors.NoSuchConfig(scope)
4107
3522
 
4108
3523
    def _remove_config_option(self, name, directory, scope):
4109
3524
        if name is None:
4110
3525
            raise errors.BzrCommandError(
4111
3526
                '--remove expects an option to remove.')
4112
 
        conf = self._get_stack(directory, scope)
4113
 
        try:
4114
 
            conf.remove(name)
4115
 
        except KeyError:
 
3527
        removed = False
 
3528
        for conf in self._get_configs(directory, scope):
 
3529
            for (section_name, section, conf_id) in conf._get_sections():
 
3530
                if scope is not None and conf_id != scope:
 
3531
                    # Not the right configuration file
 
3532
                    continue
 
3533
                if name in section:
 
3534
                    if conf_id != conf.config_id():
 
3535
                        conf = self._get_configs(directory, conf_id).next()
 
3536
                    # We use the first section in the first config where the
 
3537
                    # option is defined to remove it
 
3538
                    conf.remove_user_option(name, section_name)
 
3539
                    removed = True
 
3540
                    break
 
3541
            break
 
3542
        else:
 
3543
            raise errors.NoSuchConfig(scope)
 
3544
        if not removed:
4116
3545
            raise errors.NoSuchConfigOption(name)
4117
3546
 
4118
 
 
4119
3547
# Test registries
4120
3548
#
4121
3549
# We need adapters that can build a Store or a Stack in a test context. Test
4124
3552
# ready-to-use store or stack.  Plugins that define new store/stacks can also
4125
3553
# register themselves here to be tested against the tests defined in
4126
3554
# bzrlib.tests.test_config. Note that the builder can be called multiple times
4127
 
# for the same test.
 
3555
# for the same tests.
4128
3556
 
4129
3557
# The registered object should be a callable receiving a test instance
4130
3558
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store