/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Vincent Ladeuil
  • Date: 2011-11-24 15:48:29 UTC
  • mfrom: (6289 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6337.
  • Revision ID: v.ladeuil+lp@free.fr-20111124154829-avowjpsxdl8yp2vz
merge trunk resolving conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
log_format=name-of-format
32
32
validate_signatures_in_log=true|false(default)
33
33
acceptable_keys=pattern1,pattern2
 
34
gpg_signing_key=amy@example.com
34
35
 
35
36
in locations.conf, you specify the url of a branch and options for it.
36
37
Wildcards may be used - * and ? as normal in shell completion. Options
76
77
import sys
77
78
 
78
79
 
 
80
import bzrlib
79
81
from bzrlib.decorators import needs_write_lock
80
82
from bzrlib.lazy_import import lazy_import
81
83
lazy_import(globals(), """
85
87
 
86
88
from bzrlib import (
87
89
    atomicfile,
88
 
    bzrdir,
 
90
    controldir,
89
91
    debug,
90
92
    errors,
91
93
    lazy_regex,
 
94
    library_state,
92
95
    lockdir,
93
96
    mail_client,
94
97
    mergetools,
100
103
    urlutils,
101
104
    win32utils,
102
105
    )
 
106
from bzrlib.i18n import gettext
103
107
from bzrlib.util.configobj import configobj
104
108
""")
105
109
from bzrlib import (
106
110
    commands,
107
111
    hooks,
 
112
    lazy_regex,
108
113
    registry,
109
114
    )
110
115
from bzrlib.symbol_versioning import (
412
417
            # add) the final ','
413
418
            l = [l]
414
419
        return l
 
420
        
 
421
    def get_user_option_as_int_from_SI(self,  option_name,  default=None):
 
422
        """Get a generic option from a human readable size in SI units, e.g 10MB
 
423
        
 
424
        Accepted suffixes are K,M,G. It is case-insensitive and may be followed
 
425
        by a trailing b (i.e. Kb, MB). This is intended to be practical and not
 
426
        pedantic.
 
427
        
 
428
        :return Integer, expanded to its base-10 value if a proper SI unit is 
 
429
            found. If the option doesn't exist, or isn't a value in 
 
430
            SI units, return default (which defaults to None)
 
431
        """
 
432
        val = self.get_user_option(option_name)
 
433
        if isinstance(val, list):
 
434
            val = val[0]
 
435
        if val is None:
 
436
            val = default
 
437
        else:
 
438
            p = re.compile("^(\d+)([kmg])*b*$", re.IGNORECASE)
 
439
            try:
 
440
                m = p.match(val)
 
441
                if m is not None:
 
442
                    val = int(m.group(1))
 
443
                    if m.group(2) is not None:
 
444
                        if m.group(2).lower() == 'k':
 
445
                            val *= 10**3
 
446
                        elif m.group(2).lower() == 'm':
 
447
                            val *= 10**6
 
448
                        elif m.group(2).lower() == 'g':
 
449
                            val *= 10**9
 
450
                else:
 
451
                    ui.ui_factory.show_warning(gettext('Invalid config value for "{0}" '
 
452
                                               ' value {1!r} is not an SI unit.').format(
 
453
                                                option_name, val))
 
454
                    val = default
 
455
            except TypeError:
 
456
                val = default
 
457
        return val
 
458
        
415
459
 
416
460
    def gpg_signing_command(self):
417
461
        """What program should be used to sign signatures?"""
534
578
            return True
535
579
        return False
536
580
 
 
581
    def gpg_signing_key(self):
 
582
        """GPG user-id to sign commits"""
 
583
        key = self.get_user_option('gpg_signing_key')
 
584
        if key == "default" or key == None:
 
585
            return self.user_email()
 
586
        else:
 
587
            return key
 
588
 
537
589
    def get_alias(self, value):
538
590
        return self._get_alias(value)
539
591
 
976
1028
        # local transports are not shared. But if/when we start using
977
1029
        # LockableConfig for other kind of transports, we will need to reuse
978
1030
        # whatever connection is already established -- vila 20100929
979
 
        self.transport = transport.get_transport(self.dir)
 
1031
        self.transport = transport.get_transport_from_path(self.dir)
980
1032
        self._lock = lockdir.LockDir(self.transport, self.lock_name)
981
1033
 
982
1034
    def _create_from_string(self, unicode_bytes, save):
1348
1400
            return (self.branch._transport.get_bytes("email")
1349
1401
                    .decode(osutils.get_user_encoding())
1350
1402
                    .rstrip("\r\n"))
1351
 
        except errors.NoSuchFile, e:
 
1403
        except (errors.NoSuchFile, errors.PermissionDenied), e:
1352
1404
            pass
1353
1405
 
1354
1406
        return self._get_best_value('_get_user_id')
2229
2281
            return f
2230
2282
        except errors.NoSuchFile:
2231
2283
            return StringIO()
 
2284
        except errors.PermissionDenied, e:
 
2285
            trace.warning("Permission denied while trying to open "
 
2286
                "configuration file %s.", urlutils.unescape_for_display(
 
2287
                urlutils.join(self._transport.base, self._filename), "utf-8"))
 
2288
            return StringIO()
2232
2289
 
2233
2290
    def _external_url(self):
2234
2291
        return urlutils.join(self._transport.external_url(), self._filename)
2261
2318
    The option *values* are stored in config files and found in sections.
2262
2319
 
2263
2320
    Here we define various properties about the option itself, its default
2264
 
    value, in which config files it can be stored, etc (TBC).
 
2321
    value, how to convert it from stores, what to do when invalid values are
 
2322
    encoutered, in which config files it can be stored.
2265
2323
    """
2266
2324
 
2267
 
    def __init__(self, name, default=None, from_unicode=None):
 
2325
    def __init__(self, name, default=None, default_from_env=None,
 
2326
                 help=None,
 
2327
                 from_unicode=None, invalid=None):
 
2328
        """Build an option definition.
 
2329
 
 
2330
        :param name: the name used to refer to the option.
 
2331
 
 
2332
        :param default: the default value to use when none exist in the config
 
2333
            stores. This is either a string that ``from_unicode`` will convert
 
2334
            into the proper type or a python object that can be stringified (so
 
2335
            only the empty list is supported for example).
 
2336
 
 
2337
        :param default_from_env: A list of environment variables which can
 
2338
           provide a default value. 'default' will be used only if none of the
 
2339
           variables specified here are set in the environment.
 
2340
 
 
2341
        :param help: a doc string to explain the option to the user.
 
2342
 
 
2343
        :param from_unicode: a callable to convert the unicode string
 
2344
            representing the option value in a store. This is not called for
 
2345
            the default value.
 
2346
 
 
2347
        :param invalid: the action to be taken when an invalid value is
 
2348
            encountered in a store. This is called only when from_unicode is
 
2349
            invoked to convert a string and returns None or raise ValueError or
 
2350
            TypeError. Accepted values are: None (ignore invalid values),
 
2351
            'warning' (emit a warning), 'error' (emit an error message and
 
2352
            terminates).
 
2353
        """
 
2354
        if default_from_env is None:
 
2355
            default_from_env = []
2268
2356
        self.name = name
2269
 
        self.default = default
 
2357
        # Convert the default value to a unicode string so all values are
 
2358
        # strings internally before conversion (via from_unicode) is attempted.
 
2359
        if default is None:
 
2360
            self.default = None
 
2361
        elif isinstance(default, list):
 
2362
            # Only the empty list is supported
 
2363
            if default:
 
2364
                raise AssertionError(
 
2365
                    'Only empty lists are supported as default values')
 
2366
            self.default = u','
 
2367
        elif isinstance(default, (str, unicode, bool, int, float)):
 
2368
            # Rely on python to convert strings, booleans and integers
 
2369
            self.default = u'%s' % (default,)
 
2370
        else:
 
2371
            # other python objects are not expected
 
2372
            raise AssertionError('%r is not supported as a default value'
 
2373
                                 % (default,))
 
2374
        self.default_from_env = default_from_env
 
2375
        self.help = help
2270
2376
        self.from_unicode = from_unicode
 
2377
        if invalid and invalid not in ('warning', 'error'):
 
2378
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
 
2379
        self.invalid = invalid
 
2380
 
 
2381
    def convert_from_unicode(self, unicode_value):
 
2382
        if self.from_unicode is None or unicode_value is None:
 
2383
            # Don't convert or nothing to convert
 
2384
            return unicode_value
 
2385
        try:
 
2386
            converted = self.from_unicode(unicode_value)
 
2387
        except (ValueError, TypeError):
 
2388
            # Invalid values are ignored
 
2389
            converted = None
 
2390
        if converted is None and self.invalid is not None:
 
2391
            # The conversion failed
 
2392
            if self.invalid == 'warning':
 
2393
                trace.warning('Value "%s" is not valid for "%s"',
 
2394
                              unicode_value, self.name)
 
2395
            elif self.invalid == 'error':
 
2396
                raise errors.ConfigOptionValueError(self.name, unicode_value)
 
2397
        return converted
2271
2398
 
2272
2399
    def get_default(self):
2273
 
        return self.default
 
2400
        value = None
 
2401
        for var in self.default_from_env:
 
2402
            try:
 
2403
                # If the env variable is defined, its value is the default one
 
2404
                value = os.environ[var]
 
2405
                break
 
2406
            except KeyError:
 
2407
                continue
 
2408
        if value is None:
 
2409
            # Otherwise, fallback to the value defined at registration
 
2410
            value = self.default
 
2411
        return value
 
2412
 
 
2413
    def get_help_text(self, additional_see_also=None, plain=True):
 
2414
        result = self.help
 
2415
        from bzrlib import help_topics
 
2416
        result += help_topics._format_see_also(additional_see_also)
 
2417
        if plain:
 
2418
            result = help_topics.help_as_plain_text(result)
 
2419
        return result
2274
2420
 
2275
2421
 
2276
2422
# Predefined converters to get proper values from store
2279
2425
    return ui.bool_from_string(unicode_str)
2280
2426
 
2281
2427
 
2282
 
# Options registry
2283
 
 
2284
 
option_registry = registry.Registry()
2285
 
 
2286
 
 
2287
 
option_registry.register(
2288
 
    'editor', Option('editor'),
2289
 
    help='The command called to launch an editor to enter a message.')
2290
 
 
2291
 
option_registry.register(
2292
 
    'dirstate.fdatasync', Option('dirstate.fdatasync', default=True,
2293
 
                                 from_unicode=bool_from_store),
2294
 
    help='Flush dirstate changes onto physical disk?')
2295
 
 
2296
 
option_registry.register(
2297
 
    'repository.fdatasync',
2298
 
    Option('repository.fdatasync', default=True, from_unicode=bool_from_store),
2299
 
    help='Flush repository changes onto physical disk?')
 
2428
def int_from_store(unicode_str):
 
2429
    return int(unicode_str)
 
2430
 
 
2431
 
 
2432
def float_from_store(unicode_str):
 
2433
    return float(unicode_str)
 
2434
 
 
2435
 
 
2436
 
 
2437
# Use a an empty dict to initialize an empty configobj avoiding all
 
2438
# parsing and encoding checks
 
2439
_list_converter_config = configobj.ConfigObj(
 
2440
    {}, encoding='utf-8', list_values=True, interpolation=False)
 
2441
 
 
2442
 
 
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]
 
2458
        else:
 
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
 
2465
 
 
2466
 
 
2467
class OptionRegistry(registry.Registry):
 
2468
    """Register config options by their name.
 
2469
 
 
2470
    This overrides ``registry.Registry`` to simplify registration by acquiring
 
2471
    some information from the option object itself.
 
2472
    """
 
2473
 
 
2474
    def register(self, option):
 
2475
        """Register a new option to its name.
 
2476
 
 
2477
        :param option: The option to register. Its name is used as the key.
 
2478
        """
 
2479
        super(OptionRegistry, self).register(option.name, option,
 
2480
                                             help=option.help)
 
2481
 
 
2482
    def register_lazy(self, key, module_name, member_name):
 
2483
        """Register a new option to be loaded on request.
 
2484
 
 
2485
        :param key: the key to request the option later. Since the registration
 
2486
            is lazy, it should be provided and match the option name.
 
2487
 
 
2488
        :param module_name: the python path to the module. Such as 'os.path'.
 
2489
 
 
2490
        :param member_name: the member of the module to return.  If empty or 
 
2491
                None, get() will return the module itself.
 
2492
        """
 
2493
        super(OptionRegistry, self).register_lazy(key,
 
2494
                                                  module_name, member_name)
 
2495
 
 
2496
    def get_help(self, key=None):
 
2497
        """Get the help text associated with the given key"""
 
2498
        option = self.get(key)
 
2499
        the_help = option.help
 
2500
        if callable(the_help):
 
2501
            return the_help(self, key)
 
2502
        return the_help
 
2503
 
 
2504
 
 
2505
option_registry = OptionRegistry()
 
2506
 
 
2507
 
 
2508
# Registered options in lexicographical order
 
2509
 
 
2510
option_registry.register(
 
2511
    Option('bzr.workingtree.worth_saving_limit', default=10,
 
2512
           from_unicode=int_from_store,  invalid='warning',
 
2513
           help='''\
 
2514
How many changes before saving the dirstate.
 
2515
 
 
2516
-1 means that we will never rewrite the dirstate file for only
 
2517
stat-cache changes. Regardless of this setting, we will always rewrite
 
2518
the dirstate file if a file is added/removed/renamed/etc. This flag only
 
2519
affects the behavior of updating the dirstate file after we notice that
 
2520
a file has been touched.
 
2521
'''))
 
2522
option_registry.register(
 
2523
    Option('dirstate.fdatasync', default=True,
 
2524
           from_unicode=bool_from_store,
 
2525
           help='''\
 
2526
Flush dirstate changes onto physical disk?
 
2527
 
 
2528
If true (default), working tree metadata changes are flushed through the
 
2529
OS buffers to physical disk.  This is somewhat slower, but means data
 
2530
should not be lost if the machine crashes.  See also repository.fdatasync.
 
2531
'''))
 
2532
option_registry.register(
 
2533
    Option('debug_flags', default=[], from_unicode=list_from_store,
 
2534
           help='Debug flags to activate.'))
 
2535
option_registry.register(
 
2536
    Option('default_format', default='2a',
 
2537
           help='Format used when creating branches.'))
 
2538
option_registry.register(
 
2539
    Option('dpush_strict', default=None,
 
2540
           from_unicode=bool_from_store,
 
2541
           help='''\
 
2542
The default value for ``dpush --strict``.
 
2543
 
 
2544
If present, defines the ``--strict`` option default value for checking
 
2545
uncommitted changes before pushing into a different VCS without any
 
2546
custom bzr metadata.
 
2547
'''))
 
2548
option_registry.register(
 
2549
    Option('editor',
 
2550
           help='The command called to launch an editor to enter a message.'))
 
2551
option_registry.register(
 
2552
    Option('ignore_missing_extensions', default=False,
 
2553
           from_unicode=bool_from_store,
 
2554
           help='''\
 
2555
Control the missing extensions warning display.
 
2556
 
 
2557
The warning will not be emitted if set to True.
 
2558
'''))
 
2559
option_registry.register(
 
2560
    Option('language',
 
2561
           help='Language to translate messages into.'))
 
2562
option_registry.register(
 
2563
    Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
 
2564
           help='''\
 
2565
Steal locks that appears to be dead.
 
2566
 
 
2567
If set to True, bzr will check if a lock is supposed to be held by an
 
2568
active process from the same user on the same machine. If the user and
 
2569
machine match, but no process with the given PID is active, then bzr
 
2570
will automatically break the stale lock, and create a new lock for
 
2571
this process.
 
2572
Otherwise, bzr will prompt as normal to break the lock.
 
2573
'''))
 
2574
option_registry.register(
 
2575
    Option('log_format', default='long',
 
2576
           help= '''\
 
2577
Log format to use when displaying revisions.
 
2578
 
 
2579
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
 
2580
may be provided by plugins.
 
2581
'''))
 
2582
option_registry.register(
 
2583
    Option('output_encoding',
 
2584
           help= 'Unicode encoding for output'
 
2585
           ' (terminal encoding if not specified).'))
 
2586
option_registry.register(
 
2587
    Option('push_strict', default=None,
 
2588
           from_unicode=bool_from_store,
 
2589
           help='''\
 
2590
The default value for ``push --strict``.
 
2591
 
 
2592
If present, defines the ``--strict`` option default value for checking
 
2593
uncommitted changes before sending a merge directive.
 
2594
'''))
 
2595
option_registry.register(
 
2596
    Option('repository.fdatasync', default=True,
 
2597
           from_unicode=bool_from_store,
 
2598
           help='''\
 
2599
Flush repository changes onto physical disk?
 
2600
 
 
2601
If true (default), repository changes are flushed through the OS buffers
 
2602
to physical disk.  This is somewhat slower, but means data should not be
 
2603
lost if the machine crashes.  See also dirstate.fdatasync.
 
2604
'''))
 
2605
option_registry.register(
 
2606
    Option('send_strict', default=None,
 
2607
           from_unicode=bool_from_store,
 
2608
           help='''\
 
2609
The default value for ``send --strict``.
 
2610
 
 
2611
If present, defines the ``--strict`` option default value for checking
 
2612
uncommitted changes before pushing.
 
2613
'''))
 
2614
 
 
2615
option_registry.register(
 
2616
    Option('serve.client_timeout',
 
2617
           default=300.0, from_unicode=float_from_store,
 
2618
           help="If we wait for a new request from a client for more than"
 
2619
                " X seconds, consider the client idle, and hangup."))
2300
2620
 
2301
2621
 
2302
2622
class Section(object):
2312
2632
        # We re-use the dict-like object received
2313
2633
        self.options = options
2314
2634
 
2315
 
    def get(self, name, default=None):
 
2635
    def get(self, name, default=None, expand=True):
2316
2636
        return self.options.get(name, default)
2317
2637
 
 
2638
    def iter_option_names(self):
 
2639
        for k in self.options.iterkeys():
 
2640
            yield k
 
2641
 
2318
2642
    def __repr__(self):
2319
2643
        # Mostly for debugging use
2320
2644
        return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2389
2713
    def get_sections(self):
2390
2714
        """Returns an ordered iterable of existing sections.
2391
2715
 
2392
 
        :returns: An iterable of (name, dict).
 
2716
        :returns: An iterable of (store, section).
2393
2717
        """
2394
2718
        raise NotImplementedError(self.get_sections)
2395
2719
 
2396
 
    def get_mutable_section(self, section_name=None):
 
2720
    def get_mutable_section(self, section_id=None):
2397
2721
        """Returns the specified mutable section.
2398
2722
 
2399
 
        :param section_name: The section identifier
 
2723
        :param section_id: The section identifier
2400
2724
        """
2401
2725
        raise NotImplementedError(self.get_mutable_section)
2402
2726
 
2406
2730
                                    self.external_url())
2407
2731
 
2408
2732
 
 
2733
class CommandLineStore(Store):
 
2734
    "A store to carry command line overrides for the config options."""
 
2735
 
 
2736
    def __init__(self, opts=None):
 
2737
        super(CommandLineStore, self).__init__()
 
2738
        if opts is None:
 
2739
            opts = {}
 
2740
        self.options = {}
 
2741
 
 
2742
    def _reset(self):
 
2743
        # The dict should be cleared but not replaced so it can be shared.
 
2744
        self.options.clear()
 
2745
 
 
2746
    def _from_cmdline(self, overrides):
 
2747
        # Reset before accepting new definitions
 
2748
        self._reset()
 
2749
        for over in overrides:
 
2750
            try:
 
2751
                name, value = over.split('=', 1)
 
2752
            except ValueError:
 
2753
                raise errors.BzrCommandError(
 
2754
                    gettext("Invalid '%s', should be of the form 'name=value'")
 
2755
                    % (over,))
 
2756
            self.options[name] = value
 
2757
 
 
2758
    def external_url(self):
 
2759
        # Not an url but it makes debugging easier and it never needed
 
2760
        # otherwise
 
2761
        return 'cmdline'
 
2762
 
 
2763
    def get_sections(self):
 
2764
        yield self,  self.readonly_section_class('cmdline_overrides',
 
2765
                                                 self.options)
 
2766
 
 
2767
 
2409
2768
class IniFileStore(Store):
2410
2769
    """A config Store using ConfigObj for storage.
2411
2770
 
2417
2776
        serialize/deserialize the config file.
2418
2777
    """
2419
2778
 
2420
 
    def __init__(self, transport, file_name):
 
2779
    def __init__(self):
2421
2780
        """A config Store using ConfigObj for storage.
2422
 
 
2423
 
        :param transport: The transport object where the config file is located.
2424
 
 
2425
 
        :param file_name: The config file basename in the transport directory.
2426
2781
        """
2427
2782
        super(IniFileStore, self).__init__()
2428
 
        self.transport = transport
2429
 
        self.file_name = file_name
2430
2783
        self._config_obj = None
2431
2784
 
2432
2785
    def is_loaded(self):
2435
2788
    def unload(self):
2436
2789
        self._config_obj = None
2437
2790
 
 
2791
    def _load_content(self):
 
2792
        """Load the config file bytes.
 
2793
 
 
2794
        This should be provided by subclasses
 
2795
 
 
2796
        :return: Byte string
 
2797
        """
 
2798
        raise NotImplementedError(self._load_content)
 
2799
 
 
2800
    def _save_content(self, content):
 
2801
        """Save the config file bytes.
 
2802
 
 
2803
        This should be provided by subclasses
 
2804
 
 
2805
        :param content: Config file bytes to write
 
2806
        """
 
2807
        raise NotImplementedError(self._save_content)
 
2808
 
2438
2809
    def load(self):
2439
2810
        """Load the store from the associated file."""
2440
2811
        if self.is_loaded():
2441
2812
            return
2442
 
        content = self.transport.get_bytes(self.file_name)
 
2813
        content = self._load_content()
2443
2814
        self._load_from_string(content)
2444
2815
        for hook in ConfigHooks['load']:
2445
2816
            hook(self)
2454
2825
        co_input = StringIO(bytes)
2455
2826
        try:
2456
2827
            # The config files are always stored utf8-encoded
2457
 
            self._config_obj = ConfigObj(co_input, encoding='utf-8')
 
2828
            self._config_obj = ConfigObj(co_input, encoding='utf-8',
 
2829
                                         list_values=False)
2458
2830
        except configobj.ConfigObjError, e:
2459
2831
            self._config_obj = None
2460
2832
            raise errors.ParseConfigError(e.errors, self.external_url())
2467
2839
            return
2468
2840
        out = StringIO()
2469
2841
        self._config_obj.write(out)
2470
 
        self.transport.put_bytes(self.file_name, out.getvalue())
 
2842
        self._save_content(out.getvalue())
2471
2843
        for hook in ConfigHooks['save']:
2472
2844
            hook(self)
2473
2845
 
2474
 
    def external_url(self):
2475
 
        # FIXME: external_url should really accepts an optional relpath
2476
 
        # parameter (bug #750169) :-/ -- vila 2011-04-04
2477
 
        # The following will do in the interim but maybe we don't want to
2478
 
        # expose a path here but rather a config ID and its associated
2479
 
        # object </hand wawe>.
2480
 
        return urlutils.join(self.transport.external_url(), self.file_name)
2481
 
 
2482
2846
    def get_sections(self):
2483
2847
        """Get the configobj section in the file order.
2484
2848
 
2485
 
        :returns: An iterable of (name, dict).
 
2849
        :returns: An iterable of (store, section).
2486
2850
        """
2487
2851
        # We need a loaded store
2488
2852
        try:
2489
2853
            self.load()
2490
 
        except errors.NoSuchFile:
2491
 
            # If the file doesn't exist, there is no sections
 
2854
        except (errors.NoSuchFile, errors.PermissionDenied):
 
2855
            # If the file can't be read, there is no sections
2492
2856
            return
2493
2857
        cobj = self._config_obj
2494
2858
        if cobj.scalars:
2495
 
            yield self.readonly_section_class(None, cobj)
 
2859
            yield self, self.readonly_section_class(None, cobj)
2496
2860
        for section_name in cobj.sections:
2497
 
            yield self.readonly_section_class(section_name, cobj[section_name])
 
2861
            yield (self,
 
2862
                   self.readonly_section_class(section_name,
 
2863
                                               cobj[section_name]))
2498
2864
 
2499
 
    def get_mutable_section(self, section_name=None):
 
2865
    def get_mutable_section(self, section_id=None):
2500
2866
        # We need a loaded store
2501
2867
        try:
2502
2868
            self.load()
2503
2869
        except errors.NoSuchFile:
2504
2870
            # The file doesn't exist, let's pretend it was empty
2505
2871
            self._load_from_string('')
2506
 
        if section_name is None:
 
2872
        if section_id is None:
2507
2873
            section = self._config_obj
2508
2874
        else:
2509
 
            section = self._config_obj.setdefault(section_name, {})
2510
 
        return self.mutable_section_class(section_name, section)
 
2875
            section = self._config_obj.setdefault(section_id, {})
 
2876
        return self.mutable_section_class(section_id, section)
 
2877
 
 
2878
 
 
2879
class TransportIniFileStore(IniFileStore):
 
2880
    """IniFileStore that loads files from a transport.
 
2881
    """
 
2882
 
 
2883
    def __init__(self, transport, file_name):
 
2884
        """A Store using a ini file on a Transport
 
2885
 
 
2886
        :param transport: The transport object where the config file is located.
 
2887
        :param file_name: The config file basename in the transport directory.
 
2888
        """
 
2889
        super(TransportIniFileStore, self).__init__()
 
2890
        self.transport = transport
 
2891
        self.file_name = file_name
 
2892
 
 
2893
    def _load_content(self):
 
2894
        try:
 
2895
            return self.transport.get_bytes(self.file_name)
 
2896
        except errors.PermissionDenied:
 
2897
            trace.warning("Permission denied while trying to load "
 
2898
                          "configuration store %s.", self.external_url())
 
2899
            raise
 
2900
 
 
2901
    def _save_content(self, content):
 
2902
        self.transport.put_bytes(self.file_name, content)
 
2903
 
 
2904
    def external_url(self):
 
2905
        # FIXME: external_url should really accepts an optional relpath
 
2906
        # parameter (bug #750169) :-/ -- vila 2011-04-04
 
2907
        # The following will do in the interim but maybe we don't want to
 
2908
        # expose a path here but rather a config ID and its associated
 
2909
        # object </hand wawe>.
 
2910
        return urlutils.join(self.transport.external_url(), self.file_name)
2511
2911
 
2512
2912
 
2513
2913
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
2516
2916
# they may face the same issue.
2517
2917
 
2518
2918
 
2519
 
class LockableIniFileStore(IniFileStore):
 
2919
class LockableIniFileStore(TransportIniFileStore):
2520
2920
    """A ConfigObjStore using locks on save to ensure store integrity."""
2521
2921
 
2522
2922
    def __init__(self, transport, file_name, lock_dir_name=None):
2569
2969
class GlobalStore(LockableIniFileStore):
2570
2970
 
2571
2971
    def __init__(self, possible_transports=None):
2572
 
        t = transport.get_transport(config_dir(),
2573
 
                                    possible_transports=possible_transports)
 
2972
        t = transport.get_transport_from_path(
 
2973
            config_dir(), possible_transports=possible_transports)
2574
2974
        super(GlobalStore, self).__init__(t, 'bazaar.conf')
 
2975
        self.id = 'bazaar'
2575
2976
 
2576
2977
 
2577
2978
class LocationStore(LockableIniFileStore):
2578
2979
 
2579
2980
    def __init__(self, possible_transports=None):
2580
 
        t = transport.get_transport(config_dir(),
2581
 
                                    possible_transports=possible_transports)
 
2981
        t = transport.get_transport_from_path(
 
2982
            config_dir(), possible_transports=possible_transports)
2582
2983
        super(LocationStore, self).__init__(t, 'locations.conf')
2583
 
 
2584
 
 
2585
 
class BranchStore(IniFileStore):
 
2984
        self.id = 'locations'
 
2985
 
 
2986
 
 
2987
class BranchStore(TransportIniFileStore):
2586
2988
 
2587
2989
    def __init__(self, branch):
2588
2990
        super(BranchStore, self).__init__(branch.control_transport,
2589
2991
                                          'branch.conf')
2590
2992
        self.branch = branch
 
2993
        self.id = 'branch'
2591
2994
 
2592
2995
    def lock_write(self, token=None):
2593
2996
        return self.branch.lock_write(token)
2604
3007
        super(BranchStore, self).save()
2605
3008
 
2606
3009
 
 
3010
class ControlStore(LockableIniFileStore):
 
3011
 
 
3012
    def __init__(self, bzrdir):
 
3013
        super(ControlStore, self).__init__(bzrdir.transport,
 
3014
                                          'control.conf',
 
3015
                                           lock_dir_name='branch_lock')
 
3016
 
 
3017
 
2607
3018
class SectionMatcher(object):
2608
3019
    """Select sections into a given Store.
2609
3020
 
2610
 
    This intended to be used to postpone getting an iterable of sections from a
2611
 
    store.
 
3021
    This is intended to be used to postpone getting an iterable of sections
 
3022
    from a store.
2612
3023
    """
2613
3024
 
2614
3025
    def __init__(self, store):
2619
3030
        # sections.
2620
3031
        sections = self.store.get_sections()
2621
3032
        # Walk the revisions in the order provided
2622
 
        for s in sections:
 
3033
        for store, s in sections:
2623
3034
            if self.match(s):
2624
 
                yield s
2625
 
 
2626
 
    def match(self, secion):
 
3035
                yield store, s
 
3036
 
 
3037
    def match(self, section):
 
3038
        """Does the proposed section match.
 
3039
 
 
3040
        :param section: A Section object.
 
3041
 
 
3042
        :returns: True if the section matches, False otherwise.
 
3043
        """
2627
3044
        raise NotImplementedError(self.match)
2628
3045
 
2629
3046
 
 
3047
class NameMatcher(SectionMatcher):
 
3048
 
 
3049
    def __init__(self, store, section_id):
 
3050
        super(NameMatcher, self).__init__(store)
 
3051
        self.section_id = section_id
 
3052
 
 
3053
    def match(self, section):
 
3054
        return section.id == self.section_id
 
3055
 
 
3056
 
2630
3057
class LocationSection(Section):
2631
3058
 
2632
3059
    def __init__(self, section, length, extra_path):
2633
3060
        super(LocationSection, self).__init__(section.id, section.options)
2634
3061
        self.length = length
2635
3062
        self.extra_path = extra_path
 
3063
        self.locals = {'relpath': extra_path,
 
3064
                       'basename': urlutils.basename(extra_path)}
2636
3065
 
2637
 
    def get(self, name, default=None):
 
3066
    def get(self, name, default=None, expand=True):
2638
3067
        value = super(LocationSection, self).get(name, default)
2639
 
        if value is not None:
 
3068
        if value is not None and expand:
2640
3069
            policy_name = self.get(name + ':policy', None)
2641
3070
            policy = _policy_value.get(policy_name, POLICY_NONE)
2642
3071
            if policy == POLICY_APPENDPATH:
2643
3072
                value = urlutils.join(value, self.extra_path)
 
3073
            # expand section local options right now (since POLICY_APPENDPATH
 
3074
            # will never add options references, it's ok to expand after it).
 
3075
            chunks = []
 
3076
            for is_ref, chunk in iter_option_refs(value):
 
3077
                if not is_ref:
 
3078
                    chunks.append(chunk)
 
3079
                else:
 
3080
                    ref = chunk[1:-1]
 
3081
                    if ref in self.locals:
 
3082
                        chunks.append(self.locals[ref])
 
3083
                    else:
 
3084
                        chunks.append(chunk)
 
3085
            value = ''.join(chunks)
2644
3086
        return value
2645
3087
 
2646
3088
 
2660
3102
        all_sections = []
2661
3103
        # Filter out the no_name_section so _iter_for_location_by_parts can be
2662
3104
        # used (it assumes all sections have a name).
2663
 
        for section in self.store.get_sections():
 
3105
        for _, section in self.store.get_sections():
2664
3106
            if section.id is None:
2665
3107
                no_name_section = section
2666
3108
            else:
2703
3145
            if ignore:
2704
3146
                break
2705
3147
            # Finally, we have a valid section
2706
 
            yield section
 
3148
            yield self.store, section
 
3149
 
 
3150
 
 
3151
_option_ref_re = lazy_regex.lazy_compile('({[^{}]+})')
 
3152
"""Describes an expandable option reference.
 
3153
 
 
3154
We want to match the most embedded reference first.
 
3155
 
 
3156
I.e. for '{{foo}}' we will get '{foo}',
 
3157
for '{bar{baz}}' we will get '{baz}'
 
3158
"""
 
3159
 
 
3160
def iter_option_refs(string):
 
3161
    # Split isolate refs so every other chunk is a ref
 
3162
    is_ref = False
 
3163
    for chunk  in _option_ref_re.split(string):
 
3164
        yield is_ref, chunk
 
3165
        is_ref = not is_ref
2707
3166
 
2708
3167
 
2709
3168
class Stack(object):
2710
3169
    """A stack of configurations where an option can be defined"""
2711
3170
 
2712
 
    def __init__(self, sections_def, store=None, mutable_section_name=None):
 
3171
    def __init__(self, sections_def, store=None, mutable_section_id=None):
2713
3172
        """Creates a stack of sections with an optional store for changes.
2714
3173
 
2715
3174
        :param sections_def: A list of Section or callables that returns an
2719
3178
        :param store: The optional Store where modifications will be
2720
3179
            recorded. If none is specified, no modifications can be done.
2721
3180
 
2722
 
        :param mutable_section_name: The name of the MutableSection where
2723
 
            changes are recorded. This requires the ``store`` parameter to be
 
3181
        :param mutable_section_id: The id of the MutableSection where changes
 
3182
            are recorded. This requires the ``store`` parameter to be
2724
3183
            specified.
2725
3184
        """
2726
3185
        self.sections_def = sections_def
2727
3186
        self.store = store
2728
 
        self.mutable_section_name = mutable_section_name
 
3187
        self.mutable_section_id = mutable_section_id
2729
3188
 
2730
 
    def get(self, name):
 
3189
    def get(self, name, expand=None):
2731
3190
        """Return the *first* option value found in the sections.
2732
3191
 
2733
3192
        This is where we guarantee that sections coming from Store are loaded
2735
3194
        option exists or get its value, which in turn may require to discover
2736
3195
        in which sections it can be defined. Both of these (section and option
2737
3196
        existence) require loading the store (even partially).
 
3197
 
 
3198
        :param name: The queried option.
 
3199
 
 
3200
        :param expand: Whether options references should be expanded.
 
3201
 
 
3202
        :returns: The value of the option.
2738
3203
        """
2739
3204
        # FIXME: No caching of options nor sections yet -- vila 20110503
 
3205
        if expand is None:
 
3206
            expand = _get_expand_default_value()
2740
3207
        value = None
2741
3208
        # Ensuring lazy loading is achieved by delaying section matching (which
2742
3209
        # implies querying the persistent storage) until it can't be avoided
2743
3210
        # anymore by using callables to describe (possibly empty) section
2744
3211
        # lists.
2745
 
        for section_or_callable in self.sections_def:
2746
 
            # Each section can expand to multiple ones when a callable is used
2747
 
            if callable(section_or_callable):
2748
 
                sections = section_or_callable()
2749
 
            else:
2750
 
                sections = [section_or_callable]
2751
 
            for section in sections:
 
3212
        for sections in self.sections_def:
 
3213
            for store, section in sections():
2752
3214
                value = section.get(name)
2753
3215
                if value is not None:
2754
3216
                    break
2761
3223
        except KeyError:
2762
3224
            # Not registered
2763
3225
            opt = None
2764
 
        if (opt is not None and opt.from_unicode is not None
2765
 
            and value is not None):
2766
 
            # If a value exists and the option provides a converter, use it
2767
 
            try:
2768
 
                converted = opt.from_unicode(value)
2769
 
            except (ValueError, TypeError):
2770
 
                # Invalid values are ignored
2771
 
                converted = None
2772
 
            value = converted
2773
 
        if value is None:
 
3226
        def expand_and_convert(val):
 
3227
            # This may need to be called twice if the value is None or ends up
 
3228
            # being None during expansion or conversion.
 
3229
            if val is not None:
 
3230
                if expand:
 
3231
                    if isinstance(val, basestring):
 
3232
                        val = self._expand_options_in_string(val)
 
3233
                    else:
 
3234
                        trace.warning('Cannot expand "%s":'
 
3235
                                      ' %s does not support option expansion'
 
3236
                                      % (name, type(val)))
 
3237
                if opt is not None:
 
3238
                    val = opt.convert_from_unicode(val)
 
3239
            return val
 
3240
        value = expand_and_convert(value)
 
3241
        if opt is not None and value is None:
2774
3242
            # If the option is registered, it may provide a default value
2775
 
            if opt is not None:
2776
 
                value = opt.get_default()
2777
 
        if opt is not None and value is None:
2778
3243
            value = opt.get_default()
 
3244
            value = expand_and_convert(value)
2779
3245
        for hook in ConfigHooks['get']:
2780
3246
            hook(self, name, value)
2781
3247
        return value
2782
3248
 
 
3249
    def expand_options(self, string, env=None):
 
3250
        """Expand option references in the string in the configuration context.
 
3251
 
 
3252
        :param string: The string containing option(s) to expand.
 
3253
 
 
3254
        :param env: An option dict defining additional configuration options or
 
3255
            overriding existing ones.
 
3256
 
 
3257
        :returns: The expanded string.
 
3258
        """
 
3259
        return self._expand_options_in_string(string, env)
 
3260
 
 
3261
    def _expand_options_in_string(self, string, env=None, _refs=None):
 
3262
        """Expand options in the string in the configuration context.
 
3263
 
 
3264
        :param string: The string to be expanded.
 
3265
 
 
3266
        :param env: An option dict defining additional configuration options or
 
3267
            overriding existing ones.
 
3268
 
 
3269
        :param _refs: Private list (FIFO) containing the options being expanded
 
3270
            to detect loops.
 
3271
 
 
3272
        :returns: The expanded string.
 
3273
        """
 
3274
        if string is None:
 
3275
            # Not much to expand there
 
3276
            return None
 
3277
        if _refs is None:
 
3278
            # What references are currently resolved (to detect loops)
 
3279
            _refs = []
 
3280
        result = string
 
3281
        # We need to iterate until no more refs appear ({{foo}} will need two
 
3282
        # iterations for example).
 
3283
        expanded = True
 
3284
        while expanded:
 
3285
            expanded = False
 
3286
            chunks = []
 
3287
            for is_ref, chunk in iter_option_refs(result):
 
3288
                if not is_ref:
 
3289
                    chunks.append(chunk)
 
3290
                else:
 
3291
                    expanded = True
 
3292
                    name = chunk[1:-1]
 
3293
                    if name in _refs:
 
3294
                        raise errors.OptionExpansionLoop(string, _refs)
 
3295
                    _refs.append(name)
 
3296
                    value = self._expand_option(name, env, _refs)
 
3297
                    if value is None:
 
3298
                        raise errors.ExpandingUnknownOption(name, string)
 
3299
                    chunks.append(value)
 
3300
                    _refs.pop()
 
3301
            result = ''.join(chunks)
 
3302
        return result
 
3303
 
 
3304
    def _expand_option(self, name, env, _refs):
 
3305
        if env is not None and name in env:
 
3306
            # Special case, values provided in env takes precedence over
 
3307
            # anything else
 
3308
            value = env[name]
 
3309
        else:
 
3310
            value = self.get(name, expand=False)
 
3311
            value = self._expand_options_in_string(value, env, _refs)
 
3312
        return value
 
3313
 
2783
3314
    def _get_mutable_section(self):
2784
3315
        """Get the MutableSection for the Stack.
2785
3316
 
2786
3317
        This is where we guarantee that the mutable section is lazily loaded:
2787
3318
        this means we won't load the corresponding store before setting a value
2788
3319
        or deleting an option. In practice the store will often be loaded but
2789
 
        this allows helps catching some programming errors.
 
3320
        this helps catching some programming errors.
2790
3321
        """
2791
 
        section = self.store.get_mutable_section(self.mutable_section_name)
 
3322
        section = self.store.get_mutable_section(self.mutable_section_id)
2792
3323
        return section
2793
3324
 
2794
3325
    def set(self, name, value):
2809
3340
        # Mostly for debugging use
2810
3341
        return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
2811
3342
 
 
3343
    def _get_overrides(self):
 
3344
        # Hack around library_state.initialize never called
 
3345
        if bzrlib.global_state is not None:
 
3346
            return bzrlib.global_state.cmdline_overrides.get_sections()
 
3347
        return []
 
3348
 
2812
3349
 
2813
3350
class _CompatibleStack(Stack):
2814
3351
    """Place holder for compatibility with previous design.
2819
3356
    One assumption made here is that the daughter classes will all use Stores
2820
3357
    derived from LockableIniFileStore).
2821
3358
 
2822
 
    It implements set() by re-loading the store before applying the
2823
 
    modification and saving it.
 
3359
    It implements set() and remove () by re-loading the store before applying
 
3360
    the modification and saving it.
2824
3361
 
2825
3362
    The long term plan being to implement a single write by store to save
2826
3363
    all modifications, this class should not be used in the interim.
2833
3370
        # Force a write to persistent storage
2834
3371
        self.store.save()
2835
3372
 
 
3373
    def remove(self, name):
 
3374
        # Force a reload
 
3375
        self.store.unload()
 
3376
        super(_CompatibleStack, self).remove(name)
 
3377
        # Force a write to persistent storage
 
3378
        self.store.save()
 
3379
 
2836
3380
 
2837
3381
class GlobalStack(_CompatibleStack):
 
3382
    """Global options only stack."""
2838
3383
 
2839
3384
    def __init__(self):
2840
3385
        # Get a GlobalStore
2841
3386
        gstore = GlobalStore()
2842
 
        super(GlobalStack, self).__init__([gstore.get_sections], gstore)
 
3387
        super(GlobalStack, self).__init__(
 
3388
            [self._get_overrides, NameMatcher(gstore, 'DEFAULT').get_sections],
 
3389
            gstore, mutable_section_id='DEFAULT')
2843
3390
 
2844
3391
 
2845
3392
class LocationStack(_CompatibleStack):
 
3393
    """Per-location options falling back to global options stack."""
2846
3394
 
2847
3395
    def __init__(self, location):
2848
3396
        """Make a new stack for a location and global configuration.
2849
3397
        
2850
3398
        :param location: A URL prefix to """
2851
3399
        lstore = LocationStore()
 
3400
        if location.startswith('file://'):
 
3401
            location = urlutils.local_path_from_url(location)
2852
3402
        matcher = LocationMatcher(lstore, location)
2853
3403
        gstore = GlobalStore()
2854
3404
        super(LocationStack, self).__init__(
2855
 
            [matcher.get_sections, gstore.get_sections], lstore)
 
3405
            [self._get_overrides,
 
3406
             matcher.get_sections, NameMatcher(gstore, 'DEFAULT').get_sections],
 
3407
            lstore, mutable_section_id=location)
 
3408
 
2856
3409
 
2857
3410
class BranchStack(_CompatibleStack):
 
3411
    """Per-location options falling back to branch then global options stack."""
2858
3412
 
2859
3413
    def __init__(self, branch):
2860
 
        bstore = BranchStore(branch)
 
3414
        bstore = branch._get_config_store()
2861
3415
        lstore = LocationStore()
2862
3416
        matcher = LocationMatcher(lstore, branch.base)
2863
3417
        gstore = GlobalStore()
2864
3418
        super(BranchStack, self).__init__(
2865
 
            [matcher.get_sections, bstore.get_sections, gstore.get_sections],
2866
 
            bstore)
2867
 
        self.branch = branch
2868
 
 
 
3419
            [self._get_overrides,
 
3420
             matcher.get_sections, bstore.get_sections,
 
3421
             NameMatcher(gstore, 'DEFAULT').get_sections],
 
3422
            bstore)
 
3423
        self.branch = branch
 
3424
 
 
3425
 
 
3426
class RemoteControlStack(_CompatibleStack):
 
3427
    """Remote control-only options stack."""
 
3428
 
 
3429
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
 
3430
    # with the stack used for remote bzr dirs. RemoteControlStack only uses
 
3431
    # control.conf and is used only for stack options.
 
3432
 
 
3433
    def __init__(self, bzrdir):
 
3434
        cstore = bzrdir._get_config_store()
 
3435
        super(RemoteControlStack, self).__init__(
 
3436
            [cstore.get_sections],
 
3437
            cstore)
 
3438
        self.bzrdir = bzrdir
 
3439
 
 
3440
 
 
3441
class RemoteBranchStack(_CompatibleStack):
 
3442
    """Remote branch-only options stack."""
 
3443
 
 
3444
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
 
3445
    # with the stack used for remote branches. RemoteBranchStack only uses
 
3446
    # branch.conf and is used only for the stack options.
 
3447
 
 
3448
    def __init__(self, branch):
 
3449
        bstore = branch._get_config_store()
 
3450
        super(RemoteBranchStack, self).__init__(
 
3451
            [bstore.get_sections],
 
3452
            bstore)
 
3453
        self.branch = branch
 
3454
 
 
3455
# Use a an empty dict to initialize an empty configobj avoiding all
 
3456
# parsing and encoding checks
 
3457
_quoting_config = configobj.ConfigObj(
 
3458
    {}, encoding='utf-8', interpolation=False)
2869
3459
 
2870
3460
class cmd_config(commands.Command):
2871
3461
    __doc__ = """Display, set or remove a configuration option.
2888
3478
    takes_options = [
2889
3479
        'directory',
2890
3480
        # FIXME: This should be a registry option so that plugins can register
2891
 
        # their own config files (or not) -- vila 20101002
 
3481
        # their own config files (or not) and will also address
 
3482
        # http://pad.lv/788991 -- vila 20101115
2892
3483
        commands.Option('scope', help='Reduce the scope to the specified'
2893
3484
                        ' configuration file',
2894
3485
                        type=unicode),
2932
3523
                # Set the option value
2933
3524
                self._set_config_option(name, value, directory, scope)
2934
3525
 
2935
 
    def _get_configs(self, directory, scope=None):
2936
 
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
3526
    def _get_stack(self, directory, scope=None):
 
3527
        """Get the configuration stack specified by ``directory`` and ``scope``.
2937
3528
 
2938
3529
        :param directory: Where the configurations are derived from.
2939
3530
 
2940
3531
        :param scope: A specific config to start from.
2941
3532
        """
 
3533
        # FIXME: scope should allow access to plugin-specific stacks (even
 
3534
        # reduced to the plugin-specific store), related to
 
3535
        # http://pad.lv/788991 -- vila 2011-11-15
2942
3536
        if scope is not None:
2943
3537
            if scope == 'bazaar':
2944
 
                yield GlobalConfig()
 
3538
                return GlobalStack()
2945
3539
            elif scope == 'locations':
2946
 
                yield LocationConfig(directory)
 
3540
                return LocationStack(directory)
2947
3541
            elif scope == 'branch':
2948
 
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2949
 
                    directory)
2950
 
                yield br.get_config()
 
3542
                (_, br, _) = (
 
3543
                    controldir.ControlDir.open_containing_tree_or_branch(
 
3544
                        directory))
 
3545
                return br.get_config_stack()
 
3546
            raise errors.NoSuchConfig(scope)
2951
3547
        else:
2952
3548
            try:
2953
 
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2954
 
                    directory)
2955
 
                yield br.get_config()
 
3549
                (_, br, _) = (
 
3550
                    controldir.ControlDir.open_containing_tree_or_branch(
 
3551
                        directory))
 
3552
                return br.get_config_stack()
2956
3553
            except errors.NotBranchError:
2957
 
                yield LocationConfig(directory)
2958
 
                yield GlobalConfig()
 
3554
                return LocationStack(directory)
2959
3555
 
2960
3556
    def _show_value(self, name, directory, scope):
2961
 
        displayed = False
2962
 
        for c in self._get_configs(directory, scope):
2963
 
            if displayed:
2964
 
                break
2965
 
            for (oname, value, section, conf_id, parser) in c._get_options():
2966
 
                if name == oname:
2967
 
                    # Display only the first value and exit
2968
 
 
2969
 
                    # FIXME: We need to use get_user_option to take policies
2970
 
                    # into account and we need to make sure the option exists
2971
 
                    # too (hence the two for loops), this needs a better API
2972
 
                    # -- vila 20101117
2973
 
                    value = c.get_user_option(name)
2974
 
                    # Quote the value appropriately
2975
 
                    value = parser._quote(value)
2976
 
                    self.outf.write('%s\n' % (value,))
2977
 
                    displayed = True
2978
 
                    break
2979
 
        if not displayed:
 
3557
        conf = self._get_stack(directory, scope)
 
3558
        value = conf.get(name, expand=True)
 
3559
        if value is not None:
 
3560
            # Quote the value appropriately
 
3561
            value = _quoting_config._quote(value)
 
3562
            self.outf.write('%s\n' % (value,))
 
3563
        else:
2980
3564
            raise errors.NoSuchConfigOption(name)
2981
3565
 
2982
3566
    def _show_matching_options(self, name, directory, scope):
2985
3569
        # avoid the delay introduced by the lazy regexp.  But, we still do
2986
3570
        # want the nicer errors raised by lazy_regex.
2987
3571
        name._compile_and_collapse()
2988
 
        cur_conf_id = None
 
3572
        cur_store_id = None
2989
3573
        cur_section = None
2990
 
        for c in self._get_configs(directory, scope):
2991
 
            for (oname, value, section, conf_id, parser) in c._get_options():
2992
 
                if name.search(oname):
2993
 
                    if cur_conf_id != conf_id:
2994
 
                        # Explain where the options are defined
2995
 
                        self.outf.write('%s:\n' % (conf_id,))
2996
 
                        cur_conf_id = conf_id
2997
 
                        cur_section = None
2998
 
                    if (section not in (None, 'DEFAULT')
2999
 
                        and cur_section != section):
3000
 
                        # Display the section if it's not the default (or only)
3001
 
                        # one.
3002
 
                        self.outf.write('  [%s]\n' % (section,))
3003
 
                        cur_section = section
3004
 
                    self.outf.write('  %s = %s\n' % (oname, value))
 
3574
        conf = self._get_stack(directory, scope)
 
3575
        for sections in conf.sections_def:
 
3576
            for store, section in sections():
 
3577
                for oname in section.iter_option_names():
 
3578
                    if name.search(oname):
 
3579
                        if cur_store_id != store.id:
 
3580
                            # Explain where the options are defined
 
3581
                            self.outf.write('%s:\n' % (store.id,))
 
3582
                            cur_store_id = store.id
 
3583
                            cur_section = None
 
3584
                        if (section.id not in (None, 'DEFAULT')
 
3585
                            and cur_section != section.id):
 
3586
                            # Display the section if it's not the default (or
 
3587
                            # only) one.
 
3588
                            self.outf.write('  [%s]\n' % (section.id,))
 
3589
                            cur_section = section.id
 
3590
                        value = section.get(oname, expand=False)
 
3591
                        value = _quoting_config._quote(value)
 
3592
                        self.outf.write('  %s = %s\n' % (oname, value))
3005
3593
 
3006
3594
    def _set_config_option(self, name, value, directory, scope):
3007
 
        for conf in self._get_configs(directory, scope):
3008
 
            conf.set_user_option(name, value)
3009
 
            break
3010
 
        else:
3011
 
            raise errors.NoSuchConfig(scope)
 
3595
        conf = self._get_stack(directory, scope)
 
3596
        conf.set(name, value)
3012
3597
 
3013
3598
    def _remove_config_option(self, name, directory, scope):
3014
3599
        if name is None:
3015
3600
            raise errors.BzrCommandError(
3016
3601
                '--remove expects an option to remove.')
3017
 
        removed = False
3018
 
        for conf in self._get_configs(directory, scope):
3019
 
            for (section_name, section, conf_id) in conf._get_sections():
3020
 
                if scope is not None and conf_id != scope:
3021
 
                    # Not the right configuration file
3022
 
                    continue
3023
 
                if name in section:
3024
 
                    if conf_id != conf.config_id():
3025
 
                        conf = self._get_configs(directory, conf_id).next()
3026
 
                    # We use the first section in the first config where the
3027
 
                    # option is defined to remove it
3028
 
                    conf.remove_user_option(name, section_name)
3029
 
                    removed = True
3030
 
                    break
3031
 
            break
3032
 
        else:
3033
 
            raise errors.NoSuchConfig(scope)
3034
 
        if not removed:
 
3602
        conf = self._get_stack(directory, scope)
 
3603
        try:
 
3604
            conf.remove(name)
 
3605
        except KeyError:
3035
3606
            raise errors.NoSuchConfigOption(name)
3036
3607
 
 
3608
 
3037
3609
# Test registries
3038
3610
#
3039
3611
# We need adapters that can build a Store or a Stack in a test context. Test