~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Ross Lagerwall
  • Date: 2012-08-07 06:32:51 UTC
  • mto: (6437.63.5 2.5)
  • mto: This revision was merged to the branch mainline in revision 6558.
  • Revision ID: rosslagerwall@gmail.com-20120807063251-x9p03ghg2ws8oqjc
Add bzrlib/locale to .bzrignore

bzrlib/locale is generated with ./setup.py build_mo which is in turn called
by ./setup.py build

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2014, 2016 Canonical Ltd
 
1
# Copyright (C) 2005-2012 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
55
55
                   turns on create_signatures.
56
56
create_signatures - this option controls whether bzr will always create
57
57
                    gpg signatures or not on commits.  There is an unused
58
 
                    option which in future is expected to work if
 
58
                    option which in future is expected to work if               
59
59
                    branch settings require signatures.
60
60
log_format - this option sets the default log format.  Possible values are
61
61
             long, short, line, or a plugin can register new formats.
81
81
from bzrlib.decorators import needs_write_lock
82
82
from bzrlib.lazy_import import lazy_import
83
83
lazy_import(globals(), """
84
 
import base64
85
84
import fnmatch
86
85
import re
87
86
 
94
93
    lazy_regex,
95
94
    library_state,
96
95
    lockdir,
 
96
    mail_client,
97
97
    mergetools,
98
98
    osutils,
99
99
    symbol_versioning,
197
197
        return self[section][name]
198
198
 
199
199
 
 
200
# FIXME: Until we can guarantee that each config file is loaded once and
 
201
# only once for a given bzrlib session, we don't want to re-read the file every
 
202
# time we query for an option so we cache the value (bad ! watch out for tests
 
203
# needing to restore the proper value). -- vila 20110219
 
204
_expand_default_value = None
 
205
def _get_expand_default_value():
 
206
    global _expand_default_value
 
207
    if _expand_default_value is not None:
 
208
        return _expand_default_value
 
209
    conf = GlobalConfig()
 
210
    # Note that we must not use None for the expand value below or we'll run
 
211
    # into infinite recursion. Using False really would be quite silly ;)
 
212
    expand = conf.get_user_option_as_bool('bzr.config.expand', expand=True)
 
213
    if expand is None:
 
214
        # This is an opt-in feature, you *really* need to clearly say you want
 
215
        # to activate it !
 
216
        expand = False
 
217
    _expand_default_value = expand
 
218
    return expand
 
219
 
 
220
 
200
221
class Config(object):
201
222
    """A configuration policy - what username, editor, gpg needs etc."""
202
223
 
207
228
        """Returns a unique ID for the config."""
208
229
        raise NotImplementedError(self.config_id)
209
230
 
 
231
    @deprecated_method(deprecated_in((2, 4, 0)))
 
232
    def get_editor(self):
 
233
        """Get the users pop up editor."""
 
234
        raise NotImplementedError
 
235
 
210
236
    def get_change_editor(self, old_tree, new_tree):
211
237
        from bzrlib import diff
212
238
        cmd = self._get_change_editor()
215
241
        return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
216
242
                                             sys.stdout)
217
243
 
 
244
    def get_mail_client(self):
 
245
        """Get a mail client to use"""
 
246
        selected_client = self.get_user_option('mail_client')
 
247
        _registry = mail_client.mail_client_registry
 
248
        try:
 
249
            mail_client_class = _registry.get(selected_client)
 
250
        except KeyError:
 
251
            raise errors.UnknownMailClient(selected_client)
 
252
        return mail_client_class(self)
 
253
 
218
254
    def _get_signature_checking(self):
219
255
        """Template method to override signature checking policy."""
220
256
 
349
385
        """Template method to provide a user option."""
350
386
        return None
351
387
 
352
 
    def get_user_option(self, option_name, expand=True):
 
388
    def get_user_option(self, option_name, expand=None):
353
389
        """Get a generic option - no special process, no default.
354
390
 
355
391
        :param option_name: The queried option.
358
394
 
359
395
        :returns: The value of the option.
360
396
        """
 
397
        if expand is None:
 
398
            expand = _get_expand_default_value()
361
399
        value = self._get_user_option(option_name)
362
400
        if expand:
363
401
            if isinstance(value, list):
611
649
        for (oname, value, section, conf_id, parser) in self._get_options():
612
650
            if oname.startswith('bzr.mergetool.'):
613
651
                tool_name = oname[len('bzr.mergetool.'):]
614
 
                tools[tool_name] = self.get_user_option(oname, False)
 
652
                tools[tool_name] = self.get_user_option(oname)
615
653
        trace.mutter('loaded merge tools: %r' % tools)
616
654
        return tools
617
655
 
1053
1091
        conf._create_from_string(str_or_unicode, save)
1054
1092
        return conf
1055
1093
 
 
1094
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1095
    def get_editor(self):
 
1096
        return self._get_user_option('editor')
 
1097
 
1056
1098
    @needs_write_lock
1057
1099
    def set_user_option(self, option, value):
1058
1100
        """Save option and its value in the configuration."""
1488
1530
    """Return per-user configuration directory as unicode string
1489
1531
 
1490
1532
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1491
 
    and Linux.  On Mac OS X and Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1533
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1492
1534
    that will be used instead.
1493
1535
 
1494
1536
    TODO: Global option --config-dir to override this.
1503
1545
        #                APPDATA, but hard to move. See bug 348640 for more.
1504
1546
        return osutils.pathjoin(base, 'bazaar', '2.0')
1505
1547
    if base is None:
1506
 
        xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1507
 
        if xdg_dir is None:
1508
 
            xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1509
 
        xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1510
 
        if osutils.isdir(xdg_dir):
1511
 
            trace.mutter(
1512
 
                "Using configuration in XDG directory %s." % xdg_dir)
1513
 
            return xdg_dir
 
1548
        # GZ 2012-02-01: What should OSX use instead of XDG if anything?
 
1549
        if sys.platform != 'darwin':
 
1550
            xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
 
1551
            if xdg_dir is None:
 
1552
                xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
 
1553
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1554
            if osutils.isdir(xdg_dir):
 
1555
                trace.mutter(
 
1556
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1557
                return xdg_dir
1514
1558
        base = osutils._get_home_dir()
1515
1559
    return osutils.pathjoin(base, ".bazaar")
1516
1560
 
1555
1599
def xdg_cache_dir():
1556
1600
    # See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1557
1601
    # Possibly this should be different on Windows?
1558
 
    e = os.environ.get('XDG_CACHE_HOME', None)
 
1602
    e = os.environ.get('XDG_CACHE_DIR', None)
1559
1603
    if e:
1560
1604
        return e
1561
1605
    else:
1562
1606
        return os.path.expanduser('~/.cache')
1563
1607
 
1564
1608
 
1565
 
def _get_default_mail_domain(mailname_file='/etc/mailname'):
 
1609
def _get_default_mail_domain():
1566
1610
    """If possible, return the assumed default email domain.
1567
1611
 
1568
1612
    :returns: string mail domain, or None.
1571
1615
        # No implementation yet; patches welcome
1572
1616
        return None
1573
1617
    try:
1574
 
        f = open(mailname_file)
 
1618
        f = open('/etc/mailname')
1575
1619
    except (IOError, OSError), e:
1576
1620
        return None
1577
1621
    try:
1578
 
        domain = f.readline().strip()
 
1622
        domain = f.read().strip()
1579
1623
        return domain
1580
1624
    finally:
1581
1625
        f.close()
2131
2175
credential_store_registry.default_key = 'plain'
2132
2176
 
2133
2177
 
2134
 
class Base64CredentialStore(CredentialStore):
2135
 
    __doc__ = """Base64 credential store for the authentication.conf file"""
2136
 
 
2137
 
    def decode_password(self, credentials):
2138
 
        """See CredentialStore.decode_password."""
2139
 
        # GZ 2012-07-28: Will raise binascii.Error if password is not base64,
2140
 
        #                should probably propogate as something more useful.
2141
 
        return base64.decodestring(credentials['password'])
2142
 
 
2143
 
credential_store_registry.register('base64', Base64CredentialStore,
2144
 
                                   help=Base64CredentialStore.__doc__)
2145
 
 
2146
 
 
2147
2178
class BzrDirConfig(object):
2148
2179
 
2149
2180
    def __init__(self, bzrdir):
2155
2186
 
2156
2187
        It may be set to a location, or None.
2157
2188
 
2158
 
        This policy affects all branches contained by this control dir, except
2159
 
        for those under repositories.
 
2189
        This policy affects all branches contained by this bzrdir, except for
 
2190
        those under repositories.
2160
2191
        """
2161
2192
        if self._config is None:
2162
 
            raise errors.BzrError("Cannot set configuration in %s"
2163
 
                                  % self._bzrdir)
 
2193
            raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
2164
2194
        if value is None:
2165
2195
            self._config.set_option('', 'default_stack_on')
2166
2196
        else:
2171
2201
 
2172
2202
        This will either be a location, or None.
2173
2203
 
2174
 
        This policy affects all branches contained by this control dir, except
2175
 
        for those under repositories.
 
2204
        This policy affects all branches contained by this bzrdir, except for
 
2205
        those under repositories.
2176
2206
        """
2177
2207
        if self._config is None:
2178
2208
            return None
2314
2344
        :param help: a doc string to explain the option to the user.
2315
2345
 
2316
2346
        :param from_unicode: a callable to convert the unicode string
2317
 
            representing the option value in a store or its default value.
 
2347
            representing the option value in a store. This is not called for
 
2348
            the default value.
2318
2349
 
2319
2350
        :param invalid: the action to be taken when an invalid value is
2320
2351
            encountered in a store. This is called only when from_unicode is
2354
2385
            raise AssertionError('%r is not supported as a default value'
2355
2386
                                 % (default,))
2356
2387
        self.default_from_env = default_from_env
2357
 
        self._help = help
 
2388
        self.help = help
2358
2389
        self.from_unicode = from_unicode
2359
2390
        self.unquote = unquote
2360
2391
        if invalid and invalid not in ('warning', 'error'):
2361
2392
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2362
2393
        self.invalid = invalid
2363
2394
 
2364
 
    @property
2365
 
    def help(self):
2366
 
        return self._help
2367
 
 
2368
2395
    def convert_from_unicode(self, store, unicode_value):
2369
2396
        if self.unquote and store is not None and unicode_value is not None:
2370
2397
            unicode_value = store.unquote(unicode_value)
2411
2438
                value = self.default()
2412
2439
                if not isinstance(value, unicode):
2413
2440
                    raise AssertionError(
2414
 
                        "Callable default value for '%s' should be unicode"
2415
 
                        % (self.name))
 
2441
                    'Callable default values should be unicode')
2416
2442
            else:
2417
2443
                value = self.default
2418
2444
        return value
2471
2497
    return float(unicode_str)
2472
2498
 
2473
2499
 
2474
 
# Use an empty dict to initialize an empty configobj avoiding all parsing and
2475
 
# encoding checks
 
2500
# Use a an empty dict to initialize an empty configobj avoiding all
 
2501
# parsing and encoding checks
2476
2502
_list_converter_config = configobj.ConfigObj(
2477
2503
    {}, encoding='utf-8', list_values=True, interpolation=False)
2478
2504
 
2514
2540
        return l
2515
2541
 
2516
2542
 
2517
 
class RegistryOption(Option):
2518
 
    """Option for a choice from a registry."""
2519
 
 
2520
 
    def __init__(self, name, registry, default_from_env=None,
2521
 
                 help=None, invalid=None):
2522
 
        """A registry based Option definition.
2523
 
 
2524
 
        This overrides the base class so the conversion from a unicode string
2525
 
        can take quoting into account.
2526
 
        """
2527
 
        super(RegistryOption, self).__init__(
2528
 
            name, default=lambda: unicode(registry.default_key),
2529
 
            default_from_env=default_from_env,
2530
 
            from_unicode=self.from_unicode, help=help,
2531
 
            invalid=invalid, unquote=False)
2532
 
        self.registry = registry
2533
 
 
2534
 
    def from_unicode(self, unicode_str):
2535
 
        if not isinstance(unicode_str, basestring):
2536
 
            raise TypeError
2537
 
        try:
2538
 
            return self.registry.get(unicode_str)
2539
 
        except KeyError:
2540
 
            raise ValueError(
2541
 
                "Invalid value %s for %s."
2542
 
                "See help for a list of possible values." % (unicode_str,
2543
 
                    self.name))
2544
 
 
2545
 
    @property
2546
 
    def help(self):
2547
 
        ret = [self._help, "\n\nThe following values are supported:\n"]
2548
 
        for key in self.registry.keys():
2549
 
            ret.append(" %s - %s\n" % (key, self.registry.get_help(key)))
2550
 
        return "".join(ret)
2551
 
 
2552
 
 
2553
 
_option_ref_re = lazy_regex.lazy_compile('({[^\d\W](?:\.\w|-\w|\w)*})')
2554
 
"""Describes an expandable option reference.
2555
 
 
2556
 
We want to match the most embedded reference first.
2557
 
 
2558
 
I.e. for '{{foo}}' we will get '{foo}',
2559
 
for '{bar{baz}}' we will get '{baz}'
2560
 
"""
2561
 
 
2562
 
def iter_option_refs(string):
2563
 
    # Split isolate refs so every other chunk is a ref
2564
 
    is_ref = False
2565
 
    for chunk  in _option_ref_re.split(string):
2566
 
        yield is_ref, chunk
2567
 
        is_ref = not is_ref
2568
 
 
2569
 
 
2570
2543
class OptionRegistry(registry.Registry):
2571
2544
    """Register config options by their name.
2572
2545
 
2574
2547
    some information from the option object itself.
2575
2548
    """
2576
2549
 
2577
 
    def _check_option_name(self, option_name):
2578
 
        """Ensures an option name is valid.
2579
 
 
2580
 
        :param option_name: The name to validate.
2581
 
        """
2582
 
        if _option_ref_re.match('{%s}' % option_name) is None:
2583
 
            raise errors.IllegalOptionName(option_name)
2584
 
 
2585
2550
    def register(self, option):
2586
2551
        """Register a new option to its name.
2587
2552
 
2588
2553
        :param option: The option to register. Its name is used as the key.
2589
2554
        """
2590
 
        self._check_option_name(option.name)
2591
2555
        super(OptionRegistry, self).register(option.name, option,
2592
2556
                                             help=option.help)
2593
2557
 
2602
2566
        :param member_name: the member of the module to return.  If empty or 
2603
2567
                None, get() will return the module itself.
2604
2568
        """
2605
 
        self._check_option_name(key)
2606
2569
        super(OptionRegistry, self).register_lazy(key,
2607
2570
                                                  module_name, member_name)
2608
2571
 
2672
2635
           help="""\
2673
2636
Whether revisions associated with tags should be fetched.
2674
2637
"""))
2675
 
