~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Jonathan Riddell
  • Date: 2011-09-14 16:31:57 UTC
  • mto: This revision was merged to the branch mainline in revision 6139.
  • Revision ID: jriddell@canonical.com-20110914163157-ee87lu1pqmq5b4r3
default _translations back to None so we can tell if it gets installed

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