1508
2243
configobj[name] = value
1510
2245
configobj.setdefault(section, {})[name] = value
2246
for hook in OldConfigHooks['set']:
2247
hook(self, name, value)
2248
self._set_configobj(configobj)
2250
def remove_option(self, option_name, section_name=None):
2251
configobj = self._get_configobj()
2252
if section_name is None:
2253
del configobj[option_name]
2255
del configobj[section_name][option_name]
2256
for hook in OldConfigHooks['remove']:
2257
hook(self, option_name)
1511
2258
self._set_configobj(configobj)
1513
2260
def _get_config_file(self):
1515
return StringIO(self._transport.get_bytes(self._filename))
2262
f = StringIO(self._transport.get_bytes(self._filename))
2263
for hook in OldConfigHooks['load']:
1516
2266
except errors.NoSuchFile:
1517
2267
return StringIO()
2268
except errors.PermissionDenied, e:
2269
trace.warning("Permission denied while trying to open "
2270
"configuration file %s.", urlutils.unescape_for_display(
2271
urlutils.join(self._transport.base, self._filename), "utf-8"))
2274
def _external_url(self):
2275
return urlutils.join(self._transport.external_url(), self._filename)
1519
2277
def _get_configobj(self):
1520
return ConfigObj(self._get_config_file(), encoding='utf-8')
2278
f = self._get_config_file()
2281
conf = ConfigObj(f, encoding='utf-8')
2282
except configobj.ConfigObjError, e:
2283
raise errors.ParseConfigError(e.errors, self._external_url())
2284
except UnicodeDecodeError:
2285
raise errors.ConfigContentError(self._external_url())
1522
2290
def _set_configobj(self, configobj):
1523
2291
out_file = StringIO()
1524
2292
configobj.write(out_file)
1525
2293
out_file.seek(0)
1526
2294
self._transport.put_file(self._filename, out_file)
2295
for hook in OldConfigHooks['save']:
2299
class Option(object):
2300
"""An option definition.
2302
The option *values* are stored in config files and found in sections.
2304
Here we define various properties about the option itself, its default
2305
value, how to convert it from stores, what to do when invalid values are
2306
encoutered, in which config files it can be stored.
2309
def __init__(self, name, override_from_env=None,
2310
default=None, default_from_env=None,
2311
help=None, from_unicode=None, invalid=None, unquote=True):
2312
"""Build an option definition.
2314
:param name: the name used to refer to the option.
2316
:param override_from_env: A list of environment variables which can
2317
provide override any configuration setting.
2319
:param default: the default value to use when none exist in the config
2320
stores. This is either a string that ``from_unicode`` will convert
2321
into the proper type, a callable returning a unicode string so that
2322
``from_unicode`` can be used on the return value, or a python
2323
object that can be stringified (so only the empty list is supported
2326
:param default_from_env: A list of environment variables which can
2327
provide a default value. 'default' will be used only if none of the
2328
variables specified here are set in the environment.
2330
:param help: a doc string to explain the option to the user.
2332
:param from_unicode: a callable to convert the unicode string
2333
representing the option value in a store. This is not called for
2336
:param invalid: the action to be taken when an invalid value is
2337
encountered in a store. This is called only when from_unicode is
2338
invoked to convert a string and returns None or raise ValueError or
2339
TypeError. Accepted values are: None (ignore invalid values),
2340
'warning' (emit a warning), 'error' (emit an error message and
2343
:param unquote: should the unicode value be unquoted before conversion.
2344
This should be used only when the store providing the values cannot
2345
safely unquote them (see http://pad.lv/906897). It is provided so
2346
daughter classes can handle the quoting themselves.
2348
if override_from_env is None:
2349
override_from_env = []
2350
if default_from_env is None:
2351
default_from_env = []
2353
self.override_from_env = override_from_env
2354
# Convert the default value to a unicode string so all values are
2355
# strings internally before conversion (via from_unicode) is attempted.
2358
elif isinstance(default, list):
2359
# Only the empty list is supported
2361
raise AssertionError(
2362
'Only empty lists are supported as default values')
2364
elif isinstance(default, (str, unicode, bool, int, float)):
2365
# Rely on python to convert strings, booleans and integers
2366
self.default = u'%s' % (default,)
2367
elif callable(default):
2368
self.default = default
2370
# other python objects are not expected
2371
raise AssertionError('%r is not supported as a default value'
2373
self.default_from_env = default_from_env
2375
self.from_unicode = from_unicode
2376
self.unquote = unquote
2377
if invalid and invalid not in ('warning', 'error'):
2378
raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2379
self.invalid = invalid
2385
def convert_from_unicode(self, store, unicode_value):
2386
if self.unquote and store is not None and unicode_value is not None:
2387
unicode_value = store.unquote(unicode_value)
2388
if self.from_unicode is None or unicode_value is None:
2389
# Don't convert or nothing to convert
2390
return unicode_value
2392
converted = self.from_unicode(unicode_value)
2393
except (ValueError, TypeError):
2394
# Invalid values are ignored
2396
if converted is None and self.invalid is not None:
2397
# The conversion failed
2398
if self.invalid == 'warning':
2399
trace.warning('Value "%s" is not valid for "%s"',
2400
unicode_value, self.name)
2401
elif self.invalid == 'error':
2402
raise errors.ConfigOptionValueError(self.name, unicode_value)
2405
def get_override(self):
2407
for var in self.override_from_env:
2409
# If the env variable is defined, its value takes precedence
2410
value = os.environ[var].decode(osutils.get_user_encoding())
2416
def get_default(self):
2418
for var in self.default_from_env:
2420
# If the env variable is defined, its value is the default one
2421
value = os.environ[var].decode(osutils.get_user_encoding())
2426
# Otherwise, fallback to the value defined at registration
2427
if callable(self.default):
2428
value = self.default()
2429
if not isinstance(value, unicode):
2430
raise AssertionError(
2431
'Callable default values should be unicode')
2433
value = self.default
2436
def get_help_text(self, additional_see_also=None, plain=True):
2438
from bzrlib import help_topics
2439
result += help_topics._format_see_also(additional_see_also)
2441
result = help_topics.help_as_plain_text(result)
2445
# Predefined converters to get proper values from store
2447
def bool_from_store(unicode_str):
2448
return ui.bool_from_string(unicode_str)
2451
def int_from_store(unicode_str):
2452
return int(unicode_str)
2455
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2457
def int_SI_from_store(unicode_str):
2458
"""Convert a human readable size in SI units, e.g 10MB into an integer.
2460
Accepted suffixes are K,M,G. It is case-insensitive and may be followed
2461
by a trailing b (i.e. Kb, MB). This is intended to be practical and not
2464
:return Integer, expanded to its base-10 value if a proper SI unit is
2465
found, None otherwise.
2467
regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
2468
p = re.compile(regexp, re.IGNORECASE)
2469
m = p.match(unicode_str)
2472
val, _, unit = m.groups()
2476
coeff = _unit_suffixes[unit.upper()]
2478
raise ValueError(gettext('{0} is not an SI unit.').format(unit))
2483
def float_from_store(unicode_str):
2484
return float(unicode_str)
2487
# Use a an empty dict to initialize an empty configobj avoiding all
2488
# parsing and encoding checks
2489
_list_converter_config = configobj.ConfigObj(
2490
{}, encoding='utf-8', list_values=True, interpolation=False)
2493
class ListOption(Option):
2495
def __init__(self, name, default=None, default_from_env=None,
2496
help=None, invalid=None):
2497
"""A list Option definition.
2499
This overrides the base class so the conversion from a unicode string
2500
can take quoting into account.
2502
super(ListOption, self).__init__(
2503
name, default=default, default_from_env=default_from_env,
2504
from_unicode=self.from_unicode, help=help,
2505
invalid=invalid, unquote=False)
2507
def from_unicode(self, unicode_str):
2508
if not isinstance(unicode_str, basestring):
2510
# Now inject our string directly as unicode. All callers got their
2511
# value from configobj, so values that need to be quoted are already
2513
_list_converter_config.reset()
2514
_list_converter_config._parse([u"list=%s" % (unicode_str,)])
2515
maybe_list = _list_converter_config['list']
2516
if isinstance(maybe_list, basestring):
2518
# A single value, most probably the user forgot (or didn't care
2519
# to add) the final ','
2522
# The empty string, convert to empty list
2525
# We rely on ConfigObj providing us with a list already
2530
class RegistryOption(Option):
2531
"""Option for a choice from a registry."""
2533
def __init__(self, name, registry, default_from_env=None,
2534
help=None, invalid=None):
2535
"""A registry based Option definition.
2537
This overrides the base class so the conversion from a unicode string
2538
can take quoting into account.
2540
super(RegistryOption, self).__init__(
2541
name, default=lambda: unicode(registry.default_key),
2542
default_from_env=default_from_env,
2543
from_unicode=self.from_unicode, help=help,
2544
invalid=invalid, unquote=False)
2545
self.registry = registry
2547
def from_unicode(self, unicode_str):
2548
if not isinstance(unicode_str, basestring):
2551
return self.registry.get(unicode_str)
2554
"Invalid value %s for %s."
2555
"See help for a list of possible values." % (unicode_str,
2560
ret = [self._help, "\n\nThe following values are supported:\n"]
2561
for key in self.registry.keys():
2562
ret.append(" %s - %s\n" % (key, self.registry.get_help(key)))
2566
class OptionRegistry(registry.Registry):
2567
"""Register config options by their name.
2569
This overrides ``registry.Registry`` to simplify registration by acquiring
2570
some information from the option object itself.
2573
def register(self, option):
2574
"""Register a new option to its name.
2576
:param option: The option to register. Its name is used as the key.
2578
super(OptionRegistry, self).register(option.name, option,
2581
def register_lazy(self, key, module_name, member_name):
2582
"""Register a new option to be loaded on request.
2584
:param key: the key to request the option later. Since the registration
2585
is lazy, it should be provided and match the option name.
2587
:param module_name: the python path to the module. Such as 'os.path'.
2589
:param member_name: the member of the module to return. If empty or
2590
None, get() will return the module itself.
2592
super(OptionRegistry, self).register_lazy(key,
2593
module_name, member_name)
2595
def get_help(self, key=None):
2596
"""Get the help text associated with the given key"""
2597
option = self.get(key)
2598
the_help = option.help
2599
if callable(the_help):
2600
return the_help(self, key)
2604
option_registry = OptionRegistry()
2607
# Registered options in lexicographical order
2609
option_registry.register(
2610
Option('append_revisions_only',
2611
default=None, from_unicode=bool_from_store, invalid='warning',
2613
Whether to only append revisions to the mainline.
2615
If this is set to true, then it is not possible to change the
2616
existing mainline of the branch.
2618
option_registry.register(
2619
ListOption('acceptable_keys',
2622
List of GPG key patterns which are acceptable for verification.
2624
option_registry.register(
2625
Option('add.maximum_file_size',
2626
default=u'20MB', from_unicode=int_SI_from_store,
2628
Size above which files should be added manually.
2630
Files below this size are added automatically when using ``bzr add`` without
2633
A negative value means disable the size check.
2635
option_registry.register(
2637
default=None, from_unicode=bool_from_store,
2639
Is the branch bound to ``bound_location``.
2641
If set to "True", the branch should act as a checkout, and push each commit to
2642
the bound_location. This option is normally set by ``bind``/``unbind``.
2644
See also: bound_location.
2646
option_registry.register(
2647
Option('bound_location',
2650
The location that commits should go to when acting as a checkout.
2652
This option is normally set by ``bind``.
2656
option_registry.register(
2657
Option('branch.fetch_tags', default=False, from_unicode=bool_from_store,
2659
Whether revisions associated with tags should be fetched.
2661
option_registry.register_lazy(
2662
'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
2663
option_registry.register(
2664
Option('bzr.workingtree.worth_saving_limit', default=10,
2665
from_unicode=int_from_store, invalid='warning',
2667
How many changes before saving the dirstate.
2669
-1 means that we will never rewrite the dirstate file for only
2670
stat-cache changes. Regardless of this setting, we will always rewrite
2671
the dirstate file if a file is added/removed/renamed/etc. This flag only
2672
affects the behavior of updating the dirstate file after we notice that
2673
a file has been touched.
2675
option_registry.register(
2676
Option('bugtracker', default=None,
2678
Default bug tracker to use.
2680
This bug tracker will be used for example when marking bugs
2681
as fixed using ``bzr commit --fixes``, if no explicit
2682
bug tracker was specified.
2684
option_registry.register(
2685
Option('check_signatures', default=CHECK_IF_POSSIBLE,
2686
from_unicode=signature_policy_from_unicode,
2688
GPG checking policy.
2690
Possible values: require, ignore, check-available (default)
2692
this option will control whether bzr will require good gpg
2693
signatures, ignore them, or check them if they are
2696
option_registry.register(
2697
Option('child_submit_format',
2698
help='''The preferred format of submissions to this branch.'''))
2699
option_registry.register(
2700
Option('child_submit_to',
2701
help='''Where submissions to this branch are mailed to.'''))
2702
option_registry.register(
2703
Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2704
from_unicode=signing_policy_from_unicode,
2708
Possible values: always, never, when-required (default)
2710
This option controls whether bzr will always create
2711
gpg signatures or not on commits.
2713
option_registry.register(
2714
Option('dirstate.fdatasync', default=True,
2715
from_unicode=bool_from_store,
2717
Flush dirstate changes onto physical disk?
2719
If true (default), working tree metadata changes are flushed through the
2720
OS buffers to physical disk. This is somewhat slower, but means data
2721
should not be lost if the machine crashes. See also repository.fdatasync.
2723
option_registry.register(
2724
ListOption('debug_flags', default=[],
2725
help='Debug flags to activate.'))
2726
option_registry.register(
2727
Option('default_format', default='2a',
2728
help='Format used when creating branches.'))
2729
option_registry.register(
2730
Option('dpush_strict', default=None,
2731
from_unicode=bool_from_store,
2733
The default value for ``dpush --strict``.
2735
If present, defines the ``--strict`` option default value for checking
2736
uncommitted changes before pushing into a different VCS without any
2737
custom bzr metadata.
2739
option_registry.register(
2741
help='The command called to launch an editor to enter a message.'))
2742
option_registry.register(
2743
Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2744
help='The users identity'))
2745
option_registry.register(
2746
Option('gpg_signing_command',
2749
Program to use use for creating signatures.
2751
This should support at least the -u and --clearsign options.
2753
option_registry.register(
2754
Option('gpg_signing_key',
2757
GPG key to use for signing.
2759
This defaults to the first key associated with the users email.
2761
option_registry.register(
2762
Option('ignore_missing_extensions', default=False,
2763
from_unicode=bool_from_store,
2765
Control the missing extensions warning display.
2767
The warning will not be emitted if set to True.
2769
option_registry.register(
2771
help='Language to translate messages into.'))
2772
option_registry.register(
2773
Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2775
Steal locks that appears to be dead.
2777
If set to True, bzr will check if a lock is supposed to be held by an
2778
active process from the same user on the same machine. If the user and
2779
machine match, but no process with the given PID is active, then bzr
2780
will automatically break the stale lock, and create a new lock for
2782
Otherwise, bzr will prompt as normal to break the lock.
2784
option_registry.register(
2785
Option('log_format', default='long',
2787
Log format to use when displaying revisions.
2789
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2790
may be provided by plugins.
2792
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
2794
option_registry.register(
2795
Option('output_encoding',
2796
help= 'Unicode encoding for output'
2797
' (terminal encoding if not specified).'))
2798
option_registry.register(
2799
Option('parent_location',
2802
The location of the default branch for pull or merge.
2804
This option is normally set when creating a branch, the first ``pull`` or by
2805
``pull --remember``.
2807
option_registry.register(
2808
Option('post_commit', default=None,
2810
Post commit functions.
2812
An ordered list of python functions to call, separated by spaces.
2814
Each function takes branch, rev_id as parameters.
2816
option_registry.register(
2817
Option('public_branch',
2820
A publically-accessible version of this branch.
2822
This implies that the branch setting this option is not publically-accessible.
2823
Used and set by ``bzr send``.
2825
option_registry.register(
2826
Option('push_location',
2829
The location of the default branch for push.
2831
This option is normally set by the first ``push`` or ``push --remember``.
2833
option_registry.register(
2834
Option('push_strict', default=None,
2835
from_unicode=bool_from_store,
2837
The default value for ``push --strict``.
2839
If present, defines the ``--strict`` option default value for checking
2840
uncommitted changes before sending a merge directive.
2842
option_registry.register(
2843
Option('repository.fdatasync', default=True,
2844
from_unicode=bool_from_store,
2846
Flush repository changes onto physical disk?
2848
If true (default), repository changes are flushed through the OS buffers
2849
to physical disk. This is somewhat slower, but means data should not be
2850
lost if the machine crashes. See also dirstate.fdatasync.
2852
option_registry.register_lazy('smtp_server',
2853
'bzrlib.smtp_connection', 'smtp_server')
2854
option_registry.register_lazy('smtp_password',
2855
'bzrlib.smtp_connection', 'smtp_password')
2856
option_registry.register_lazy('smtp_username',
2857
'bzrlib.smtp_connection', 'smtp_username')
2858
option_registry.register(
2859
Option('selftest.timeout',
2861
from_unicode=int_from_store,
2862
help='Abort selftest if one test takes longer than this many seconds',
2865
option_registry.register(
2866
Option('send_strict', default=None,
2867
from_unicode=bool_from_store,
2869
The default value for ``send --strict``.
2871
If present, defines the ``--strict`` option default value for checking
2872
uncommitted changes before sending a bundle.
2875
option_registry.register(
2876
Option('serve.client_timeout',
2877
default=300.0, from_unicode=float_from_store,
2878
help="If we wait for a new request from a client for more than"
2879
" X seconds, consider the client idle, and hangup."))
2880
option_registry.register(
2881
Option('stacked_on_location',
2883
help="""The location where this branch is stacked on."""))
2884
option_registry.register(
2885
Option('submit_branch',
2888
The branch you intend to submit your current work to.
2890
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2891
by the ``submit:`` revision spec.
2893
option_registry.register(
2895
help='''Where submissions from this branch are mailed to.'''))
2896
option_registry.register(
2897
ListOption('suppress_warnings',
2899
help="List of warning classes to suppress."))
2900
option_registry.register(
2901
Option('validate_signatures_in_log', default=False,
2902
from_unicode=bool_from_store, invalid='warning',
2903
help='''Whether to validate signatures in bzr log.'''))
2904
option_registry.register_lazy('ssl.ca_certs',
2905
'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2907
option_registry.register_lazy('ssl.cert_reqs',
2908
'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2911
class Section(object):
2912
"""A section defines a dict of option name => value.
2914
This is merely a read-only dict which can add some knowledge about the
2915
options. It is *not* a python dict object though and doesn't try to mimic
2919
def __init__(self, section_id, options):
2920
self.id = section_id
2921
# We re-use the dict-like object received
2922
self.options = options
2924
def get(self, name, default=None, expand=True):
2925
return self.options.get(name, default)
2927
def iter_option_names(self):
2928
for k in self.options.iterkeys():
2932
# Mostly for debugging use
2933
return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2936
_NewlyCreatedOption = object()
2937
"""Was the option created during the MutableSection lifetime"""
2938
_DeletedOption = object()
2939
"""Was the option deleted during the MutableSection lifetime"""
2942
class MutableSection(Section):
2943
"""A section allowing changes and keeping track of the original values."""
2945
def __init__(self, section_id, options):
2946
super(MutableSection, self).__init__(section_id, options)
2947
self.reset_changes()
2949
def set(self, name, value):
2950
if name not in self.options:
2951
# This is a new option
2952
self.orig[name] = _NewlyCreatedOption
2953
elif name not in self.orig:
2954
self.orig[name] = self.get(name, None)
2955
self.options[name] = value
2957
def remove(self, name):
2958
if name not in self.orig:
2959
self.orig[name] = self.get(name, None)
2960
del self.options[name]
2962
def reset_changes(self):
2965
def apply_changes(self, dirty, store):
2966
"""Apply option value changes.
2968
``self`` has been reloaded from the persistent storage. ``dirty``
2969
contains the changes made since the previous loading.
2971
:param dirty: the mutable section containing the changes.
2973
:param store: the store containing the section
2975
for k, expected in dirty.orig.iteritems():
2976
actual = dirty.get(k, _DeletedOption)
2977
reloaded = self.get(k, _NewlyCreatedOption)
2978
if actual is _DeletedOption:
2979
if k in self.options:
2983
# Report concurrent updates in an ad-hoc way. This should only
2984
# occurs when different processes try to update the same option
2985
# which is not supported (as in: the config framework is not meant
2986
# to be used a sharing mechanism).
2987
if expected != reloaded:
2988
if actual is _DeletedOption:
2989
actual = '<DELETED>'
2990
if reloaded is _NewlyCreatedOption:
2991
reloaded = '<CREATED>'
2992
if expected is _NewlyCreatedOption:
2993
expected = '<CREATED>'
2994
# Someone changed the value since we get it from the persistent
2996
trace.warning(gettext(
2997
"Option {0} in section {1} of {2} was changed"
2998
" from {3} to {4}. The {5} value will be saved.".format(
2999
k, self.id, store.external_url(), expected,
3001
# No need to keep track of these changes
3002
self.reset_changes()
3005
class Store(object):
3006
"""Abstract interface to persistent storage for configuration options."""
3008
readonly_section_class = Section
3009
mutable_section_class = MutableSection
3012
# Which sections need to be saved
3013
self.dirty_sections = []
3015
def is_loaded(self):
3016
"""Returns True if the Store has been loaded.
3018
This is used to implement lazy loading and ensure the persistent
3019
storage is queried only when needed.
3021
raise NotImplementedError(self.is_loaded)
3024
"""Loads the Store from persistent storage."""
3025
raise NotImplementedError(self.load)
3027
def _load_from_string(self, bytes):
3028
"""Create a store from a string in configobj syntax.
3030
:param bytes: A string representing the file content.
3032
raise NotImplementedError(self._load_from_string)
3035
"""Unloads the Store.
3037
This should make is_loaded() return False. This is used when the caller
3038
knows that the persistent storage has changed or may have change since
3041
raise NotImplementedError(self.unload)
3043
def quote(self, value):
3044
"""Quote a configuration option value for storing purposes.
3046
This allows Stacks to present values as they will be stored.
3050
def unquote(self, value):
3051
"""Unquote a configuration option value into unicode.
3053
The received value is quoted as stored.
3058
"""Saves the Store to persistent storage."""
3059
raise NotImplementedError(self.save)
3061
def _need_saving(self):
3062
for s in self.dirty_sections:
3064
# At least one dirty section contains a modification
3068
def apply_changes(self, dirty_sections):
3069
"""Apply changes from dirty sections while checking for coherency.
3071
The Store content is discarded and reloaded from persistent storage to
3072
acquire up-to-date values.
3074
Dirty sections are MutableSection which kept track of the value they
3075
are expected to update.
3077
# We need an up-to-date version from the persistent storage, unload the
3078
# store. The reload will occur when needed (triggered by the first
3079
# get_mutable_section() call below.
3081
# Apply the changes from the preserved dirty sections
3082
for dirty in dirty_sections:
3083
clean = self.get_mutable_section(dirty.id)
3084
clean.apply_changes(dirty, self)
3085
# Everything is clean now
3086
self.dirty_sections = []
3088
def save_changes(self):
3089
"""Saves the Store to persistent storage if changes occurred.
3091
Apply the changes recorded in the mutable sections to a store content
3092
refreshed from persistent storage.
3094
raise NotImplementedError(self.save_changes)
3096
def external_url(self):
3097
raise NotImplementedError(self.external_url)
3099
def get_sections(self):
3100
"""Returns an ordered iterable of existing sections.
3102
:returns: An iterable of (store, section).
3104
raise NotImplementedError(self.get_sections)
3106
def get_mutable_section(self, section_id=None):
3107
"""Returns the specified mutable section.
3109
:param section_id: The section identifier
3111
raise NotImplementedError(self.get_mutable_section)
3114
# Mostly for debugging use
3115
return "<config.%s(%s)>" % (self.__class__.__name__,
3116
self.external_url())
3119
class CommandLineStore(Store):
3120
"A store to carry command line overrides for the config options."""
3122
def __init__(self, opts=None):
3123
super(CommandLineStore, self).__init__()
3130
# The dict should be cleared but not replaced so it can be shared.
3131
self.options.clear()
3133
def _from_cmdline(self, overrides):
3134
# Reset before accepting new definitions
3136
for over in overrides:
3138
name, value = over.split('=', 1)
3140
raise errors.BzrCommandError(
3141
gettext("Invalid '%s', should be of the form 'name=value'")
3143
self.options[name] = value
3145
def external_url(self):
3146
# Not an url but it makes debugging easier and is never needed
3150
def get_sections(self):
3151
yield self, self.readonly_section_class(None, self.options)
3154
class IniFileStore(Store):
3155
"""A config Store using ConfigObj for storage.
3157
:ivar _config_obj: Private member to hold the ConfigObj instance used to
3158
serialize/deserialize the config file.
3162
"""A config Store using ConfigObj for storage.
3164
super(IniFileStore, self).__init__()
3165
self._config_obj = None
3167
def is_loaded(self):
3168
return self._config_obj != None
3171
self._config_obj = None
3172
self.dirty_sections = []
3174
def _load_content(self):
3175
"""Load the config file bytes.
3177
This should be provided by subclasses
3179
:return: Byte string
3181
raise NotImplementedError(self._load_content)
3183
def _save_content(self, content):
3184
"""Save the config file bytes.
3186
This should be provided by subclasses
3188
:param content: Config file bytes to write
3190
raise NotImplementedError(self._save_content)
3193
"""Load the store from the associated file."""
3194
if self.is_loaded():
3196
content = self._load_content()
3197
self._load_from_string(content)
3198
for hook in ConfigHooks['load']:
3201
def _load_from_string(self, bytes):
3202
"""Create a config store from a string.
3204
:param bytes: A string representing the file content.
3206
if self.is_loaded():
3207
raise AssertionError('Already loaded: %r' % (self._config_obj,))
3208
co_input = StringIO(bytes)
3210
# The config files are always stored utf8-encoded
3211
self._config_obj = ConfigObj(co_input, encoding='utf-8',
3213
except configobj.ConfigObjError, e:
3214
self._config_obj = None
3215
raise errors.ParseConfigError(e.errors, self.external_url())
3216
except UnicodeDecodeError:
3217
raise errors.ConfigContentError(self.external_url())
3219
def save_changes(self):
3220
if not self.is_loaded():
3223
if not self._need_saving():
3225
# Preserve the current version
3226
current = self._config_obj
3227
dirty_sections = list(self.dirty_sections)
3228
self.apply_changes(dirty_sections)
3229
# Save to the persistent storage
3233
if not self.is_loaded():
3237
self._config_obj.write(out)
3238
self._save_content(out.getvalue())
3239
for hook in ConfigHooks['save']:
3242
def get_sections(self):
3243
"""Get the configobj section in the file order.
3245
:returns: An iterable of (store, section).
3247
# We need a loaded store
3250
except (errors.NoSuchFile, errors.PermissionDenied):
3251
# If the file can't be read, there is no sections
3253
cobj = self._config_obj
3255
yield self, self.readonly_section_class(None, cobj)
3256
for section_name in cobj.sections:
3258
self.readonly_section_class(section_name,
3259
cobj[section_name]))
3261
def get_mutable_section(self, section_id=None):
3262
# We need a loaded store
3265
except errors.NoSuchFile:
3266
# The file doesn't exist, let's pretend it was empty
3267
self._load_from_string('')
3268
if section_id is None:
3269
section = self._config_obj
3271
section = self._config_obj.setdefault(section_id, {})
3272
mutable_section = self.mutable_section_class(section_id, section)
3273
# All mutable sections can become dirty
3274
self.dirty_sections.append(mutable_section)
3275
return mutable_section
3277
def quote(self, value):
3279
# configobj conflates automagical list values and quoting
3280
self._config_obj.list_values = True
3281
return self._config_obj._quote(value)
3283
self._config_obj.list_values = False
3285
def unquote(self, value):
3286
if value and isinstance(value, basestring):
3287
# _unquote doesn't handle None nor empty strings nor anything that
3288
# is not a string, really.
3289
value = self._config_obj._unquote(value)
3292
def external_url(self):
3293
# Since an IniFileStore can be used without a file (at least in tests),
3294
# it's better to provide something than raising a NotImplementedError.
3295
# All daughter classes are supposed to provide an implementation
3297
return 'In-Process Store, no URL'
3299
class TransportIniFileStore(IniFileStore):
3300
"""IniFileStore that loads files from a transport.
3302
:ivar transport: The transport object where the config file is located.
3304
:ivar file_name: The config file basename in the transport directory.
3307
def __init__(self, transport, file_name):
3308
"""A Store using a ini file on a Transport
3310
:param transport: The transport object where the config file is located.
3311
:param file_name: The config file basename in the transport directory.
3313
super(TransportIniFileStore, self).__init__()
3314
self.transport = transport
3315
self.file_name = file_name
3317
def _load_content(self):
3319
return self.transport.get_bytes(self.file_name)
3320
except errors.PermissionDenied:
3321
trace.warning("Permission denied while trying to load "
3322
"configuration store %s.", self.external_url())
3325
def _save_content(self, content):
3326
self.transport.put_bytes(self.file_name, content)
3328
def external_url(self):
3329
# FIXME: external_url should really accepts an optional relpath
3330
# parameter (bug #750169) :-/ -- vila 2011-04-04
3331
# The following will do in the interim but maybe we don't want to
3332
# expose a path here but rather a config ID and its associated
3333
# object </hand wawe>.
3334
return urlutils.join(self.transport.external_url(), self.file_name)
3337
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
3338
# unlockable stores for use with objects that can already ensure the locking
3339
# (think branches). If different stores (not based on ConfigObj) are created,
3340
# they may face the same issue.
3343
class LockableIniFileStore(TransportIniFileStore):
3344
"""A ConfigObjStore using locks on save to ensure store integrity."""
3346
def __init__(self, transport, file_name, lock_dir_name=None):
3347
"""A config Store using ConfigObj for storage.
3349
:param transport: The transport object where the config file is located.
3351
:param file_name: The config file basename in the transport directory.
3353
if lock_dir_name is None:
3354
lock_dir_name = 'lock'
3355
self.lock_dir_name = lock_dir_name
3356
super(LockableIniFileStore, self).__init__(transport, file_name)
3357
self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
3359
def lock_write(self, token=None):
3360
"""Takes a write lock in the directory containing the config file.
3362
If the directory doesn't exist it is created.
3364
# FIXME: This doesn't check the ownership of the created directories as
3365
# ensure_config_dir_exists does. It should if the transport is local
3366
# -- vila 2011-04-06
3367
self.transport.create_prefix()
3368
return self._lock.lock_write(token)
3373
def break_lock(self):
3374
self._lock.break_lock()
3378
# We need to be able to override the undecorated implementation
3379
self.save_without_locking()
3381
def save_without_locking(self):
3382
super(LockableIniFileStore, self).save()
3385
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
3386
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
3387
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
3389
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
3390
# functions or a registry will make it easier and clearer for tests, focusing
3391
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3392
# on a poolie's remark)
3393
class GlobalStore(LockableIniFileStore):
3395
def __init__(self, possible_transports=None):
3396
t = transport.get_transport_from_path(
3397
config_dir(), possible_transports=possible_transports)
3398
super(GlobalStore, self).__init__(t, 'bazaar.conf')
3402
class LocationStore(LockableIniFileStore):
3404
def __init__(self, possible_transports=None):
3405
t = transport.get_transport_from_path(
3406
config_dir(), possible_transports=possible_transports)
3407
super(LocationStore, self).__init__(t, 'locations.conf')
3408
self.id = 'locations'
3411
class BranchStore(TransportIniFileStore):
3413
def __init__(self, branch):
3414
super(BranchStore, self).__init__(branch.control_transport,
3416
self.branch = branch
3419
def lock_write(self, token=None):
3420
return self.branch.lock_write(token)
3423
return self.branch.unlock()
3427
# We need to be able to override the undecorated implementation
3428
self.save_without_locking()
3430
def save_without_locking(self):
3431
super(BranchStore, self).save()
3434
class ControlStore(LockableIniFileStore):
3436
def __init__(self, bzrdir):
3437
super(ControlStore, self).__init__(bzrdir.transport,
3439
lock_dir_name='branch_lock')
3443
class SectionMatcher(object):
3444
"""Select sections into a given Store.
3446
This is intended to be used to postpone getting an iterable of sections
3450
def __init__(self, store):
3453
def get_sections(self):
3454
# This is where we require loading the store so we can see all defined
3456
sections = self.store.get_sections()
3457
# Walk the revisions in the order provided
3458
for store, s in sections:
3462
def match(self, section):
3463
"""Does the proposed section match.
3465
:param section: A Section object.
3467
:returns: True if the section matches, False otherwise.
3469
raise NotImplementedError(self.match)
3472
class NameMatcher(SectionMatcher):
3474
def __init__(self, store, section_id):
3475
super(NameMatcher, self).__init__(store)
3476
self.section_id = section_id
3478
def match(self, section):
3479
return section.id == self.section_id
3482
class LocationSection(Section):
3484
def __init__(self, section, extra_path):
3485
super(LocationSection, self).__init__(section.id, section.options)
3486
self.extra_path = extra_path
3487
self.locals = {'relpath': extra_path,
3488
'basename': urlutils.basename(extra_path)}
3490
def get(self, name, default=None, expand=True):
3491
value = super(LocationSection, self).get(name, default)
3492
if value is not None and expand:
3493
policy_name = self.get(name + ':policy', None)
3494
policy = _policy_value.get(policy_name, POLICY_NONE)
3495
if policy == POLICY_APPENDPATH:
3496
value = urlutils.join(value, self.extra_path)
3497
# expand section local options right now (since POLICY_APPENDPATH
3498
# will never add options references, it's ok to expand after it).
3500
for is_ref, chunk in iter_option_refs(value):
3502
chunks.append(chunk)
3505
if ref in self.locals:
3506
chunks.append(self.locals[ref])
3508
chunks.append(chunk)
3509
value = ''.join(chunks)
3513
class StartingPathMatcher(SectionMatcher):
3514
"""Select sections for a given location respecting the Store order."""
3516
# FIXME: Both local paths and urls can be used for section names as well as
3517
# ``location`` to stay consistent with ``LocationMatcher`` which itself
3518
# inherited the fuzziness from the previous ``LocationConfig``
3519
# implementation. We probably need to revisit which encoding is allowed for
3520
# both ``location`` and section names and how we normalize
3521
# them. http://pad.lv/85479, http://pad.lv/437009 and http://359320 are
3522
# related too. -- vila 2012-01-04
3524
def __init__(self, store, location):
3525
super(StartingPathMatcher, self).__init__(store)
3526
if location.startswith('file://'):
3527
location = urlutils.local_path_from_url(location)
3528
self.location = location
3530
def get_sections(self):
3531
"""Get all sections matching ``location`` in the store.
3533
The most generic sections are described first in the store, then more
3534
specific ones can be provided for reduced scopes.
3536
The returned section are therefore returned in the reversed order so
3537
the most specific ones can be found first.
3539
location_parts = self.location.rstrip('/').split('/')
3542
# Later sections are more specific, they should be returned first
3543
for _, section in reversed(list(store.get_sections())):
3544
if section.id is None:
3545
# The no-name section is always included if present
3546
yield store, LocationSection(section, self.location)
3548
section_path = section.id
3549
if section_path.startswith('file://'):
3550
# the location is already a local path or URL, convert the
3551
# section id to the same format
3552
section_path = urlutils.local_path_from_url(section_path)
3553
if (self.location.startswith(section_path)
3554
or fnmatch.fnmatch(self.location, section_path)):
3555
section_parts = section_path.rstrip('/').split('/')
3556
extra_path = '/'.join(location_parts[len(section_parts):])
3557
yield store, LocationSection(section, extra_path)
3560
class LocationMatcher(SectionMatcher):
3562
def __init__(self, store, location):
3563
super(LocationMatcher, self).__init__(store)
3564
if location.startswith('file://'):
3565
location = urlutils.local_path_from_url(location)
3566
self.location = location
3568
def _get_matching_sections(self):
3569
"""Get all sections matching ``location``."""
3570
# We slightly diverge from LocalConfig here by allowing the no-name
3571
# section as the most generic one and the lower priority.
3572
no_name_section = None
3574
# Filter out the no_name_section so _iter_for_location_by_parts can be
3575
# used (it assumes all sections have a name).
3576
for _, section in self.store.get_sections():
3577
if section.id is None:
3578
no_name_section = section
3580
all_sections.append(section)
3581
# Unfortunately _iter_for_location_by_parts deals with section names so
3582
# we have to resync.
3583
filtered_sections = _iter_for_location_by_parts(
3584
[s.id for s in all_sections], self.location)
3585
iter_all_sections = iter(all_sections)
3586
matching_sections = []
3587
if no_name_section is not None:
3588
matching_sections.append(
3589
(0, LocationSection(no_name_section, self.location)))
3590
for section_id, extra_path, length in filtered_sections:
3591
# a section id is unique for a given store so it's safe to take the
3592
# first matching section while iterating. Also, all filtered
3593
# sections are part of 'all_sections' and will always be found
3596
section = iter_all_sections.next()
3597
if section_id == section.id:
3598
matching_sections.append(
3599
(length, LocationSection(section, extra_path)))
3601
return matching_sections
3603
def get_sections(self):
3604
# Override the default implementation as we want to change the order
3605
matching_sections = self._get_matching_sections()
3606
# We want the longest (aka more specific) locations first
3607
sections = sorted(matching_sections,
3608
key=lambda (length, section): (length, section.id),
3610
# Sections mentioning 'ignore_parents' restrict the selection
3611
for _, section in sections:
3612
# FIXME: We really want to use as_bool below -- vila 2011-04-07
3613
ignore = section.get('ignore_parents', None)
3614
if ignore is not None:
3615
ignore = ui.bool_from_string(ignore)
3618
# Finally, we have a valid section
3619
yield self.store, section
3622
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
3623
"""Describes an expandable option reference.
3625
We want to match the most embedded reference first.
3627
I.e. for '{{foo}}' we will get '{foo}',
3628
for '{bar{baz}}' we will get '{baz}'
3631
def iter_option_refs(string):
3632
# Split isolate refs so every other chunk is a ref
3634
for chunk in _option_ref_re.split(string):
3639
class Stack(object):
3640
"""A stack of configurations where an option can be defined"""
3642
def __init__(self, sections_def, store=None, mutable_section_id=None):
3643
"""Creates a stack of sections with an optional store for changes.
3645
:param sections_def: A list of Section or callables that returns an
3646
iterable of Section. This defines the Sections for the Stack and
3647
can be called repeatedly if needed.
3649
:param store: The optional Store where modifications will be
3650
recorded. If none is specified, no modifications can be done.
3652
:param mutable_section_id: The id of the MutableSection where changes
3653
are recorded. This requires the ``store`` parameter to be
3656
self.sections_def = sections_def
3658
self.mutable_section_id = mutable_section_id
3660
def get(self, name, expand=None):
3661
"""Return the *first* option value found in the sections.
3663
This is where we guarantee that sections coming from Store are loaded
3664
lazily: the loading is delayed until we need to either check that an
3665
option exists or get its value, which in turn may require to discover
3666
in which sections it can be defined. Both of these (section and option
3667
existence) require loading the store (even partially).
3669
:param name: The queried option.
3671
:param expand: Whether options references should be expanded.
3673
:returns: The value of the option.
3675
# FIXME: No caching of options nor sections yet -- vila 20110503
3677
expand = _get_expand_default_value()
3679
found_store = None # Where the option value has been found
3680
# If the option is registered, it may provide additional info about
3683
opt = option_registry.get(name)
3688
def expand_and_convert(val):
3689
# This may need to be called in different contexts if the value is
3690
# None or ends up being None during expansion or conversion.
3693
if isinstance(val, basestring):
3694
val = self._expand_options_in_string(val)
3696
trace.warning('Cannot expand "%s":'
3697
' %s does not support option expansion'
3698
% (name, type(val)))
3700
val = found_store.unquote(val)
3702
val = opt.convert_from_unicode(found_store, val)
3705
# First of all, check if the environment can override the configuration
3707
if opt is not None and opt.override_from_env:
3708
value = opt.get_override()
3709
value = expand_and_convert(value)
3711
# Ensuring lazy loading is achieved by delaying section matching
3712
# (which implies querying the persistent storage) until it can't be
3713
# avoided anymore by using callables to describe (possibly empty)
3715
for sections in self.sections_def:
3716
for store, section in sections():
3717
value = section.get(name)
3718
if value is not None:
3721
if value is not None:
3723
value = expand_and_convert(value)
3724
if opt is not None and value is None:
3725
# If the option is registered, it may provide a default value
3726
value = opt.get_default()
3727
value = expand_and_convert(value)
3728
for hook in ConfigHooks['get']:
3729
hook(self, name, value)
3732
def expand_options(self, string, env=None):
3733
"""Expand option references in the string in the configuration context.
3735
:param string: The string containing option(s) to expand.
3737
:param env: An option dict defining additional configuration options or
3738
overriding existing ones.
3740
:returns: The expanded string.
3742
return self._expand_options_in_string(string, env)
3744
def _expand_options_in_string(self, string, env=None, _refs=None):
3745
"""Expand options in the string in the configuration context.
3747
:param string: The string to be expanded.
3749
:param env: An option dict defining additional configuration options or
3750
overriding existing ones.
3752
:param _refs: Private list (FIFO) containing the options being expanded
3755
:returns: The expanded string.
3758
# Not much to expand there
3761
# What references are currently resolved (to detect loops)
3764
# We need to iterate until no more refs appear ({{foo}} will need two
3765
# iterations for example).
3770
for is_ref, chunk in iter_option_refs(result):
3772
chunks.append(chunk)
3777
raise errors.OptionExpansionLoop(string, _refs)
3779
value = self._expand_option(name, env, _refs)
3781
raise errors.ExpandingUnknownOption(name, string)
3782
chunks.append(value)
3784
result = ''.join(chunks)
3787
def _expand_option(self, name, env, _refs):
3788
if env is not None and name in env:
3789
# Special case, values provided in env takes precedence over
3793
value = self.get(name, expand=False)
3794
value = self._expand_options_in_string(value, env, _refs)
3797
def _get_mutable_section(self):
3798
"""Get the MutableSection for the Stack.
3800
This is where we guarantee that the mutable section is lazily loaded:
3801
this means we won't load the corresponding store before setting a value
3802
or deleting an option. In practice the store will often be loaded but
3803
this helps catching some programming errors.
3806
section = store.get_mutable_section(self.mutable_section_id)
3807
return store, section
3809
def set(self, name, value):
3810
"""Set a new value for the option."""
3811
store, section = self._get_mutable_section()
3812
section.set(name, store.quote(value))
3813
for hook in ConfigHooks['set']:
3814
hook(self, name, value)
3816
def remove(self, name):
3817
"""Remove an existing option."""
3818
_, section = self._get_mutable_section()
3819
section.remove(name)
3820
for hook in ConfigHooks['remove']:
3824
# Mostly for debugging use
3825
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3827
def _get_overrides(self):
3828
# Hack around library_state.initialize never called
3829
if bzrlib.global_state is not None:
3830
return bzrlib.global_state.cmdline_overrides.get_sections()
3834
class MemoryStack(Stack):
3835
"""A configuration stack defined from a string.
3837
This is mainly intended for tests and requires no disk resources.
3840
def __init__(self, content=None):
3841
"""Create an in-memory stack from a given content.
3843
It uses a single store based on configobj and support reading and
3846
:param content: The initial content of the store. If None, the store is
3847
not loaded and ``_load_from_string`` can and should be used if
3850
store = IniFileStore()
3851
if content is not None:
3852
store._load_from_string(content)
3853
super(MemoryStack, self).__init__(
3854
[store.get_sections], store)
3857
class _CompatibleStack(Stack):
3858
"""Place holder for compatibility with previous design.
3860
This is intended to ease the transition from the Config-based design to the
3861
Stack-based design and should not be used nor relied upon by plugins.
3863
One assumption made here is that the daughter classes will all use Stores
3864
derived from LockableIniFileStore).
3866
It implements set() and remove () by re-loading the store before applying
3867
the modification and saving it.
3869
The long term plan being to implement a single write by store to save
3870
all modifications, this class should not be used in the interim.
3873
def set(self, name, value):
3876
super(_CompatibleStack, self).set(name, value)
3877
# Force a write to persistent storage
3880
def remove(self, name):
3883
super(_CompatibleStack, self).remove(name)
3884
# Force a write to persistent storage
3888
class GlobalStack(_CompatibleStack):
3889
"""Global options only stack.
3891
The following sections are queried:
3893
* command-line overrides,
3895
* the 'DEFAULT' section in bazaar.conf
3897
This stack will use the ``DEFAULT`` section in bazaar.conf as its
3902
gstore = GlobalStore()
3903
super(GlobalStack, self).__init__(
3904
[self._get_overrides,
3905
NameMatcher(gstore, 'DEFAULT').get_sections],
3906
gstore, mutable_section_id='DEFAULT')
3909
class LocationStack(_CompatibleStack):
3910
"""Per-location options falling back to global options stack.
3913
The following sections are queried:
3915
* command-line overrides,
3917
* the sections matching ``location`` in ``locations.conf``, the order being
3918
defined by the number of path components in the section glob, higher
3919
numbers first (from most specific section to most generic).
3921
* the 'DEFAULT' section in bazaar.conf
3923
This stack will use the ``location`` section in locations.conf as its
3927
def __init__(self, location):
3928
"""Make a new stack for a location and global configuration.
3930
:param location: A URL prefix to """
3931
lstore = LocationStore()
3932
if location.startswith('file://'):
3933
location = urlutils.local_path_from_url(location)
3934
gstore = GlobalStore()
3935
super(LocationStack, self).__init__(
3936
[self._get_overrides,
3937
LocationMatcher(lstore, location).get_sections,
3938
NameMatcher(gstore, 'DEFAULT').get_sections],
3939
lstore, mutable_section_id=location)
3942
class BranchStack(_CompatibleStack):
3943
"""Per-location options falling back to branch then global options stack.
3945
The following sections are queried:
3947
* command-line overrides,
3949
* the sections matching ``location`` in ``locations.conf``, the order being
3950
defined by the number of path components in the section glob, higher
3951
numbers first (from most specific section to most generic),
3953
* the no-name section in branch.conf,
3955
* the ``DEFAULT`` section in ``bazaar.conf``.
3957
This stack will use the no-name section in ``branch.conf`` as its
3961
def __init__(self, branch):
3962
lstore = LocationStore()
3963
bstore = branch._get_config_store()
3964
gstore = GlobalStore()
3965
super(BranchStack, self).__init__(
3966
[self._get_overrides,
3967
LocationMatcher(lstore, branch.base).get_sections,
3968
NameMatcher(bstore, None).get_sections,
3969
NameMatcher(gstore, 'DEFAULT').get_sections],
3971
self.branch = branch
3974
class RemoteControlStack(_CompatibleStack):
3975
"""Remote control-only options stack."""
3977
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3978
# with the stack used for remote bzr dirs. RemoteControlStack only uses
3979
# control.conf and is used only for stack options.
3981
def __init__(self, bzrdir):
3982
cstore = bzrdir._get_config_store()
3983
super(RemoteControlStack, self).__init__(
3984
[NameMatcher(cstore, None).get_sections],
3986
self.bzrdir = bzrdir
3989
class BranchOnlyStack(_CompatibleStack):
3990
"""Branch-only options stack."""
3992
# FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
3993
# stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
3994
# -- vila 2011-12-16
3996
def __init__(self, branch):
3997
bstore = branch._get_config_store()
3998
super(BranchOnlyStack, self).__init__(
3999
[NameMatcher(bstore, None).get_sections],
4001
self.branch = branch
4004
# Use a an empty dict to initialize an empty configobj avoiding all
4005
# parsing and encoding checks
4006
_quoting_config = configobj.ConfigObj(
4007
{}, encoding='utf-8', interpolation=False, list_values=True)
4009
class cmd_config(commands.Command):
4010
__doc__ = """Display, set or remove a configuration option.
4012
Display the active value for a given option.
4014
If --all is specified, NAME is interpreted as a regular expression and all
4015
matching options are displayed mentioning their scope. The active value
4016
that bzr will take into account is the first one displayed for each option.
4018
If no NAME is given, --all .* is implied.
4020
Setting a value is achieved by using name=value without spaces. The value
4021
is set in the most relevant scope and can be checked by displaying the
4025
takes_args = ['name?']
4029
# FIXME: This should be a registry option so that plugins can register
4030
# their own config files (or not) and will also address
4031
# http://pad.lv/788991 -- vila 20101115
4032
commands.Option('scope', help='Reduce the scope to the specified'
4033
' configuration file.',
4035
commands.Option('all',
4036
help='Display all the defined values for the matching options.',
4038
commands.Option('remove', help='Remove the option from'
4039
' the configuration file.'),
4042
_see_also = ['configuration']
4044
@commands.display_command
4045
def run(self, name=None, all=False, directory=None, scope=None,
4047
if directory is None:
4049
directory = urlutils.normalize_url(directory)
4051
raise errors.BzrError(
4052
'--all and --remove are mutually exclusive.')
4054
# Delete the option in the given scope
4055
self._remove_config_option(name, directory, scope)
4057
# Defaults to all options
4058
self._show_matching_options('.*', directory, scope)
4061
name, value = name.split('=', 1)
4063
# Display the option(s) value(s)
4065
self._show_matching_options(name, directory, scope)
4067
self._show_value(name, directory, scope)
4070
raise errors.BzrError(
4071
'Only one option can be set.')
4072
# Set the option value
4073
self._set_config_option(name, value, directory, scope)
4075
def _get_stack(self, directory, scope=None):
4076
"""Get the configuration stack specified by ``directory`` and ``scope``.
4078
:param directory: Where the configurations are derived from.
4080
:param scope: A specific config to start from.
4082
# FIXME: scope should allow access to plugin-specific stacks (even
4083
# reduced to the plugin-specific store), related to
4084
# http://pad.lv/788991 -- vila 2011-11-15
4085
if scope is not None:
4086
if scope == 'bazaar':
4087
return GlobalStack()
4088
elif scope == 'locations':
4089
return LocationStack(directory)
4090
elif scope == 'branch':
4092
controldir.ControlDir.open_containing_tree_or_branch(
4094
return br.get_config_stack()
4095
raise errors.NoSuchConfig(scope)
4099
controldir.ControlDir.open_containing_tree_or_branch(
4101
return br.get_config_stack()
4102
except errors.NotBranchError:
4103
return LocationStack(directory)
4105
def _show_value(self, name, directory, scope):
4106
conf = self._get_stack(directory, scope)
4107
value = conf.get(name, expand=True)
4108
if value is not None:
4109
# Quote the value appropriately
4110
value = _quoting_config._quote(value)
4111
self.outf.write('%s\n' % (value,))
4113
raise errors.NoSuchConfigOption(name)
4115
def _show_matching_options(self, name, directory, scope):
4116
name = lazy_regex.lazy_compile(name)
4117
# We want any error in the regexp to be raised *now* so we need to
4118
# avoid the delay introduced by the lazy regexp. But, we still do
4119
# want the nicer errors raised by lazy_regex.
4120
name._compile_and_collapse()
4123
conf = self._get_stack(directory, scope)
4124
for sections in conf.sections_def:
4125
for store, section in sections():
4126
for oname in section.iter_option_names():
4127
if name.search(oname):
4128
if cur_store_id != store.id:
4129
# Explain where the options are defined
4130
self.outf.write('%s:\n' % (store.id,))
4131
cur_store_id = store.id
4133
if (section.id is not None
4134
and cur_section != section.id):
4135
# Display the section id as it appears in the store
4136
# (None doesn't appear by definition)
4137
self.outf.write(' [%s]\n' % (section.id,))
4138
cur_section = section.id
4139
value = section.get(oname, expand=False)
4140
# Since we don't use the stack, we need to restore a
4143
opt = option_registry.get(oname)
4144
value = opt.convert_from_unicode(store, value)
4146
value = store.unquote(value)
4147
value = _quoting_config._quote(value)
4148
self.outf.write(' %s = %s\n' % (oname, value))
4150
def _set_config_option(self, name, value, directory, scope):
4151
conf = self._get_stack(directory, scope)
4152
conf.set(name, value)
4154
def _remove_config_option(self, name, directory, scope):
4156
raise errors.BzrCommandError(
4157
'--remove expects an option to remove.')
4158
conf = self._get_stack(directory, scope)
4162
raise errors.NoSuchConfigOption(name)
4167
# We need adapters that can build a Store or a Stack in a test context. Test
4168
# classes, based on TestCaseWithTransport, can use the registry to parametrize
4169
# themselves. The builder will receive a test instance and should return a
4170
# ready-to-use store or stack. Plugins that define new store/stacks can also
4171
# register themselves here to be tested against the tests defined in
4172
# bzrlib.tests.test_config. Note that the builder can be called multiple times
4173
# for the same test.
4175
# The registered object should be a callable receiving a test instance
4176
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
4178
test_store_builder_registry = registry.Registry()
4180
# The registered object should be a callable receiving a test instance
4181
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
4183
test_stack_builder_registry = registry.Registry()