option_registry.register_lazy(
2676
 
    'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
2677
2638
option_registry.register(
2678
2639
    Option('bzr.workingtree.worth_saving_limit', default=10,
2679
2640
           from_unicode=int_from_store,  invalid='warning',
2687
2648
a file has been touched.
2688
2649
'''))
2689
2650
option_registry.register(
2690
 
    Option('bugtracker', default=None,
2691
 
           help='''\
2692
 
Default bug tracker to use.
2693
 
 
2694
 
This bug tracker will be used for example when marking bugs
2695
 
as fixed using ``bzr commit --fixes``, if no explicit
2696
 
bug tracker was specified.
2697
 
'''))
2698
 
option_registry.register(
2699
2651
    Option('check_signatures', default=CHECK_IF_POSSIBLE,
2700
2652
           from_unicode=signature_policy_from_unicode,
2701
2653
           help='''\
2803
2755
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2804
2756
may be provided by plugins.
2805
2757
'''))
2806
 
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
2807
 
    'opt_mail_client')
2808
2758
option_registry.register(
2809
2759
    Option('output_encoding',
2810
2760
           help= 'Unicode encoding for output'
2827
2777
 
2828
2778
Each function takes branch, rev_id as parameters.
2829
2779
'''))
2830
 
option_registry.register_lazy('progress_bar', 'bzrlib.ui.text',
2831
 
                              'opt_progress_bar')
2832
2780
option_registry.register(
2833
2781
    Option('public_branch',
2834
2782
           default=None,
2909
2857
option_registry.register(
2910
2858
    Option('submit_to',
2911
2859
           help='''Where submissions from this branch are mailed to.'''))
2912
 
option_registry.register(
2913
 
    ListOption('suppress_warnings',
2914
 
           default=[],
2915
 
           help="List of warning classes to suppress."))
2916
 
option_registry.register(
2917
 
    Option('validate_signatures_in_log', default=False,
2918
 
           from_unicode=bool_from_store, invalid='warning',
2919
 
           help='''Whether to validate signatures in bzr log.'''))
 
2860
 
2920
2861
option_registry.register_lazy('ssl.ca_certs',
2921
2862
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2922
2863
 
2924
2865
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2925
2866
 
2926
2867
 
 
2868
 
2927
2869
class Section(object):
2928
2870
    """A section defines a dict of option name => value.
2929
2871
 
2971
2913
        self.options[name] = value
2972
2914
 
2973
2915
    def remove(self, name):
2974
 
        if name not in self.orig and name in self.options:
 
2916
        if name not in self.orig:
2975
2917
            self.orig[name] = self.get(name, None)
2976
2918
        del self.options[name]
2977
2919
 
2999
2941
            # Report concurrent updates in an ad-hoc way. This should only
3000
2942
            # occurs when different processes try to update the same option
3001
2943
            # which is not supported (as in: the config framework is not meant
3002
 
            # to be used as a sharing mechanism).
 
2944
            # to be used a sharing mechanism).
3003
2945
            if expected != reloaded:
3004
2946
                if actual is _DeletedOption:
3005
2947
                    actual = '<DELETED>'
3025
2967
    mutable_section_class = MutableSection
3026
2968
 
3027
2969
    def __init__(self):
3028
 
        # Which sections need to be saved (by section id). We use a dict here
3029
 
        # so the dirty sections can be shared by multiple callers.
3030
 
        self.dirty_sections = {}
 
2970
        # Which sections need to be saved
 
2971
        self.dirty_sections = []
3031
2972
 
3032
2973
    def is_loaded(self):
3033
2974
        """Returns True if the Store has been loaded.
3076
3017
        raise NotImplementedError(self.save)
3077
3018
 
3078
3019
    def _need_saving(self):
3079
 
        for s in self.dirty_sections.values():
 
3020
        for s in self.dirty_sections:
3080
3021
            if s.orig:
3081
3022
                # At least one dirty section contains a modification
3082
3023
                return True
3096
3037
        # get_mutable_section() call below.
3097
3038
        self.unload()
3098
3039
        # Apply the changes from the preserved dirty sections
3099
 
        for section_id, dirty in dirty_sections.iteritems():
3100
 
            clean = self.get_mutable_section(section_id)
 
3040
        for dirty in dirty_sections:
 
3041
            clean = self.get_mutable_section(dirty.id)
3101
3042
            clean.apply_changes(dirty, self)
3102
3043
        # Everything is clean now
3103
 
        self.dirty_sections = {}
 
3044
        self.dirty_sections = []
3104
3045
 
3105
3046
    def save_changes(self):
3106
3047
        """Saves the Store to persistent storage if changes occurred.
3186
3127
 
3187
3128
    def unload(self):
3188
3129
        self._config_obj = None
3189
 
        self.dirty_sections = {}
 
3130
        self.dirty_sections = []
3190
3131
 
3191
3132
    def _load_content(self):
3192
3133
        """Load the config file bytes.
3240
3181
        if not self._need_saving():
3241
3182
            return
3242
3183
        # Preserve the current version
3243
 
        dirty_sections = dict(self.dirty_sections.items())
 
3184
        current = self._config_obj
 
3185
        dirty_sections = list(self.dirty_sections)
3244
3186
        self.apply_changes(dirty_sections)
3245
3187
        # Save to the persistent storage
3246
3188
        self.save()
3281
3223
        except errors.NoSuchFile:
3282
3224
            # The file doesn't exist, let's pretend it was empty
3283
3225
            self._load_from_string('')
3284
 
        if section_id in self.dirty_sections:
3285
 
            # We already created a mutable section for this id
3286
 
            return self.dirty_sections[section_id]
3287
3226
        if section_id is None:
3288
3227
            section = self._config_obj
3289
3228
        else:
3290
3229
            section = self._config_obj.setdefault(section_id, {})
3291
3230
        mutable_section = self.mutable_section_class(section_id, section)
3292
3231
        # All mutable sections can become dirty
3293
 
        self.dirty_sections[section_id] = mutable_section
 
3232
        self.dirty_sections.append(mutable_section)
3294
3233
        return mutable_section
3295
3234
 
3296
3235
    def quote(self, value):
3315
3254
        # anyway.
3316
3255
        return 'In-Process Store, no URL'
3317
3256
 
3318
 
 
3319
3257
class TransportIniFileStore(IniFileStore):
3320
3258
    """IniFileStore that loads files from a transport.
3321
3259
 
3411
3349
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3412
3350
# on a poolie's remark)
3413
3351
class GlobalStore(LockableIniFileStore):
3414
 
    """A config store for global options.
3415
 
 
3416
 
    There is a single GlobalStore for a given process.
3417
 
    """
3418
3352
 
3419
3353
    def __init__(self, possible_transports=None):
3420
3354
        t = transport.get_transport_from_path(
3424
3358
 
3425
3359
 
3426
3360
class LocationStore(LockableIniFileStore):
3427
 
    """A config store for options specific to a location.
3428
 
 
3429
 
    There is a single LocationStore for a given process.
3430
 
    """
3431
3361
 
3432
3362
    def __init__(self, possible_transports=None):
3433
3363
        t = transport.get_transport_from_path(
3437
3367
 
3438
3368
 
3439
3369
class BranchStore(TransportIniFileStore):
3440
 
    """A config store for branch options.
3441
 
 
3442
 
    There is a single BranchStore for a given branch.
3443
 
    """
3444
3370
 
3445
3371
    def __init__(self, branch):
3446
3372
        super(BranchStore, self).__init__(branch.control_transport,
3448
3374
        self.branch = branch
3449
3375
        self.id = 'branch'
3450
3376
 
 
3377
    def lock_write(self, token=None):
 
3378
        return self.branch.lock_write(token)
 
3379
 
 
3380
    def unlock(self):
 
3381
        return self.branch.unlock()
 
3382
 
 
3383
    @needs_write_lock
 
3384
    def save(self):
 
3385
        # We need to be able to override the undecorated implementation
 
3386
        self.save_without_locking()
 
3387
 
 
3388
    def save_without_locking(self):
 
3389
        super(BranchStore, self).save()
 
3390
 
3451
3391
 
3452
3392
class ControlStore(LockableIniFileStore):
3453
3393
 
3499
3439
 
3500
3440
class LocationSection(Section):
3501
3441
 
3502
 
    def __init__(self, section, extra_path, branch_name=None):
 
3442
    def __init__(self, section, extra_path):
3503
3443
        super(LocationSection, self).__init__(section.id, section.options)
3504
3444
        self.extra_path = extra_path
3505
 
        if branch_name is None:
3506
 
            branch_name = ''
3507
3445
        self.locals = {'relpath': extra_path,
3508
 
                       'basename': urlutils.basename(extra_path),
3509
 
                       'branchname': branch_name}
 
3446
                       'basename': urlutils.basename(extra_path)}
3510
3447
 
3511
3448
    def get(self, name, default=None, expand=True):
3512
3449
        value = super(LocationSection, self).get(name, default)
3559
3496
        """
3560
3497
        location_parts = self.location.rstrip('/').split('/')
3561
3498
        store = self.store
 
3499
        sections = []
3562
3500
        # Later sections are more specific, they should be returned first
3563
3501
        for _, section in reversed(list(store.get_sections())):
3564
3502
            if section.id is None:
3581
3519
 
3582
3520
    def __init__(self, store, location):
3583
3521
        super(LocationMatcher, self).__init__(store)
3584
 
        url, params = urlutils.split_segment_parameters(location)
3585
3522
        if location.startswith('file://'):
3586
3523
            location = urlutils.local_path_from_url(location)
3587
3524
        self.location = location
3588
 
        branch_name = params.get('branch')
3589
 
        if branch_name is None:
3590
 
            self.branch_name = urlutils.basename(self.location)
3591
 
        else:
3592
 
            self.branch_name = urlutils.unescape(branch_name)
3593
3525
 
3594
3526
    def _get_matching_sections(self):
3595
3527
        """Get all sections matching ``location``."""
3621
3553
            while True:
3622
3554
                section = iter_all_sections.next()
3623
3555
                if section_id == section.id:
3624
 
                    section = LocationSection(section, extra_path,
3625
 
                                              self.branch_name)
3626
 
                    matching_sections.append((length, section))
 
3556
                    matching_sections.append(
 
3557
                        (length, LocationSection(section, extra_path)))
3627
3558
                    break
3628
3559
        return matching_sections
3629
3560
 
3646
3577
            yield self.store, section
3647
3578
 
3648
3579
 
3649
 
# FIXME: _shared_stores should be an attribute of a library state once a
3650
 
# library_state object is always available.
3651
 
_shared_stores = {}
3652
 
_shared_stores_at_exit_installed = False
 
3580
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
 
3581
"""Describes an expandable option reference.
 
3582
 
 
3583
We want to match the most embedded reference first.
 
3584
 
 
3585
I.e. for '{{foo}}' we will get '{foo}',
 
3586
for '{bar{baz}}' we will get '{baz}'
 
3587
"""
 
3588
 
 
3589
def iter_option_refs(string):
 
3590
    # Split isolate refs so every other chunk is a ref
 
3591
    is_ref = False
 
3592
    for chunk  in _option_ref_re.split(string):
 
3593
        yield is_ref, chunk
 
3594
        is_ref = not is_ref
 
3595
 
3653
3596
 
3654
3597
class Stack(object):
3655
3598
    """A stack of configurations where an option can be defined"""
3672
3615
        self.store = store
3673
3616
        self.mutable_section_id = mutable_section_id
3674
3617
 
3675
 
    def iter_sections(self):
3676
 
        """Iterate all the defined sections."""
3677
 
        # Ensuring lazy loading is achieved by delaying section matching (which
3678
 
        # implies querying the persistent storage) until it can't be avoided
3679
 
        # anymore by using callables to describe (possibly empty) section
3680
 
        # lists.
3681
 
        for sections in self.sections_def:
3682
 
            for store, section in sections():
3683
 
                yield store, section
3684
 
 
3685
 
    def get(self, name, expand=True, convert=True):
 
3618
    def get(self, name, expand=None):
3686
3619
        """Return the *first* option value found in the sections.
3687
3620
 
3688
3621
        This is where we guarantee that sections coming from Store are loaded
3695
3628
 
3696
3629
        :param expand: Whether options references should be expanded.
3697
3630
 
3698
 
        :param convert: Whether the option value should be converted from
3699
 
            unicode (do nothing for non-registered options).
3700
 
 
3701
3631
        :returns: The value of the option.
3702
3632
        """
3703
3633
        # FIXME: No caching of options nor sections yet -- vila 20110503
 
3634
        if expand is None:
 
3635
            expand = _get_expand_default_value()
3704
3636
        value = None
3705
3637
        found_store = None # Where the option value has been found
3706
3638
        # If the option is registered, it may provide additional info about
3724
3656
                                      % (name, type(val)))
3725
3657
                if opt is None:
3726
3658
                    val = found_store.unquote(val)
3727
 
                elif convert:
 
3659
                else:
3728
3660
                    val = opt.convert_from_unicode(found_store, val)
3729
3661
            return val
3730
3662
 
3734
3666
            value = opt.get_override()
3735
3667
            value = expand_and_convert(value)
3736
3668
        if value is None:
3737
 
            for store, section in self.iter_sections():
3738
 
                value = section.get(name)
 
3669
            # Ensuring lazy loading is achieved by delaying section matching
 
3670
            # (which implies querying the persistent storage) until it can't be
 
3671
            # avoided anymore by using callables to describe (possibly empty)
 
3672
            # section lists.
 
3673
            for sections in self.sections_def:
 
3674
                for store, section in sections():
 
3675
                    value = section.get(name)
 
3676
                    if value is not None:
 
3677
                        found_store = store
 
3678
                        break
3739
3679
                if value is not None:
3740
 
                    found_store = store
3741
3680
                    break
3742
3681
            value = expand_and_convert(value)
3743
3682
            if opt is not None and value is None:
3809
3748
            # anything else
3810
3749
            value = env[name]
3811
3750
        else:
3812
 
            value = self.get(name, expand=False, convert=False)
 
3751
            value = self.get(name, expand=False)
3813
3752
            value = self._expand_options_in_string(value, env, _refs)
3814
3753
        return value
3815
3754
 
3844
3783
        return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3845
3784
 
3846
3785
    def _get_overrides(self):
3847
 
        # FIXME: Hack around library_state.initialize never called
 
3786
        # Hack around library_state.initialize never called
3848
3787
        if bzrlib.global_state is not None:
3849
3788
            return bzrlib.global_state.cmdline_overrides.get_sections()
3850
3789
        return []
3851
3790
 
3852
 
    def get_shared_store(self, store, state=None):
3853
 
        """Get a known shared store.
3854
 
 
3855
 
        Store urls uniquely identify them and are used to ensure a single copy
3856
 
        is shared across all users.
3857
 
 
3858
 
        :param store: The store known to the caller.
3859
 
 
3860
 
        :param state: The library state where the known stores are kept.
3861
 
 
3862
 
        :returns: The store received if it's not a known one, an already known
3863
 
            otherwise.
3864
 
        """
3865
 
        if state is None:
3866
 
            state = bzrlib.global_state
3867
 
        if state is None:
3868
 
            global _shared_stores_at_exit_installed
3869
 
            stores = _shared_stores
3870
 
            def save_config_changes():
3871
 
                for k, store in stores.iteritems():
3872
 
                    store.save_changes()
3873
 
            if not _shared_stores_at_exit_installed:
3874
 
                # FIXME: Ugly hack waiting for library_state to always be
3875
 
                # available. -- vila 20120731
3876
 
                import atexit
3877
 
                atexit.register(save_config_changes)
3878
 
                _shared_stores_at_exit_installed = True
3879
 
        else:
3880
 
            stores = state.config_stores
3881
 
        url = store.external_url()
3882
 
        try:
3883
 
            return stores[url]
3884
 
        except KeyError:
3885
 
            stores[url] = store
3886
 
            return store
3887
 
 
3888
3791
 
3889
3792
class MemoryStack(Stack):
3890
3793
    """A configuration stack defined from a string.
3940
3843
        self.store.save()
3941
3844
 
3942
3845
 
3943
 
class GlobalStack(Stack):
 
3846
class GlobalStack(_CompatibleStack):
3944
3847
    """Global options only stack.
3945
3848
 
3946
3849
    The following sections are queried:
3954
3857
    """
3955
3858
 
3956
3859
    def __init__(self):
3957
 
        gstore = self.get_shared_store(GlobalStore())
 
3860
        gstore = GlobalStore()
3958
3861
        super(GlobalStack, self).__init__(
3959
3862
            [self._get_overrides,
3960
3863
             NameMatcher(gstore, 'DEFAULT').get_sections],
3961
3864
            gstore, mutable_section_id='DEFAULT')
3962
3865
 
3963
3866
 
3964
 
class LocationStack(Stack):
 
3867
class LocationStack(_CompatibleStack):
3965
3868
    """Per-location options falling back to global options stack.
3966
3869
 
3967
3870
 
3983
3886
        """Make a new stack for a location and global configuration.
3984
3887
 
3985
3888
        :param location: A URL prefix to """
3986
 
        lstore = self.get_shared_store(LocationStore())
 
3889
        lstore = LocationStore()
3987
3890
        if location.startswith('file://'):
3988
3891
            location = urlutils.local_path_from_url(location)
3989
 
        gstore = self.get_shared_store(GlobalStore())
 
3892
        gstore = GlobalStore()
3990
3893
        super(LocationStack, self).__init__(
3991
3894
            [self._get_overrides,
3992
3895
             LocationMatcher(lstore, location).get_sections,
3994
3897
            lstore, mutable_section_id=location)
3995
3898
 
3996
3899
 
3997
 
class BranchStack(Stack):
 
3900
class BranchStack(_CompatibleStack):
3998
3901
    """Per-location options falling back to branch then global options stack.
3999
3902
 
4000
3903
    The following sections are queried:
4014
3917
    """
4015
3918
 
4016
3919
    def __init__(self, branch):
4017
 
        lstore = self.get_shared_store(LocationStore())
 
3920
        lstore = LocationStore()
4018
3921
        bstore = branch._get_config_store()
4019
 
        gstore = self.get_shared_store(GlobalStore())
 
3922
        gstore = GlobalStore()
4020
3923
        super(BranchStack, self).__init__(
4021
3924
            [self._get_overrides,
4022
3925
             LocationMatcher(lstore, branch.base).get_sections,
4025
3928
            bstore)
4026
3929
        self.branch = branch
4027
3930
 
4028
 
    def lock_write(self, token=None):
4029
 
        return self.branch.lock_write(token)
4030
 
 
4031
 
    def unlock(self):
4032
 
        return self.branch.unlock()
4033
 
 
4034
 
    @needs_write_lock
4035
 
    def set(self, name, value):
4036
 
        super(BranchStack, self).set(name, value)
4037
 
        # Unlocking the branch will trigger a store.save_changes() so the last
4038
 
        # unlock saves all the changes.
4039
 
 
4040
 
    @needs_write_lock
4041
 
    def remove(self, name):
4042
 
        super(BranchStack, self).remove(name)
4043
 
        # Unlocking the branch will trigger a store.save_changes() so the last
4044
 
        # unlock saves all the changes.
4045
 
 
4046
 
 
4047
 
class RemoteControlStack(Stack):
 
3931
 
 
3932
class RemoteControlStack(_CompatibleStack):
4048
3933
    """Remote control-only options stack."""
4049
3934
 
4050
3935
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
4059
3944
        self.bzrdir = bzrdir
4060
3945
 
4061
3946
 
4062
 
class BranchOnlyStack(Stack):
 
3947
class BranchOnlyStack(_CompatibleStack):
4063
3948
    """Branch-only options stack."""
4064
3949
 
4065
3950
    # FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
4073
3958
            bstore)
4074
3959
        self.branch = branch
4075
3960
 
4076
 
    def lock_write(self, token=None):
4077
 
        return self.branch.lock_write(token)
4078
 
 
4079
 
    def unlock(self):
4080
 
        return self.branch.unlock()
4081
 
 
4082
 
    @needs_write_lock
4083
 
    def set(self, name, value):
4084
 
        super(BranchOnlyStack, self).set(name, value)
4085
 
        # Force a write to persistent storage
4086
 
        self.store.save_changes()
4087
 
 
4088
 
    @needs_write_lock
4089
 
    def remove(self, name):
4090
 
        super(BranchOnlyStack, self).remove(name)
4091
 
        # Force a write to persistent storage
4092
 
        self.store.save_changes()
4093
 
 
 
3961
 
 
3962
# Use a an empty dict to initialize an empty configobj avoiding all
 
3963
# parsing and encoding checks
 
3964
_quoting_config = configobj.ConfigObj(
 
3965
    {}, encoding='utf-8', interpolation=False, list_values=True)
4094
3966
 
4095
3967
class cmd_config(commands.Command):
4096
3968
    __doc__ = """Display, set or remove a configuration option.
4097
3969
 
4098
 
    Display the active value for option NAME.
 
3970
    Display the active value for a given option.
4099
3971
 
4100
3972
    If --all is specified, NAME is interpreted as a regular expression and all
4101
 
    matching options are displayed mentioning their scope and without resolving
4102
 
    option references in the value). The active value that bzr will take into
4103
 
    account is the first one displayed for each option.
4104
 
 
4105
 
    If NAME is not given, --all .* is implied (all options are displayed for the
4106
 
    current scope).
4107
 
 
4108
 
    Setting a value is achieved by using NAME=value without spaces. The value
 
3973
    matching options are displayed mentioning their scope. The active value
 
3974
    that bzr will take into account is the first one displayed for each option.
 
3975
 
 
3976
    If no NAME is given, --all .* is implied.
 
3977
 
 
3978
    Setting a value is achieved by using name=value without spaces. The value
4109
3979
    is set in the most relevant scope and can be checked by displaying the
4110
3980
    option again.
4111
 
 
4112
 
    Removing a value is achieved by using --remove NAME.
4113
3981
    """
4114
3982
 
4115
3983
    takes_args = ['name?']
4163
4031
                # Set the option value
4164
4032
                self._set_config_option(name, value, directory, scope)
4165
4033
 
4166
 
    def _get_stack(self, directory, scope=None, write_access=False):
 
4034
    def _get_stack(self, directory, scope=None):
4167
4035
        """Get the configuration stack specified by ``directory`` and ``scope``.
4168
4036
 
4169
4037
        :param directory: Where the configurations are derived from.
4170
4038
 
4171
4039
        :param scope: A specific config to start from.
4172
 
 
4173
 
        :param write_access: Whether a write access to the stack will be
4174
 
            attempted.
4175
4040
        """
4176
4041
        # FIXME: scope should allow access to plugin-specific stacks (even
4177
4042
        # reduced to the plugin-specific store), related to
4185
4050
                (_, br, _) = (
4186
4051
                    controldir.ControlDir.open_containing_tree_or_branch(
4187
4052
                        directory))
4188
 
                if write_access:
4189
 
                    self.add_cleanup(br.lock_write().unlock)
4190
4053
                return br.get_config_stack()
4191
4054
            raise errors.NoSuchConfig(scope)
4192
4055
        else:
4194
4057
                (_, br, _) = (
4195
4058
                    controldir.ControlDir.open_containing_tree_or_branch(
4196
4059
                        directory))
4197
 
                if write_access:
4198
 
                    self.add_cleanup(br.lock_write().unlock)
4199
4060
                return br.get_config_stack()
4200
4061
            except errors.NotBranchError:
4201
4062
                return LocationStack(directory)
4202
4063
 
4203
 
    def _quote_multiline(self, value):
4204
 
        if '\n' in value:
4205
 
            value = '"""' + value + '"""'
4206
 
        return value
4207
 
 
4208
4064
    def _show_value(self, name, directory, scope):
4209
4065
        conf = self._get_stack(directory, scope)
4210
 
        value = conf.get(name, expand=True, convert=False)
 
4066
        value = conf.get(name, expand=True)
4211
4067
        if value is not None:
4212
4068
            # Quote the value appropriately
4213
 
            value = self._quote_multiline(value)
 
4069
            value = _quoting_config._quote(value)
4214
4070
            self.outf.write('%s\n' % (value,))
4215
4071
        else:
4216
4072
            raise errors.NoSuchConfigOption(name)
4224
4080
        cur_store_id = None
4225
4081
        cur_section = None
4226
4082
        conf = self._get_stack(directory, scope)
4227
 
        for store, section in conf.iter_sections():
4228
 
            for oname in section.iter_option_names():
4229
 
                if name.search(oname):
4230
 
                    if cur_store_id != store.id:
4231
 
                        # Explain where the options are defined
4232
 
                        self.outf.write('%s:\n' % (store.id,))
4233
 
                        cur_store_id = store.id
4234
 
                        cur_section = None
4235
 
                    if (section.id is not None and cur_section != section.id):
4236
 
                        # Display the section id as it appears in the store
4237
 
                        # (None doesn't appear by definition)
4238
 
                        self.outf.write('  [%s]\n' % (section.id,))
4239
 
                        cur_section = section.id
4240
 
                    value = section.get(oname, expand=False)
4241
 
                    # Quote the value appropriately
4242
 
                    value = self._quote_multiline(value)
4243
 
                    self.outf.write('  %s = %s\n' % (oname, value))
 
4083
        for sections in conf.sections_def:
 
4084
            for store, section in sections():
 
4085
                for oname in section.iter_option_names():
 
4086
                    if name.search(oname):
 
4087
                        if cur_store_id != store.id:
 
4088
                            # Explain where the options are defined
 
4089
                            self.outf.write('%s:\n' % (store.id,))
 
4090
                            cur_store_id = store.id
 
4091
                            cur_section = None
 
4092
                        if (section.id is not None
 
4093
                            and cur_section != section.id):
 
4094
                            # Display the section id as it appears in the store
 
4095
                            # (None doesn't appear by definition)
 
4096
                            self.outf.write('  [%s]\n' % (section.id,))
 
4097
                            cur_section = section.id
 
4098
                        value = section.get(oname, expand=False)
 
4099
                        # Since we don't use the stack, we need to restore a
 
4100
                        # proper quoting.
 
4101
                        try:
 
4102
                            opt = option_registry.get(oname)
 
4103
                            value = opt.convert_from_unicode(store, value)
 
4104
                        except KeyError:
 
4105
                            value = store.unquote(value)
 
4106
                        value = _quoting_config._quote(value)
 
4107
                        self.outf.write('  %s = %s\n' % (oname, value))
4244
4108
 
4245
4109
    def _set_config_option(self, name, value, directory, scope):
4246
 
        conf = self._get_stack(directory, scope, write_access=True)
 
4110
        conf = self._get_stack(directory, scope)
4247
4111
        conf.set(name, value)
4248
 
        # Explicitly save the changes
4249
 
        conf.store.save_changes()
4250
4112
 
4251
4113
    def _remove_config_option(self, name, directory, scope):
4252
4114
        if name is None:
4253
4115
            raise errors.BzrCommandError(
4254
4116
                '--remove expects an option to remove.')
4255
 
        conf = self._get_stack(directory, scope, write_access=True)
 
4117
        conf = self._get_stack(directory, scope)
4256
4118
        try:
4257
4119
            conf.remove(name)
4258
 
            # Explicitly save the changes
4259
 
            conf.store.save_changes()
4260
4120
        except KeyError:
4261
4121
            raise errors.NoSuchConfigOption(name)
4262
4122