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(
2662
Option('bzr.workingtree.worth_saving_limit', default=10,
2663
from_unicode=int_from_store, invalid='warning',
2665
How many changes before saving the dirstate.
2667
-1 means that we will never rewrite the dirstate file for only
2668
stat-cache changes. Regardless of this setting, we will always rewrite
2669
the dirstate file if a file is added/removed/renamed/etc. This flag only
2670
affects the behavior of updating the dirstate file after we notice that
2671
a file has been touched.
2673
option_registry.register(
2674
Option('check_signatures', default=CHECK_IF_POSSIBLE,
2675
from_unicode=signature_policy_from_unicode,
2677
GPG checking policy.
2679
Possible values: require, ignore, check-available (default)
2681
this option will control whether bzr will require good gpg
2682
signatures, ignore them, or check them if they are
2685
option_registry.register(
2686
Option('child_submit_format',
2687
help='''The preferred format of submissions to this branch.'''))
2688
option_registry.register(
2689
Option('child_submit_to',
2690
help='''Where submissions to this branch are mailed to.'''))
2691
option_registry.register(
2692
Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2693
from_unicode=signing_policy_from_unicode,
2697
Possible values: always, never, when-required (default)
2699
This option controls whether bzr will always create
2700
gpg signatures or not on commits.
2702
option_registry.register(
2703
Option('dirstate.fdatasync', default=True,
2704
from_unicode=bool_from_store,
2706
Flush dirstate changes onto physical disk?
2708
If true (default), working tree metadata changes are flushed through the
2709
OS buffers to physical disk. This is somewhat slower, but means data
2710
should not be lost if the machine crashes. See also repository.fdatasync.
2712
option_registry.register(
2713
ListOption('debug_flags', default=[],
2714
help='Debug flags to activate.'))
2715
option_registry.register(
2716
Option('default_format', default='2a',
2717
help='Format used when creating branches.'))
2718
option_registry.register(
2719
Option('dpush_strict', default=None,
2720
from_unicode=bool_from_store,
2722
The default value for ``dpush --strict``.
2724
If present, defines the ``--strict`` option default value for checking
2725
uncommitted changes before pushing into a different VCS without any
2726
custom bzr metadata.
2728
option_registry.register(
2730
help='The command called to launch an editor to enter a message.'))
2731
option_registry.register(
2732
Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2733
help='The users identity'))
2734
option_registry.register(
2735
Option('gpg_signing_command',
2738
Program to use use for creating signatures.
2740
This should support at least the -u and --clearsign options.
2742
option_registry.register(
2743
Option('gpg_signing_key',
2746
GPG key to use for signing.
2748
This defaults to the first key associated with the users email.
2750
option_registry.register(
2751
Option('ignore_missing_extensions', default=False,
2752
from_unicode=bool_from_store,
2754
Control the missing extensions warning display.
2756
The warning will not be emitted if set to True.
2758
option_registry.register(
2760
help='Language to translate messages into.'))
2761
option_registry.register(
2762
Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2764
Steal locks that appears to be dead.
2766
If set to True, bzr will check if a lock is supposed to be held by an
2767
active process from the same user on the same machine. If the user and
2768
machine match, but no process with the given PID is active, then bzr
2769
will automatically break the stale lock, and create a new lock for
2771
Otherwise, bzr will prompt as normal to break the lock.
2773
option_registry.register(
2774
Option('log_format', default='long',
2776
Log format to use when displaying revisions.
2778
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2779
may be provided by plugins.
2781
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
2783
option_registry.register(
2784
Option('output_encoding',
2785
help= 'Unicode encoding for output'
2786
' (terminal encoding if not specified).'))
2787
option_registry.register(
2788
Option('parent_location',
2791
The location of the default branch for pull or merge.
2793
This option is normally set when creating a branch, the first ``pull`` or by
2794
``pull --remember``.
2796
option_registry.register(
2797
Option('post_commit', default=None,
2799
Post commit functions.
2801
An ordered list of python functions to call, separated by spaces.
2803
Each function takes branch, rev_id as parameters.
2805
option_registry.register(
2806
Option('public_branch',
2809
A publically-accessible version of this branch.
2811
This implies that the branch setting this option is not publically-accessible.
2812
Used and set by ``bzr send``.
2814
option_registry.register(
2815
Option('push_location',
2818
The location of the default branch for push.
2820
This option is normally set by the first ``push`` or ``push --remember``.
2822
option_registry.register(
2823
Option('push_strict', default=None,
2824
from_unicode=bool_from_store,
2826
The default value for ``push --strict``.
2828
If present, defines the ``--strict`` option default value for checking
2829
uncommitted changes before sending a merge directive.
2831
option_registry.register(
2832
Option('repository.fdatasync', default=True,
2833
from_unicode=bool_from_store,
2835
Flush repository changes onto physical disk?
2837
If true (default), repository changes are flushed through the OS buffers
2838
to physical disk. This is somewhat slower, but means data should not be
2839
lost if the machine crashes. See also dirstate.fdatasync.
2841
option_registry.register_lazy('smtp_server',
2842
'bzrlib.smtp_connection', 'smtp_server')
2843
option_registry.register_lazy('smtp_password',
2844
'bzrlib.smtp_connection', 'smtp_password')
2845
option_registry.register_lazy('smtp_username',
2846
'bzrlib.smtp_connection', 'smtp_username')
2847
option_registry.register(
2848
Option('selftest.timeout',
2850
from_unicode=int_from_store,
2851
help='Abort selftest if one test takes longer than this many seconds',
2854
option_registry.register(
2855
Option('send_strict', default=None,
2856
from_unicode=bool_from_store,
2858
The default value for ``send --strict``.
2860
If present, defines the ``--strict`` option default value for checking
2861
uncommitted changes before sending a bundle.
2864
option_registry.register(
2865
Option('serve.client_timeout',
2866
default=300.0, from_unicode=float_from_store,
2867
help="If we wait for a new request from a client for more than"
2868
" X seconds, consider the client idle, and hangup."))
2869
option_registry.register(
2870
Option('stacked_on_location',
2872
help="""The location where this branch is stacked on."""))
2873
option_registry.register(
2874
Option('submit_branch',
2877
The branch you intend to submit your current work to.
2879
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2880
by the ``submit:`` revision spec.
2882
option_registry.register(
2884
help='''Where submissions from this branch are mailed to.'''))
2885
option_registry.register(
2886
ListOption('suppress_warnings',
2888
help="List of warning classes to suppress."))
2889
option_registry.register(
2890
Option('validate_signatures_in_log', default=False,
2891
from_unicode=bool_from_store, invalid='warning',
2892
help='''Whether to validate signatures in bzr log.'''))
2893
option_registry.register_lazy('ssl.ca_certs',
2894
'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2896
option_registry.register_lazy('ssl.cert_reqs',
2897
'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2901
class Section(object):
2902
"""A section defines a dict of option name => value.
2904
This is merely a read-only dict which can add some knowledge about the
2905
options. It is *not* a python dict object though and doesn't try to mimic
2909
def __init__(self, section_id, options):
2910
self.id = section_id
2911
# We re-use the dict-like object received
2912
self.options = options
2914
def get(self, name, default=None, expand=True):
2915
return self.options.get(name, default)
2917
def iter_option_names(self):
2918
for k in self.options.iterkeys():
2922
# Mostly for debugging use
2923
return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2926
_NewlyCreatedOption = object()
2927
"""Was the option created during the MutableSection lifetime"""
2928
_DeletedOption = object()
2929
"""Was the option deleted during the MutableSection lifetime"""
2932
class MutableSection(Section):
2933
"""A section allowing changes and keeping track of the original values."""
2935
def __init__(self, section_id, options):
2936
super(MutableSection, self).__init__(section_id, options)
2937
self.reset_changes()
2939
def set(self, name, value):
2940
if name not in self.options:
2941
# This is a new option
2942
self.orig[name] = _NewlyCreatedOption
2943
elif name not in self.orig:
2944
self.orig[name] = self.get(name, None)
2945
self.options[name] = value
2947
def remove(self, name):
2948
if name not in self.orig:
2949
self.orig[name] = self.get(name, None)
2950
del self.options[name]
2952
def reset_changes(self):
2955
def apply_changes(self, dirty, store):
2956
"""Apply option value changes.
2958
``self`` has been reloaded from the persistent storage. ``dirty``
2959
contains the changes made since the previous loading.
2961
:param dirty: the mutable section containing the changes.
2963
:param store: the store containing the section
2965
for k, expected in dirty.orig.iteritems():
2966
actual = dirty.get(k, _DeletedOption)
2967
reloaded = self.get(k, _NewlyCreatedOption)
2968
if actual is _DeletedOption:
2969
if k in self.options:
2973
# Report concurrent updates in an ad-hoc way. This should only
2974
# occurs when different processes try to update the same option
2975
# which is not supported (as in: the config framework is not meant
2976
# to be used a sharing mechanism).
2977
if expected != reloaded:
2978
if actual is _DeletedOption:
2979
actual = '<DELETED>'
2980
if reloaded is _NewlyCreatedOption:
2981
reloaded = '<CREATED>'
2982
if expected is _NewlyCreatedOption:
2983
expected = '<CREATED>'
2984
# Someone changed the value since we get it from the persistent
2986
trace.warning(gettext(
2987
"Option {0} in section {1} of {2} was changed"
2988
" from {3} to {4}. The {5} value will be saved.".format(
2989
k, self.id, store.external_url(), expected,
2991
# No need to keep track of these changes
2992
self.reset_changes()
2995
class Store(object):
2996
"""Abstract interface to persistent storage for configuration options."""
2998
readonly_section_class = Section
2999
mutable_section_class = MutableSection
3002
# Which sections need to be saved
3003
self.dirty_sections = []
3005
def is_loaded(self):
3006
"""Returns True if the Store has been loaded.
3008
This is used to implement lazy loading and ensure the persistent
3009
storage is queried only when needed.
3011
raise NotImplementedError(self.is_loaded)
3014
"""Loads the Store from persistent storage."""
3015
raise NotImplementedError(self.load)
3017
def _load_from_string(self, bytes):
3018
"""Create a store from a string in configobj syntax.
3020
:param bytes: A string representing the file content.
3022
raise NotImplementedError(self._load_from_string)
3025
"""Unloads the Store.
3027
This should make is_loaded() return False. This is used when the caller
3028
knows that the persistent storage has changed or may have change since
3031
raise NotImplementedError(self.unload)
3033
def quote(self, value):
3034
"""Quote a configuration option value for storing purposes.
3036
This allows Stacks to present values as they will be stored.
3040
def unquote(self, value):
3041
"""Unquote a configuration option value into unicode.
3043
The received value is quoted as stored.
3048
"""Saves the Store to persistent storage."""
3049
raise NotImplementedError(self.save)
3051
def _need_saving(self):
3052
for s in self.dirty_sections:
3054
# At least one dirty section contains a modification
3058
def apply_changes(self, dirty_sections):
3059
"""Apply changes from dirty sections while checking for coherency.
3061
The Store content is discarded and reloaded from persistent storage to
3062
acquire up-to-date values.
3064
Dirty sections are MutableSection which kept track of the value they
3065
are expected to update.
3067
# We need an up-to-date version from the persistent storage, unload the
3068
# store. The reload will occur when needed (triggered by the first
3069
# get_mutable_section() call below.
3071
# Apply the changes from the preserved dirty sections
3072
for dirty in dirty_sections:
3073
clean = self.get_mutable_section(dirty.id)
3074
clean.apply_changes(dirty, self)
3075
# Everything is clean now
3076
self.dirty_sections = []
3078
def save_changes(self):
3079
"""Saves the Store to persistent storage if changes occurred.
3081
Apply the changes recorded in the mutable sections to a store content
3082
refreshed from persistent storage.
3084
raise NotImplementedError(self.save_changes)
3086
def external_url(self):
3087
raise NotImplementedError(self.external_url)
3089
def get_sections(self):
3090
"""Returns an ordered iterable of existing sections.
3092
:returns: An iterable of (store, section).
3094
raise NotImplementedError(self.get_sections)
3096
def get_mutable_section(self, section_id=None):
3097
"""Returns the specified mutable section.
3099
:param section_id: The section identifier
3101
raise NotImplementedError(self.get_mutable_section)
3104
# Mostly for debugging use
3105
return "<config.%s(%s)>" % (self.__class__.__name__,
3106
self.external_url())
3109
class CommandLineStore(Store):
3110
"A store to carry command line overrides for the config options."""
3112
def __init__(self, opts=None):
3113
super(CommandLineStore, self).__init__()
3120
# The dict should be cleared but not replaced so it can be shared.
3121
self.options.clear()
3123
def _from_cmdline(self, overrides):
3124
# Reset before accepting new definitions
3126
for over in overrides:
3128
name, value = over.split('=', 1)
3130
raise errors.BzrCommandError(
3131
gettext("Invalid '%s', should be of the form 'name=value'")
3133
self.options[name] = value
3135
def external_url(self):
3136
# Not an url but it makes debugging easier and is never needed
3140
def get_sections(self):
3141
yield self, self.readonly_section_class(None, self.options)
3144
class IniFileStore(Store):
3145
"""A config Store using ConfigObj for storage.
3147
:ivar _config_obj: Private member to hold the ConfigObj instance used to
3148
serialize/deserialize the config file.
3152
"""A config Store using ConfigObj for storage.
3154
super(IniFileStore, self).__init__()
3155
self._config_obj = None
3157
def is_loaded(self):
3158
return self._config_obj != None
3161
self._config_obj = None
3162
self.dirty_sections = []
3164
def _load_content(self):
3165
"""Load the config file bytes.
3167
This should be provided by subclasses
3169
:return: Byte string
3171
raise NotImplementedError(self._load_content)
3173
def _save_content(self, content):
3174
"""Save the config file bytes.
3176
This should be provided by subclasses
3178
:param content: Config file bytes to write
3180
raise NotImplementedError(self._save_content)
3183
"""Load the store from the associated file."""
3184
if self.is_loaded():
3186
content = self._load_content()
3187
self._load_from_string(content)
3188
for hook in ConfigHooks['load']:
3191
def _load_from_string(self, bytes):
3192
"""Create a config store from a string.
3194
:param bytes: A string representing the file content.
3196
if self.is_loaded():
3197
raise AssertionError('Already loaded: %r' % (self._config_obj,))
3198
co_input = StringIO(bytes)
3200
# The config files are always stored utf8-encoded
3201
self._config_obj = ConfigObj(co_input, encoding='utf-8',
3203
except configobj.ConfigObjError, e:
3204
self._config_obj = None
3205
raise errors.ParseConfigError(e.errors, self.external_url())
3206
except UnicodeDecodeError:
3207
raise errors.ConfigContentError(self.external_url())
3209
def save_changes(self):
3210
if not self.is_loaded():
3213
if not self._need_saving():
3215
# Preserve the current version
3216
current = self._config_obj
3217
dirty_sections = list(self.dirty_sections)
3218
self.apply_changes(dirty_sections)
3219
# Save to the persistent storage
3223
if not self.is_loaded():
3227
self._config_obj.write(out)
3228
self._save_content(out.getvalue())
3229
for hook in ConfigHooks['save']:
3232
def get_sections(self):
3233
"""Get the configobj section in the file order.
3235
:returns: An iterable of (store, section).
3237
# We need a loaded store
3240
except (errors.NoSuchFile, errors.PermissionDenied):
3241
# If the file can't be read, there is no sections
3243
cobj = self._config_obj
3245
yield self, self.readonly_section_class(None, cobj)
3246
for section_name in cobj.sections:
3248
self.readonly_section_class(section_name,
3249
cobj[section_name]))
3251
def get_mutable_section(self, section_id=None):
3252
# We need a loaded store
3255
except errors.NoSuchFile:
3256
# The file doesn't exist, let's pretend it was empty
3257
self._load_from_string('')
3258
if section_id is None:
3259
section = self._config_obj
3261
section = self._config_obj.setdefault(section_id, {})
3262
mutable_section = self.mutable_section_class(section_id, section)
3263
# All mutable sections can become dirty
3264
self.dirty_sections.append(mutable_section)
3265
return mutable_section
3267
def quote(self, value):
3269
# configobj conflates automagical list values and quoting
3270
self._config_obj.list_values = True
3271
return self._config_obj._quote(value)
3273
self._config_obj.list_values = False
3275
def unquote(self, value):
3276
if value and isinstance(value, basestring):
3277
# _unquote doesn't handle None nor empty strings nor anything that
3278
# is not a string, really.
3279
value = self._config_obj._unquote(value)
3282
def external_url(self):
3283
# Since an IniFileStore can be used without a file (at least in tests),
3284
# it's better to provide something than raising a NotImplementedError.
3285
# All daughter classes are supposed to provide an implementation
3287
return 'In-Process Store, no URL'
3289
class TransportIniFileStore(IniFileStore):
3290
"""IniFileStore that loads files from a transport.
3292
:ivar transport: The transport object where the config file is located.
3294
:ivar file_name: The config file basename in the transport directory.
3297
def __init__(self, transport, file_name):
3298
"""A Store using a ini file on a Transport
3300
:param transport: The transport object where the config file is located.
3301
:param file_name: The config file basename in the transport directory.
3303
super(TransportIniFileStore, self).__init__()
3304
self.transport = transport
3305
self.file_name = file_name
3307
def _load_content(self):
3309
return self.transport.get_bytes(self.file_name)
3310
except errors.PermissionDenied:
3311
trace.warning("Permission denied while trying to load "
3312
"configuration store %s.", self.external_url())
3315
def _save_content(self, content):
3316
self.transport.put_bytes(self.file_name, content)
3318
def external_url(self):
3319
# FIXME: external_url should really accepts an optional relpath
3320
# parameter (bug #750169) :-/ -- vila 2011-04-04
3321
# The following will do in the interim but maybe we don't want to
3322
# expose a path here but rather a config ID and its associated
3323
# object </hand wawe>.
3324
return urlutils.join(self.transport.external_url(), self.file_name)
3327
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
3328
# unlockable stores for use with objects that can already ensure the locking
3329
# (think branches). If different stores (not based on ConfigObj) are created,
3330
# they may face the same issue.
3333
class LockableIniFileStore(TransportIniFileStore):
3334
"""A ConfigObjStore using locks on save to ensure store integrity."""
3336
def __init__(self, transport, file_name, lock_dir_name=None):
3337
"""A config Store using ConfigObj for storage.
3339
:param transport: The transport object where the config file is located.
3341
:param file_name: The config file basename in the transport directory.
3343
if lock_dir_name is None:
3344
lock_dir_name = 'lock'
3345
self.lock_dir_name = lock_dir_name
3346
super(LockableIniFileStore, self).__init__(transport, file_name)
3347
self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
3349
def lock_write(self, token=None):
3350
"""Takes a write lock in the directory containing the config file.
3352
If the directory doesn't exist it is created.
3354
# FIXME: This doesn't check the ownership of the created directories as
3355
# ensure_config_dir_exists does. It should if the transport is local
3356
# -- vila 2011-04-06
3357
self.transport.create_prefix()
3358
return self._lock.lock_write(token)
3363
def break_lock(self):
3364
self._lock.break_lock()
3368
# We need to be able to override the undecorated implementation
3369
self.save_without_locking()
3371
def save_without_locking(self):
3372
super(LockableIniFileStore, self).save()
3375
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
3376
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
3377
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
3379
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
3380
# functions or a registry will make it easier and clearer for tests, focusing
3381
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3382
# on a poolie's remark)
3383
class GlobalStore(LockableIniFileStore):
3385
def __init__(self, possible_transports=None):
3386
t = transport.get_transport_from_path(
3387
config_dir(), possible_transports=possible_transports)
3388
super(GlobalStore, self).__init__(t, 'bazaar.conf')
3392
class LocationStore(LockableIniFileStore):
3394
def __init__(self, possible_transports=None):
3395
t = transport.get_transport_from_path(
3396
config_dir(), possible_transports=possible_transports)
3397
super(LocationStore, self).__init__(t, 'locations.conf')
3398
self.id = 'locations'
3401
class BranchStore(TransportIniFileStore):
3403
def __init__(self, branch):
3404
super(BranchStore, self).__init__(branch.control_transport,
3406
self.branch = branch
3409
def lock_write(self, token=None):
3410
return self.branch.lock_write(token)
3413
return self.branch.unlock()
3417
# We need to be able to override the undecorated implementation
3418
self.save_without_locking()
3420
def save_without_locking(self):
3421
super(BranchStore, self).save()
3424
class ControlStore(LockableIniFileStore):
3426
def __init__(self, bzrdir):
3427
super(ControlStore, self).__init__(bzrdir.transport,
3429
lock_dir_name='branch_lock')
3433
class SectionMatcher(object):
3434
"""Select sections into a given Store.
3436
This is intended to be used to postpone getting an iterable of sections
3440
def __init__(self, store):
3443
def get_sections(self):
3444
# This is where we require loading the store so we can see all defined
3446
sections = self.store.get_sections()
3447
# Walk the revisions in the order provided
3448
for store, s in sections:
3452
def match(self, section):
3453
"""Does the proposed section match.
3455
:param section: A Section object.
3457
:returns: True if the section matches, False otherwise.
3459
raise NotImplementedError(self.match)
3462
class NameMatcher(SectionMatcher):
3464
def __init__(self, store, section_id):
3465
super(NameMatcher, self).__init__(store)
3466
self.section_id = section_id
3468
def match(self, section):
3469
return section.id == self.section_id
3472
class LocationSection(Section):
3474
def __init__(self, section, extra_path):
3475
super(LocationSection, self).__init__(section.id, section.options)
3476
self.extra_path = extra_path
3477
self.locals = {'relpath': extra_path,
3478
'basename': urlutils.basename(extra_path)}
3480
def get(self, name, default=None, expand=True):
3481
value = super(LocationSection, self).get(name, default)
3482
if value is not None and expand:
3483
policy_name = self.get(name + ':policy', None)
3484
policy = _policy_value.get(policy_name, POLICY_NONE)
3485
if policy == POLICY_APPENDPATH:
3486
value = urlutils.join(value, self.extra_path)
3487
# expand section local options right now (since POLICY_APPENDPATH
3488
# will never add options references, it's ok to expand after it).
3490
for is_ref, chunk in iter_option_refs(value):
3492
chunks.append(chunk)
3495
if ref in self.locals:
3496
chunks.append(self.locals[ref])
3498
chunks.append(chunk)
3499
value = ''.join(chunks)
3503
class StartingPathMatcher(SectionMatcher):
3504
"""Select sections for a given location respecting the Store order."""
3506
# FIXME: Both local paths and urls can be used for section names as well as
3507
# ``location`` to stay consistent with ``LocationMatcher`` which itself
3508
# inherited the fuzziness from the previous ``LocationConfig``
3509
# implementation. We probably need to revisit which encoding is allowed for
3510
# both ``location`` and section names and how we normalize
3511
# them. http://pad.lv/85479, http://pad.lv/437009 and http://359320 are
3512
# related too. -- vila 2012-01-04
3514
def __init__(self, store, location):
3515
super(StartingPathMatcher, self).__init__(store)
3516
if location.startswith('file://'):
3517
location = urlutils.local_path_from_url(location)
3518
self.location = location
3520
def get_sections(self):
3521
"""Get all sections matching ``location`` in the store.
3523
The most generic sections are described first in the store, then more
3524
specific ones can be provided for reduced scopes.
3526
The returned section are therefore returned in the reversed order so
3527
the most specific ones can be found first.
3529
location_parts = self.location.rstrip('/').split('/')
3532
# Later sections are more specific, they should be returned first
3533
for _, section in reversed(list(store.get_sections())):
3534
if section.id is None:
3535
# The no-name section is always included if present
3536
yield store, LocationSection(section, self.location)
3538
section_path = section.id
3539
if section_path.startswith('file://'):
3540
# the location is already a local path or URL, convert the
3541
# section id to the same format
3542
section_path = urlutils.local_path_from_url(section_path)
3543
if (self.location.startswith(section_path)
3544
or fnmatch.fnmatch(self.location, section_path)):
3545
section_parts = section_path.rstrip('/').split('/')
3546
extra_path = '/'.join(location_parts[len(section_parts):])
3547
yield store, LocationSection(section, extra_path)
3550
class LocationMatcher(SectionMatcher):
3552
def __init__(self, store, location):
3553
super(LocationMatcher, self).__init__(store)
3554
if location.startswith('file://'):
3555
location = urlutils.local_path_from_url(location)
3556
self.location = location
3558
def _get_matching_sections(self):
3559
"""Get all sections matching ``location``."""
3560
# We slightly diverge from LocalConfig here by allowing the no-name
3561
# section as the most generic one and the lower priority.
3562
no_name_section = None
3564
# Filter out the no_name_section so _iter_for_location_by_parts can be
3565
# used (it assumes all sections have a name).
3566
for _, section in self.store.get_sections():
3567
if section.id is None:
3568
no_name_section = section
3570
all_sections.append(section)
3571
# Unfortunately _iter_for_location_by_parts deals with section names so
3572
# we have to resync.
3573
filtered_sections = _iter_for_location_by_parts(
3574
[s.id for s in all_sections], self.location)
3575
iter_all_sections = iter(all_sections)
3576
matching_sections = []
3577
if no_name_section is not None:
3578
matching_sections.append(
3579
(0, LocationSection(no_name_section, self.location)))
3580
for section_id, extra_path, length in filtered_sections:
3581
# a section id is unique for a given store so it's safe to take the
3582
# first matching section while iterating. Also, all filtered
3583
# sections are part of 'all_sections' and will always be found
3586
section = iter_all_sections.next()
3587
if section_id == section.id:
3588
matching_sections.append(
3589
(length, LocationSection(section, extra_path)))
3591
return matching_sections
3593
def get_sections(self):
3594
# Override the default implementation as we want to change the order
3595
matching_sections = self._get_matching_sections()
3596
# We want the longest (aka more specific) locations first
3597
sections = sorted(matching_sections,
3598
key=lambda (length, section): (length, section.id),
3600
# Sections mentioning 'ignore_parents' restrict the selection
3601
for _, section in sections:
3602
# FIXME: We really want to use as_bool below -- vila 2011-04-07
3603
ignore = section.get('ignore_parents', None)
3604
if ignore is not None:
3605
ignore = ui.bool_from_string(ignore)
3608
# Finally, we have a valid section
3609
yield self.store, section
3612
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
3613
"""Describes an expandable option reference.
3615
We want to match the most embedded reference first.
3617
I.e. for '{{foo}}' we will get '{foo}',
3618
for '{bar{baz}}' we will get '{baz}'
3621
def iter_option_refs(string):
3622
# Split isolate refs so every other chunk is a ref
3624
for chunk in _option_ref_re.split(string):
3629
class Stack(object):
3630
"""A stack of configurations where an option can be defined"""
3632
def __init__(self, sections_def, store=None, mutable_section_id=None):
3633
"""Creates a stack of sections with an optional store for changes.
3635
:param sections_def: A list of Section or callables that returns an
3636
iterable of Section. This defines the Sections for the Stack and
3637
can be called repeatedly if needed.
3639
:param store: The optional Store where modifications will be
3640
recorded. If none is specified, no modifications can be done.
3642
:param mutable_section_id: The id of the MutableSection where changes
3643
are recorded. This requires the ``store`` parameter to be
3646
self.sections_def = sections_def
3648
self.mutable_section_id = mutable_section_id
3650
def get(self, name, expand=None):
3651
"""Return the *first* option value found in the sections.
3653
This is where we guarantee that sections coming from Store are loaded
3654
lazily: the loading is delayed until we need to either check that an
3655
option exists or get its value, which in turn may require to discover
3656
in which sections it can be defined. Both of these (section and option
3657
existence) require loading the store (even partially).
3659
:param name: The queried option.
3661
:param expand: Whether options references should be expanded.
3663
:returns: The value of the option.
3665
# FIXME: No caching of options nor sections yet -- vila 20110503
3667
expand = _get_expand_default_value()
3669
found_store = None # Where the option value has been found
3670
# If the option is registered, it may provide additional info about
3673
opt = option_registry.get(name)
3678
def expand_and_convert(val):
3679
# This may need to be called in different contexts if the value is
3680
# None or ends up being None during expansion or conversion.
3683
if isinstance(val, basestring):
3684
val = self._expand_options_in_string(val)
3686
trace.warning('Cannot expand "%s":'
3687
' %s does not support option expansion'
3688
% (name, type(val)))
3690
val = found_store.unquote(val)
3692
val = opt.convert_from_unicode(found_store, val)
3695
# First of all, check if the environment can override the configuration
3697
if opt is not None and opt.override_from_env:
3698
value = opt.get_override()
3699
value = expand_and_convert(value)
3701
# Ensuring lazy loading is achieved by delaying section matching
3702
# (which implies querying the persistent storage) until it can't be
3703
# avoided anymore by using callables to describe (possibly empty)
3705
for sections in self.sections_def:
3706
for store, section in sections():
3707
value = section.get(name)
3708
if value is not None:
3711
if value is not None:
3713
value = expand_and_convert(value)
3714
if opt is not None and value is None:
3715
# If the option is registered, it may provide a default value
3716
value = opt.get_default()
3717
value = expand_and_convert(value)
3718
for hook in ConfigHooks['get']:
3719
hook(self, name, value)
3722
def expand_options(self, string, env=None):
3723
"""Expand option references in the string in the configuration context.
3725
:param string: The string containing option(s) to expand.
3727
:param env: An option dict defining additional configuration options or
3728
overriding existing ones.
3730
:returns: The expanded string.
3732
return self._expand_options_in_string(string, env)
3734
def _expand_options_in_string(self, string, env=None, _refs=None):
3735
"""Expand options in the string in the configuration context.
3737
:param string: The string to be expanded.
3739
:param env: An option dict defining additional configuration options or
3740
overriding existing ones.
3742
:param _refs: Private list (FIFO) containing the options being expanded
3745
:returns: The expanded string.
3748
# Not much to expand there
3751
# What references are currently resolved (to detect loops)
3754
# We need to iterate until no more refs appear ({{foo}} will need two
3755
# iterations for example).
3760
for is_ref, chunk in iter_option_refs(result):
3762
chunks.append(chunk)
3767
raise errors.OptionExpansionLoop(string, _refs)
3769
value = self._expand_option(name, env, _refs)
3771
raise errors.ExpandingUnknownOption(name, string)
3772
chunks.append(value)
3774
result = ''.join(chunks)
3777
def _expand_option(self, name, env, _refs):
3778
if env is not None and name in env:
3779
# Special case, values provided in env takes precedence over
3783
value = self.get(name, expand=False)
3784
value = self._expand_options_in_string(value, env, _refs)
3787
def _get_mutable_section(self):
3788
"""Get the MutableSection for the Stack.
3790
This is where we guarantee that the mutable section is lazily loaded:
3791
this means we won't load the corresponding store before setting a value
3792
or deleting an option. In practice the store will often be loaded but
3793
this helps catching some programming errors.
3796
section = store.get_mutable_section(self.mutable_section_id)
3797
return store, section
3799
def set(self, name, value):
3800
"""Set a new value for the option."""
3801
store, section = self._get_mutable_section()
3802
section.set(name, store.quote(value))
3803
for hook in ConfigHooks['set']:
3804
hook(self, name, value)
3806
def remove(self, name):
3807
"""Remove an existing option."""
3808
_, section = self._get_mutable_section()
3809
section.remove(name)
3810
for hook in ConfigHooks['remove']:
3814
# Mostly for debugging use
3815
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3817
def _get_overrides(self):
3818
# Hack around library_state.initialize never called
3819
if bzrlib.global_state is not None:
3820
return bzrlib.global_state.cmdline_overrides.get_sections()
3824
class MemoryStack(Stack):
3825
"""A configuration stack defined from a string.
3827
This is mainly intended for tests and requires no disk resources.
3830
def __init__(self, content=None):
3831
"""Create an in-memory stack from a given content.
3833
It uses a single store based on configobj and support reading and
3836
:param content: The initial content of the store. If None, the store is
3837
not loaded and ``_load_from_string`` can and should be used if
3840
store = IniFileStore()
3841
if content is not None:
3842
store._load_from_string(content)
3843
super(MemoryStack, self).__init__(
3844
[store.get_sections], store)
3847
class _CompatibleStack(Stack):
3848
"""Place holder for compatibility with previous design.
3850
This is intended to ease the transition from the Config-based design to the
3851
Stack-based design and should not be used nor relied upon by plugins.
3853
One assumption made here is that the daughter classes will all use Stores
3854
derived from LockableIniFileStore).
3856
It implements set() and remove () by re-loading the store before applying
3857
the modification and saving it.
3859
The long term plan being to implement a single write by store to save
3860
all modifications, this class should not be used in the interim.
3863
def set(self, name, value):
3866
super(_CompatibleStack, self).set(name, value)
3867
# Force a write to persistent storage
3870
def remove(self, name):
3873
super(_CompatibleStack, self).remove(name)
3874
# Force a write to persistent storage
3878
class GlobalStack(_CompatibleStack):
3879
"""Global options only stack.
3881
The following sections are queried:
3883
* command-line overrides,
3885
* the 'DEFAULT' section in bazaar.conf
3887
This stack will use the ``DEFAULT`` section in bazaar.conf as its
3892
gstore = GlobalStore()
3893
super(GlobalStack, self).__init__(
3894
[self._get_overrides,
3895
NameMatcher(gstore, 'DEFAULT').get_sections],
3896
gstore, mutable_section_id='DEFAULT')
3899
class LocationStack(_CompatibleStack):
3900
"""Per-location options falling back to global options stack.
3903
The following sections are queried:
3905
* command-line overrides,
3907
* the sections matching ``location`` in ``locations.conf``, the order being
3908
defined by the number of path components in the section glob, higher
3909
numbers first (from most specific section to most generic).
3911
* the 'DEFAULT' section in bazaar.conf
3913
This stack will use the ``location`` section in locations.conf as its
3917
def __init__(self, location):
3918
"""Make a new stack for a location and global configuration.
3920
:param location: A URL prefix to """
3921
lstore = LocationStore()
3922
if location.startswith('file://'):
3923
location = urlutils.local_path_from_url(location)
3924
gstore = GlobalStore()
3925
super(LocationStack, self).__init__(
3926
[self._get_overrides,
3927
LocationMatcher(lstore, location).get_sections,
3928
NameMatcher(gstore, 'DEFAULT').get_sections],
3929
lstore, mutable_section_id=location)
3932
class BranchStack(_CompatibleStack):
3933
"""Per-location options falling back to branch then global options stack.
3935
The following sections are queried:
3937
* command-line overrides,
3939
* the sections matching ``location`` in ``locations.conf``, the order being
3940
defined by the number of path components in the section glob, higher
3941
numbers first (from most specific section to most generic),
3943
* the no-name section in branch.conf,
3945
* the ``DEFAULT`` section in ``bazaar.conf``.
3947
This stack will use the no-name section in ``branch.conf`` as its
3951
def __init__(self, branch):
3952
lstore = LocationStore()
3953
bstore = branch._get_config_store()
3954
gstore = GlobalStore()
3955
super(BranchStack, self).__init__(
3956
[self._get_overrides,
3957
LocationMatcher(lstore, branch.base).get_sections,
3958
NameMatcher(bstore, None).get_sections,
3959
NameMatcher(gstore, 'DEFAULT').get_sections],
3961
self.branch = branch
3964
class RemoteControlStack(_CompatibleStack):
3965
"""Remote control-only options stack."""
3967
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3968
# with the stack used for remote bzr dirs. RemoteControlStack only uses
3969
# control.conf and is used only for stack options.
3971
def __init__(self, bzrdir):
3972
cstore = bzrdir._get_config_store()
3973
super(RemoteControlStack, self).__init__(
3974
[NameMatcher(cstore, None).get_sections],
3976
self.bzrdir = bzrdir
3979
class BranchOnlyStack(_CompatibleStack):
3980
"""Branch-only options stack."""
3982
# FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
3983
# stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
3984
# -- vila 2011-12-16
3986
def __init__(self, branch):
3987
bstore = branch._get_config_store()
3988
super(BranchOnlyStack, self).__init__(
3989
[NameMatcher(bstore, None).get_sections],
3991
self.branch = branch
3994
# Use a an empty dict to initialize an empty configobj avoiding all
3995
# parsing and encoding checks
3996
_quoting_config = configobj.ConfigObj(
3997
{}, encoding='utf-8', interpolation=False, list_values=True)
3999
class cmd_config(commands.Command):
4000
__doc__ = """Display, set or remove a configuration option.
4002
Display the active value for a given option.
4004
If --all is specified, NAME is interpreted as a regular expression and all
4005
matching options are displayed mentioning their scope. The active value
4006
that bzr will take into account is the first one displayed for each option.
4008
If no NAME is given, --all .* is implied.
4010
Setting a value is achieved by using name=value without spaces. The value
4011
is set in the most relevant scope and can be checked by displaying the
4015
takes_args = ['name?']
4019
# FIXME: This should be a registry option so that plugins can register
4020
# their own config files (or not) and will also address
4021
# http://pad.lv/788991 -- vila 20101115
4022
commands.Option('scope', help='Reduce the scope to the specified'
4023
' configuration file.',
4025
commands.Option('all',
4026
help='Display all the defined values for the matching options.',
4028
commands.Option('remove', help='Remove the option from'
4029
' the configuration file.'),
4032
_see_also = ['configuration']
4034
@commands.display_command
4035
def run(self, name=None, all=False, directory=None, scope=None,
4037
if directory is None:
4039
directory = urlutils.normalize_url(directory)
4041
raise errors.BzrError(
4042
'--all and --remove are mutually exclusive.')
4044
# Delete the option in the given scope
4045
self._remove_config_option(name, directory, scope)
4047
# Defaults to all options
4048
self._show_matching_options('.*', directory, scope)
4051
name, value = name.split('=', 1)
4053
# Display the option(s) value(s)
4055
self._show_matching_options(name, directory, scope)
4057
self._show_value(name, directory, scope)
4060
raise errors.BzrError(
4061
'Only one option can be set.')
4062
# Set the option value
4063
self._set_config_option(name, value, directory, scope)
4065
def _get_stack(self, directory, scope=None):
4066
"""Get the configuration stack specified by ``directory`` and ``scope``.
4068
:param directory: Where the configurations are derived from.
4070
:param scope: A specific config to start from.
4072
# FIXME: scope should allow access to plugin-specific stacks (even
4073
# reduced to the plugin-specific store), related to
4074
# http://pad.lv/788991 -- vila 2011-11-15
4075
if scope is not None:
4076
if scope == 'bazaar':
4077
return GlobalStack()
4078
elif scope == 'locations':
4079
return LocationStack(directory)
4080
elif scope == 'branch':
4082
controldir.ControlDir.open_containing_tree_or_branch(
4084
return br.get_config_stack()
4085
raise errors.NoSuchConfig(scope)
4089
controldir.ControlDir.open_containing_tree_or_branch(
4091
return br.get_config_stack()
4092
except errors.NotBranchError:
4093
return LocationStack(directory)
4095
def _show_value(self, name, directory, scope):
4096
conf = self._get_stack(directory, scope)
4097
value = conf.get(name, expand=True)
4098
if value is not None:
4099
# Quote the value appropriately
4100
value = _quoting_config._quote(value)
4101
self.outf.write('%s\n' % (value,))
4103
raise errors.NoSuchConfigOption(name)
4105
def _show_matching_options(self, name, directory, scope):
4106
name = lazy_regex.lazy_compile(name)
4107
# We want any error in the regexp to be raised *now* so we need to
4108
# avoid the delay introduced by the lazy regexp. But, we still do
4109
# want the nicer errors raised by lazy_regex.
4110
name._compile_and_collapse()
4113
conf = self._get_stack(directory, scope)
4114
for sections in conf.sections_def:
4115
for store, section in sections():
4116
for oname in section.iter_option_names():
4117
if name.search(oname):
4118
if cur_store_id != store.id:
4119
# Explain where the options are defined
4120
self.outf.write('%s:\n' % (store.id,))
4121
cur_store_id = store.id
4123
if (section.id is not None
4124
and cur_section != section.id):
4125
# Display the section id as it appears in the store
4126
# (None doesn't appear by definition)
4127
self.outf.write(' [%s]\n' % (section.id,))
4128
cur_section = section.id
4129
value = section.get(oname, expand=False)
4130
# Since we don't use the stack, we need to restore a
4133
opt = option_registry.get(oname)
4134
value = opt.convert_from_unicode(store, value)
4136
value = store.unquote(value)
4137
value = _quoting_config._quote(value)
4138
self.outf.write(' %s = %s\n' % (oname, value))
4140
def _set_config_option(self, name, value, directory, scope):
4141
conf = self._get_stack(directory, scope)
4142
conf.set(name, value)
4144
def _remove_config_option(self, name, directory, scope):
4146
raise errors.BzrCommandError(
4147
'--remove expects an option to remove.')
4148
conf = self._get_stack(directory, scope)
4152
raise errors.NoSuchConfigOption(name)
4157
# We need adapters that can build a Store or a Stack in a test context. Test
4158
# classes, based on TestCaseWithTransport, can use the registry to parametrize
4159
# themselves. The builder will receive a test instance and should return a
4160
# ready-to-use store or stack. Plugins that define new store/stacks can also
4161
# register themselves here to be tested against the tests defined in
4162
# bzrlib.tests.test_config. Note that the builder can be called multiple times
4163
# for the same test.
4165
# The registered object should be a callable receiving a test instance
4166
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
4168
test_store_builder_registry = registry.Registry()
4170
# The registered object should be a callable receiving a test instance
4171
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
4173
test_stack_builder_registry = registry.Registry()