1508
2267
configobj[name] = value
1510
2269
configobj.setdefault(section, {})[name] = value
2270
for hook in OldConfigHooks['set']:
2271
hook(self, name, value)
2272
self._set_configobj(configobj)
2274
def remove_option(self, option_name, section_name=None):
2275
configobj = self._get_configobj()
2276
if section_name is None:
2277
del configobj[option_name]
2279
del configobj[section_name][option_name]
2280
for hook in OldConfigHooks['remove']:
2281
hook(self, option_name)
1511
2282
self._set_configobj(configobj)
1513
2284
def _get_config_file(self):
1515
return StringIO(self._transport.get_bytes(self._filename))
2286
f = StringIO(self._transport.get_bytes(self._filename))
2287
for hook in OldConfigHooks['load']:
1516
2290
except errors.NoSuchFile:
1517
2291
return StringIO()
2292
except errors.PermissionDenied, e:
2293
trace.warning("Permission denied while trying to open "
2294
"configuration file %s.", urlutils.unescape_for_display(
2295
urlutils.join(self._transport.base, self._filename), "utf-8"))
2298
def _external_url(self):
2299
return urlutils.join(self._transport.external_url(), self._filename)
1519
2301
def _get_configobj(self):
1520
return ConfigObj(self._get_config_file(), encoding='utf-8')
2302
f = self._get_config_file()
2305
conf = ConfigObj(f, encoding='utf-8')
2306
except configobj.ConfigObjError, e:
2307
raise errors.ParseConfigError(e.errors, self._external_url())
2308
except UnicodeDecodeError:
2309
raise errors.ConfigContentError(self._external_url())
1522
2314
def _set_configobj(self, configobj):
1523
2315
out_file = StringIO()
1524
2316
configobj.write(out_file)
1525
2317
out_file.seek(0)
1526
2318
self._transport.put_file(self._filename, out_file)
2319
for hook in OldConfigHooks['save']:
2323
class Option(object):
2324
"""An option definition.
2326
The option *values* are stored in config files and found in sections.
2328
Here we define various properties about the option itself, its default
2329
value, how to convert it from stores, what to do when invalid values are
2330
encoutered, in which config files it can be stored.
2333
def __init__(self, name, default=None, default_from_env=None,
2334
help=None, from_unicode=None, invalid=None):
2335
"""Build an option definition.
2337
:param name: the name used to refer to the option.
2339
:param default: the default value to use when none exist in the config
2340
stores. This is either a string that ``from_unicode`` will convert
2341
into the proper type or a python object that can be stringified (so
2342
only the empty list is supported for example).
2344
:param default_from_env: A list of environment variables which can
2345
provide a default value. 'default' will be used only if none of the
2346
variables specified here are set in the environment.
2348
:param help: a doc string to explain the option to the user.
2350
:param from_unicode: a callable to convert the unicode string
2351
representing the option value in a store. This is not called for
2354
:param invalid: the action to be taken when an invalid value is
2355
encountered in a store. This is called only when from_unicode is
2356
invoked to convert a string and returns None or raise ValueError or
2357
TypeError. Accepted values are: None (ignore invalid values),
2358
'warning' (emit a warning), 'error' (emit an error message and
2361
if default_from_env is None:
2362
default_from_env = []
2364
# Convert the default value to a unicode string so all values are
2365
# strings internally before conversion (via from_unicode) is attempted.
2368
elif isinstance(default, list):
2369
# Only the empty list is supported
2371
raise AssertionError(
2372
'Only empty lists are supported as default values')
2374
elif isinstance(default, (str, unicode, bool, int, float)):
2375
# Rely on python to convert strings, booleans and integers
2376
self.default = u'%s' % (default,)
2377
elif callable(default):
2378
self.default = default
2380
# other python objects are not expected
2381
raise AssertionError('%r is not supported as a default value'
2383
self.default_from_env = default_from_env
2385
self.from_unicode = from_unicode
2386
if invalid and invalid not in ('warning', 'error'):
2387
raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2388
self.invalid = invalid
2390
def convert_from_unicode(self, unicode_value):
2391
if self.from_unicode is None or unicode_value is None:
2392
# Don't convert or nothing to convert
2393
return unicode_value
2395
converted = self.from_unicode(unicode_value)
2396
except (ValueError, TypeError):
2397
# Invalid values are ignored
2399
if converted is None and self.invalid is not None:
2400
# The conversion failed
2401
if self.invalid == 'warning':
2402
trace.warning('Value "%s" is not valid for "%s"',
2403
unicode_value, self.name)
2404
elif self.invalid == 'error':
2405
raise errors.ConfigOptionValueError(self.name, unicode_value)
2408
def get_default(self):
2410
for var in self.default_from_env:
2412
# If the env variable is defined, its value is the default one
2413
value = os.environ[var]
2418
# Otherwise, fallback to the value defined at registration
2419
if callable(self.default):
2420
value = self.default()
2421
if type(value) != unicode:
2422
raise ValueError("%r is not unicode" % value)
2424
value = self.default
2427
def get_help_text(self, additional_see_also=None, plain=True):
2429
from bzrlib import help_topics
2430
result += help_topics._format_see_also(additional_see_also)
2432
result = help_topics.help_as_plain_text(result)
2436
# Predefined converters to get proper values from store
2438
def bool_from_store(unicode_str):
2439
return ui.bool_from_string(unicode_str)
2442
def int_from_store(unicode_str):
2443
return int(unicode_str)
2446
def float_from_store(unicode_str):
2447
return float(unicode_str)
2451
# Use a an empty dict to initialize an empty configobj avoiding all
2452
# parsing and encoding checks
2453
_list_converter_config = configobj.ConfigObj(
2454
{}, encoding='utf-8', list_values=True, interpolation=False)
2457
def list_from_store(unicode_str):
2458
if not isinstance(unicode_str, basestring):
2460
# Now inject our string directly as unicode. All callers got their value
2461
# from configobj, so values that need to be quoted are already properly
2463
_list_converter_config.reset()
2464
_list_converter_config._parse([u"list=%s" % (unicode_str,)])
2465
maybe_list = _list_converter_config['list']
2466
# ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2467
if isinstance(maybe_list, basestring):
2469
# A single value, most probably the user forgot (or didn't care to
2470
# add) the final ','
2473
# The empty string, convert to empty list
2476
# We rely on ConfigObj providing us with a list already
2481
class OptionRegistry(registry.Registry):
2482
"""Register config options by their name.
2484
This overrides ``registry.Registry`` to simplify registration by acquiring
2485
some information from the option object itself.
2488
def register(self, option):
2489
"""Register a new option to its name.
2491
:param option: The option to register. Its name is used as the key.
2493
super(OptionRegistry, self).register(option.name, option,
2496
def register_lazy(self, key, module_name, member_name):
2497
"""Register a new option to be loaded on request.
2499
:param key: the key to request the option later. Since the registration
2500
is lazy, it should be provided and match the option name.
2502
:param module_name: the python path to the module. Such as 'os.path'.
2504
:param member_name: the member of the module to return. If empty or
2505
None, get() will return the module itself.
2507
super(OptionRegistry, self).register_lazy(key,
2508
module_name, member_name)
2510
def get_help(self, key=None):
2511
"""Get the help text associated with the given key"""
2512
option = self.get(key)
2513
the_help = option.help
2514
if callable(the_help):
2515
return the_help(self, key)
2519
option_registry = OptionRegistry()
2522
# Registered options in lexicographical order
2524
option_registry.register(
2525
Option('acceptable_keys',
2526
default=None, from_unicode=list_from_store,
2528
List of GPG key patterns which are acceptable for verification.
2530
option_registry.register(
2531
Option('bzr.workingtree.worth_saving_limit', default=10,
2532
from_unicode=int_from_store, invalid='warning',
2534
How many changes before saving the dirstate.
2536
-1 means that we will never rewrite the dirstate file for only
2537
stat-cache changes. Regardless of this setting, we will always rewrite
2538
the dirstate file if a file is added/removed/renamed/etc. This flag only
2539
affects the behavior of updating the dirstate file after we notice that
2540
a file has been touched.
2542
option_registry.register(
2543
Option('check_signatures', default=CHECK_IF_POSSIBLE,
2544
from_unicode=signature_policy_from_unicode,
2546
GPG checking policy.
2548
Possible values: require, ignore, check-available (default)
2550
this option will control whether bzr will require good gpg
2551
signatures, ignore them, or check them if they are
2554
option_registry.register(
2555
Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2556
from_unicode=signing_policy_from_unicode,
2560
Possible values: always, never, when-required (default)
2562
This option controls whether bzr will always create
2563
gpg signatures or not on commits.
2565
option_registry.register(
2566
Option('dirstate.fdatasync', default=True,
2567
from_unicode=bool_from_store,
2569
Flush dirstate changes onto physical disk?
2571
If true (default), working tree metadata changes are flushed through the
2572
OS buffers to physical disk. This is somewhat slower, but means data
2573
should not be lost if the machine crashes. See also repository.fdatasync.
2575
option_registry.register(
2576
Option('debug_flags', default=[], from_unicode=list_from_store,
2577
help='Debug flags to activate.'))
2578
option_registry.register(
2579
Option('default_format', default='2a',
2580
help='Format used when creating branches.'))
2581
option_registry.register(
2582
Option('dpush_strict', default=None,
2583
from_unicode=bool_from_store,
2585
The default value for ``dpush --strict``.
2587
If present, defines the ``--strict`` option default value for checking
2588
uncommitted changes before pushing into a different VCS without any
2589
custom bzr metadata.
2591
option_registry.register(
2593
help='The command called to launch an editor to enter a message.'))
2596
def default_email():
2597
name, email = _auto_user_id()
2599
return '%s <%s>' % (name, email)
2602
raise errors.NoWhoami()
2605
option_registry.register(
2606
Option('email', default=default_email,
2607
default_from_env=['BZR_EMAIL', 'EMAIL'],
2608
help='The users identity'))
2609
option_registry.register(
2610
Option('gpg_signing_command',
2613
Program to use use for creating signatures.
2615
This should support at least the -u and --clearsign options.
2617
option_registry.register(
2618
Option('gpg_signing_key',
2621
GPG key to use for signing.
2623
This defaults to the first key associated with the users email.
2625
option_registry.register(
2626
Option('ignore_missing_extensions', default=False,
2627
from_unicode=bool_from_store,
2629
Control the missing extensions warning display.
2631
The warning will not be emitted if set to True.
2633
option_registry.register(
2635
help='Language to translate messages into.'))
2636
option_registry.register(
2637
Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2639
Steal locks that appears to be dead.
2641
If set to True, bzr will check if a lock is supposed to be held by an
2642
active process from the same user on the same machine. If the user and
2643
machine match, but no process with the given PID is active, then bzr
2644
will automatically break the stale lock, and create a new lock for
2646
Otherwise, bzr will prompt as normal to break the lock.
2648
option_registry.register(
2649
Option('log_format', default='long',
2651
Log format to use when displaying revisions.
2653
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2654
may be provided by plugins.
2656
option_registry.register(
2657
Option('output_encoding',
2658
help= 'Unicode encoding for output'
2659
' (terminal encoding if not specified).'))
2660
option_registry.register(
2661
Option('push_strict', default=None,
2662
from_unicode=bool_from_store,
2664
The default value for ``push --strict``.
2666
If present, defines the ``--strict`` option default value for checking
2667
uncommitted changes before sending a merge directive.
2669
option_registry.register(
2670
Option('repository.fdatasync', default=True,
2671
from_unicode=bool_from_store,
2673
Flush repository changes onto physical disk?
2675
If true (default), repository changes are flushed through the OS buffers
2676
to physical disk. This is somewhat slower, but means data should not be
2677
lost if the machine crashes. See also dirstate.fdatasync.
2680
option_registry.register(
2681
Option('selftest.timeout',
2683
from_unicode=int_from_store,
2684
help='Abort selftest if one test takes longer than this many seconds',
2687
option_registry.register(
2688
Option('send_strict', default=None,
2689
from_unicode=bool_from_store,
2691
The default value for ``send --strict``.
2693
If present, defines the ``--strict`` option default value for checking
2694
uncommitted changes before pushing.
2697
option_registry.register(
2698
Option('serve.client_timeout',
2699
default=300.0, from_unicode=float_from_store,
2700
help="If we wait for a new request from a client for more than"
2701
" X seconds, consider the client idle, and hangup."))
2704
class Section(object):
2705
"""A section defines a dict of option name => value.
2707
This is merely a read-only dict which can add some knowledge about the
2708
options. It is *not* a python dict object though and doesn't try to mimic
2712
def __init__(self, section_id, options):
2713
self.id = section_id
2714
# We re-use the dict-like object received
2715
self.options = options
2717
def get(self, name, default=None, expand=True):
2718
return self.options.get(name, default)
2720
def iter_option_names(self):
2721
for k in self.options.iterkeys():
2725
# Mostly for debugging use
2726
return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2729
_NewlyCreatedOption = object()
2730
"""Was the option created during the MutableSection lifetime"""
2733
class MutableSection(Section):
2734
"""A section allowing changes and keeping track of the original values."""
2736
def __init__(self, section_id, options):
2737
super(MutableSection, self).__init__(section_id, options)
2740
def set(self, name, value):
2741
if name not in self.options:
2742
# This is a new option
2743
self.orig[name] = _NewlyCreatedOption
2744
elif name not in self.orig:
2745
self.orig[name] = self.get(name, None)
2746
self.options[name] = value
2748
def remove(self, name):
2749
if name not in self.orig:
2750
self.orig[name] = self.get(name, None)
2751
del self.options[name]
2754
class Store(object):
2755
"""Abstract interface to persistent storage for configuration options."""
2757
readonly_section_class = Section
2758
mutable_section_class = MutableSection
2760
def is_loaded(self):
2761
"""Returns True if the Store has been loaded.
2763
This is used to implement lazy loading and ensure the persistent
2764
storage is queried only when needed.
2766
raise NotImplementedError(self.is_loaded)
2769
"""Loads the Store from persistent storage."""
2770
raise NotImplementedError(self.load)
2772
def _load_from_string(self, bytes):
2773
"""Create a store from a string in configobj syntax.
2775
:param bytes: A string representing the file content.
2777
raise NotImplementedError(self._load_from_string)
2780
"""Unloads the Store.
2782
This should make is_loaded() return False. This is used when the caller
2783
knows that the persistent storage has changed or may have change since
2786
raise NotImplementedError(self.unload)
2789
"""Saves the Store to persistent storage."""
2790
raise NotImplementedError(self.save)
2792
def external_url(self):
2793
raise NotImplementedError(self.external_url)
2795
def get_sections(self):
2796
"""Returns an ordered iterable of existing sections.
2798
:returns: An iterable of (store, section).
2800
raise NotImplementedError(self.get_sections)
2802
def get_mutable_section(self, section_id=None):
2803
"""Returns the specified mutable section.
2805
:param section_id: The section identifier
2807
raise NotImplementedError(self.get_mutable_section)
2810
# Mostly for debugging use
2811
return "<config.%s(%s)>" % (self.__class__.__name__,
2812
self.external_url())
2815
class CommandLineStore(Store):
2816
"A store to carry command line overrides for the config options."""
2818
def __init__(self, opts=None):
2819
super(CommandLineStore, self).__init__()
2825
# The dict should be cleared but not replaced so it can be shared.
2826
self.options.clear()
2828
def _from_cmdline(self, overrides):
2829
# Reset before accepting new definitions
2831
for over in overrides:
2833
name, value = over.split('=', 1)
2835
raise errors.BzrCommandError(
2836
gettext("Invalid '%s', should be of the form 'name=value'")
2838
self.options[name] = value
2840
def external_url(self):
2841
# Not an url but it makes debugging easier and is never needed
2845
def get_sections(self):
2846
yield self, self.readonly_section_class('cmdline_overrides',
2850
class IniFileStore(Store):
2851
"""A config Store using ConfigObj for storage.
2853
:ivar transport: The transport object where the config file is located.
2855
:ivar file_name: The config file basename in the transport directory.
2857
:ivar _config_obj: Private member to hold the ConfigObj instance used to
2858
serialize/deserialize the config file.
2862
"""A config Store using ConfigObj for storage.
2864
super(IniFileStore, self).__init__()
2865
self._config_obj = None
2867
def is_loaded(self):
2868
return self._config_obj != None
2871
self._config_obj = None
2873
def _load_content(self):
2874
"""Load the config file bytes.
2876
This should be provided by subclasses
2878
:return: Byte string
2880
raise NotImplementedError(self._load_content)
2882
def _save_content(self, content):
2883
"""Save the config file bytes.
2885
This should be provided by subclasses
2887
:param content: Config file bytes to write
2889
raise NotImplementedError(self._save_content)
2892
"""Load the store from the associated file."""
2893
if self.is_loaded():
2895
content = self._load_content()
2896
self._load_from_string(content)
2897
for hook in ConfigHooks['load']:
2900
def _load_from_string(self, bytes):
2901
"""Create a config store from a string.
2903
:param bytes: A string representing the file content.
2905
if self.is_loaded():
2906
raise AssertionError('Already loaded: %r' % (self._config_obj,))
2907
co_input = StringIO(bytes)
2909
# The config files are always stored utf8-encoded
2910
self._config_obj = ConfigObj(co_input, encoding='utf-8',
2912
except configobj.ConfigObjError, e:
2913
self._config_obj = None
2914
raise errors.ParseConfigError(e.errors, self.external_url())
2915
except UnicodeDecodeError:
2916
raise errors.ConfigContentError(self.external_url())
2919
if not self.is_loaded():
2923
self._config_obj.write(out)
2924
self._save_content(out.getvalue())
2925
for hook in ConfigHooks['save']:
2928
def get_sections(self):
2929
"""Get the configobj section in the file order.
2931
:returns: An iterable of (store, section).
2933
# We need a loaded store
2936
except (errors.NoSuchFile, errors.PermissionDenied):
2937
# If the file can't be read, there is no sections
2939
cobj = self._config_obj
2941
yield self, self.readonly_section_class(None, cobj)
2942
for section_name in cobj.sections:
2944
self.readonly_section_class(section_name,
2945
cobj[section_name]))
2947
def get_mutable_section(self, section_id=None):
2948
# We need a loaded store
2951
except errors.NoSuchFile:
2952
# The file doesn't exist, let's pretend it was empty
2953
self._load_from_string('')
2954
if section_id is None:
2955
section = self._config_obj
2957
section = self._config_obj.setdefault(section_id, {})
2958
return self.mutable_section_class(section_id, section)
2961
class TransportIniFileStore(IniFileStore):
2962
"""IniFileStore that loads files from a transport.
2965
def __init__(self, transport, file_name):
2966
"""A Store using a ini file on a Transport
2968
:param transport: The transport object where the config file is located.
2969
:param file_name: The config file basename in the transport directory.
2971
super(TransportIniFileStore, self).__init__()
2972
self.transport = transport
2973
self.file_name = file_name
2975
def _load_content(self):
2977
return self.transport.get_bytes(self.file_name)
2978
except errors.PermissionDenied:
2979
trace.warning("Permission denied while trying to load "
2980
"configuration store %s.", self.external_url())
2983
def _save_content(self, content):
2984
self.transport.put_bytes(self.file_name, content)
2986
def external_url(self):
2987
# FIXME: external_url should really accepts an optional relpath
2988
# parameter (bug #750169) :-/ -- vila 2011-04-04
2989
# The following will do in the interim but maybe we don't want to
2990
# expose a path here but rather a config ID and its associated
2991
# object </hand wawe>.
2992
return urlutils.join(self.transport.external_url(), self.file_name)
2995
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
2996
# unlockable stores for use with objects that can already ensure the locking
2997
# (think branches). If different stores (not based on ConfigObj) are created,
2998
# they may face the same issue.
3001
class LockableIniFileStore(TransportIniFileStore):
3002
"""A ConfigObjStore using locks on save to ensure store integrity."""
3004
def __init__(self, transport, file_name, lock_dir_name=None):
3005
"""A config Store using ConfigObj for storage.
3007
:param transport: The transport object where the config file is located.
3009
:param file_name: The config file basename in the transport directory.
3011
if lock_dir_name is None:
3012
lock_dir_name = 'lock'
3013
self.lock_dir_name = lock_dir_name
3014
super(LockableIniFileStore, self).__init__(transport, file_name)
3015
self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
3017
def lock_write(self, token=None):
3018
"""Takes a write lock in the directory containing the config file.
3020
If the directory doesn't exist it is created.
3022
# FIXME: This doesn't check the ownership of the created directories as
3023
# ensure_config_dir_exists does. It should if the transport is local
3024
# -- vila 2011-04-06
3025
self.transport.create_prefix()
3026
return self._lock.lock_write(token)
3031
def break_lock(self):
3032
self._lock.break_lock()
3036
# We need to be able to override the undecorated implementation
3037
self.save_without_locking()
3039
def save_without_locking(self):
3040
super(LockableIniFileStore, self).save()
3043
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
3044
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
3045
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
3047
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
3048
# functions or a registry will make it easier and clearer for tests, focusing
3049
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3050
# on a poolie's remark)
3051
class GlobalStore(LockableIniFileStore):
3053
def __init__(self, possible_transports=None):
3054
t = transport.get_transport_from_path(
3055
config_dir(), possible_transports=possible_transports)
3056
super(GlobalStore, self).__init__(t, 'bazaar.conf')
3060
class LocationStore(LockableIniFileStore):
3062
def __init__(self, possible_transports=None):
3063
t = transport.get_transport_from_path(
3064
config_dir(), possible_transports=possible_transports)
3065
super(LocationStore, self).__init__(t, 'locations.conf')
3066
self.id = 'locations'
3069
class BranchStore(TransportIniFileStore):
3071
def __init__(self, branch):
3072
super(BranchStore, self).__init__(branch.control_transport,
3074
self.branch = branch
3077
def lock_write(self, token=None):
3078
return self.branch.lock_write(token)
3081
return self.branch.unlock()
3085
# We need to be able to override the undecorated implementation
3086
self.save_without_locking()
3088
def save_without_locking(self):
3089
super(BranchStore, self).save()
3092
class ControlStore(LockableIniFileStore):
3094
def __init__(self, bzrdir):
3095
super(ControlStore, self).__init__(bzrdir.transport,
3097
lock_dir_name='branch_lock')
3100
class SectionMatcher(object):
3101
"""Select sections into a given Store.
3103
This is intended to be used to postpone getting an iterable of sections
3107
def __init__(self, store):
3110
def get_sections(self):
3111
# This is where we require loading the store so we can see all defined
3113
sections = self.store.get_sections()
3114
# Walk the revisions in the order provided
3115
for store, s in sections:
3119
def match(self, section):
3120
"""Does the proposed section match.
3122
:param section: A Section object.
3124
:returns: True if the section matches, False otherwise.
3126
raise NotImplementedError(self.match)
3129
class NameMatcher(SectionMatcher):
3131
def __init__(self, store, section_id):
3132
super(NameMatcher, self).__init__(store)
3133
self.section_id = section_id
3135
def match(self, section):
3136
return section.id == self.section_id
3139
class LocationSection(Section):
3141
def __init__(self, section, length, extra_path):
3142
super(LocationSection, self).__init__(section.id, section.options)
3143
self.length = length
3144
self.extra_path = extra_path
3145
self.locals = {'relpath': extra_path,
3146
'basename': urlutils.basename(extra_path)}
3148
def get(self, name, default=None, expand=True):
3149
value = super(LocationSection, self).get(name, default)
3150
if value is not None and expand:
3151
policy_name = self.get(name + ':policy', None)
3152
policy = _policy_value.get(policy_name, POLICY_NONE)
3153
if policy == POLICY_APPENDPATH:
3154
value = urlutils.join(value, self.extra_path)
3155
# expand section local options right now (since POLICY_APPENDPATH
3156
# will never add options references, it's ok to expand after it).
3158
for is_ref, chunk in iter_option_refs(value):
3160
chunks.append(chunk)
3163
if ref in self.locals:
3164
chunks.append(self.locals[ref])
3166
chunks.append(chunk)
3167
value = ''.join(chunks)
3171
class LocationMatcher(SectionMatcher):
3173
def __init__(self, store, location):
3174
super(LocationMatcher, self).__init__(store)
3175
if location.startswith('file://'):
3176
location = urlutils.local_path_from_url(location)
3177
self.location = location
3179
def _get_matching_sections(self):
3180
"""Get all sections matching ``location``."""
3181
# We slightly diverge from LocalConfig here by allowing the no-name
3182
# section as the most generic one and the lower priority.
3183
no_name_section = None
3185
# Filter out the no_name_section so _iter_for_location_by_parts can be
3186
# used (it assumes all sections have a name).
3187
for _, section in self.store.get_sections():
3188
if section.id is None:
3189
no_name_section = section
3191
all_sections.append(section)
3192
# Unfortunately _iter_for_location_by_parts deals with section names so
3193
# we have to resync.
3194
filtered_sections = _iter_for_location_by_parts(
3195
[s.id for s in all_sections], self.location)
3196
iter_all_sections = iter(all_sections)
3197
matching_sections = []
3198
if no_name_section is not None:
3199
matching_sections.append(
3200
LocationSection(no_name_section, 0, self.location))
3201
for section_id, extra_path, length in filtered_sections:
3202
# a section id is unique for a given store so it's safe to take the
3203
# first matching section while iterating. Also, all filtered
3204
# sections are part of 'all_sections' and will always be found
3207
section = iter_all_sections.next()
3208
if section_id == section.id:
3209
matching_sections.append(
3210
LocationSection(section, length, extra_path))
3212
return matching_sections
3214
def get_sections(self):
3215
# Override the default implementation as we want to change the order
3216
matching_sections = self._get_matching_sections()
3217
# We want the longest (aka more specific) locations first
3218
sections = sorted(matching_sections,
3219
key=lambda section: (section.length, section.id),
3221
# Sections mentioning 'ignore_parents' restrict the selection
3222
for section in sections:
3223
# FIXME: We really want to use as_bool below -- vila 2011-04-07
3224
ignore = section.get('ignore_parents', None)
3225
if ignore is not None:
3226
ignore = ui.bool_from_string(ignore)
3229
# Finally, we have a valid section
3230
yield self.store, section
3233
_option_ref_re = lazy_regex.lazy_compile('({[^{}]+})')
3234
"""Describes an expandable option reference.
3236
We want to match the most embedded reference first.
3238
I.e. for '{{foo}}' we will get '{foo}',
3239
for '{bar{baz}}' we will get '{baz}'
3242
def iter_option_refs(string):
3243
# Split isolate refs so every other chunk is a ref
3245
for chunk in _option_ref_re.split(string):
3250
class Stack(object):
3251
"""A stack of configurations where an option can be defined"""
3253
def __init__(self, sections_def, store=None, mutable_section_id=None):
3254
"""Creates a stack of sections with an optional store for changes.
3256
:param sections_def: A list of Section or callables that returns an
3257
iterable of Section. This defines the Sections for the Stack and
3258
can be called repeatedly if needed.
3260
:param store: The optional Store where modifications will be
3261
recorded. If none is specified, no modifications can be done.
3263
:param mutable_section_id: The id of the MutableSection where changes
3264
are recorded. This requires the ``store`` parameter to be
3267
self.sections_def = sections_def
3269
self.mutable_section_id = mutable_section_id
3271
def get(self, name, expand=None):
3272
"""Return the *first* option value found in the sections.
3274
This is where we guarantee that sections coming from Store are loaded
3275
lazily: the loading is delayed until we need to either check that an
3276
option exists or get its value, which in turn may require to discover
3277
in which sections it can be defined. Both of these (section and option
3278
existence) require loading the store (even partially).
3280
:param name: The queried option.
3282
:param expand: Whether options references should be expanded.
3284
:returns: The value of the option.
3286
# FIXME: No caching of options nor sections yet -- vila 20110503
3288
expand = _get_expand_default_value()
3290
# Ensuring lazy loading is achieved by delaying section matching (which
3291
# implies querying the persistent storage) until it can't be avoided
3292
# anymore by using callables to describe (possibly empty) section
3294
for sections in self.sections_def:
3295
for store, section in sections():
3296
value = section.get(name)
3297
if value is not None:
3299
if value is not None:
3301
# If the option is registered, it may provide additional info about
3304
opt = option_registry.get(name)
3308
def expand_and_convert(val):
3309
# This may need to be called twice if the value is None or ends up
3310
# being None during expansion or conversion.
3313
if isinstance(val, basestring):
3314
val = self._expand_options_in_string(val)
3316
trace.warning('Cannot expand "%s":'
3317
' %s does not support option expansion'
3318
% (name, type(val)))
3320
val = opt.convert_from_unicode(val)
3322
value = expand_and_convert(value)
3323
if opt is not None and value is None:
3324
# If the option is registered, it may provide a default value
3325
value = opt.get_default()
3326
value = expand_and_convert(value)
3327
for hook in ConfigHooks['get']:
3328
hook(self, name, value)
3331
def expand_options(self, string, env=None):
3332
"""Expand option references in the string in the configuration context.
3334
:param string: The string containing option(s) to expand.
3336
:param env: An option dict defining additional configuration options or
3337
overriding existing ones.
3339
:returns: The expanded string.
3341
return self._expand_options_in_string(string, env)
3343
def _expand_options_in_string(self, string, env=None, _refs=None):
3344
"""Expand options in the string in the configuration context.
3346
:param string: The string to be expanded.
3348
:param env: An option dict defining additional configuration options or
3349
overriding existing ones.
3351
:param _refs: Private list (FIFO) containing the options being expanded
3354
:returns: The expanded string.
3357
# Not much to expand there
3360
# What references are currently resolved (to detect loops)
3363
# We need to iterate until no more refs appear ({{foo}} will need two
3364
# iterations for example).
3369
for is_ref, chunk in iter_option_refs(result):
3371
chunks.append(chunk)
3376
raise errors.OptionExpansionLoop(string, _refs)
3378
value = self._expand_option(name, env, _refs)
3380
raise errors.ExpandingUnknownOption(name, string)
3381
chunks.append(value)
3383
result = ''.join(chunks)
3386
def _expand_option(self, name, env, _refs):
3387
if env is not None and name in env:
3388
# Special case, values provided in env takes precedence over
3392
value = self.get(name, expand=False)
3393
value = self._expand_options_in_string(value, env, _refs)
3396
def _get_mutable_section(self):
3397
"""Get the MutableSection for the Stack.
3399
This is where we guarantee that the mutable section is lazily loaded:
3400
this means we won't load the corresponding store before setting a value
3401
or deleting an option. In practice the store will often be loaded but
3402
this helps catching some programming errors.
3404
section = self.store.get_mutable_section(self.mutable_section_id)
3407
def set(self, name, value):
3408
"""Set a new value for the option."""
3409
section = self._get_mutable_section()
3410
section.set(name, value)
3411
for hook in ConfigHooks['set']:
3412
hook(self, name, value)
3414
def remove(self, name):
3415
"""Remove an existing option."""
3416
section = self._get_mutable_section()
3417
section.remove(name)
3418
for hook in ConfigHooks['remove']:
3422
# Mostly for debugging use
3423
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3425
def _get_overrides(self):
3426
# Hack around library_state.initialize never called
3427
if bzrlib.global_state is not None:
3428
return bzrlib.global_state.cmdline_overrides.get_sections()
3432
class _CompatibleStack(Stack):
3433
"""Place holder for compatibility with previous design.
3435
This is intended to ease the transition from the Config-based design to the
3436
Stack-based design and should not be used nor relied upon by plugins.
3438
One assumption made here is that the daughter classes will all use Stores
3439
derived from LockableIniFileStore).
3441
It implements set() and remove () by re-loading the store before applying
3442
the modification and saving it.
3444
The long term plan being to implement a single write by store to save
3445
all modifications, this class should not be used in the interim.
3448
def set(self, name, value):
3451
super(_CompatibleStack, self).set(name, value)
3452
# Force a write to persistent storage
3455
def remove(self, name):
3458
super(_CompatibleStack, self).remove(name)
3459
# Force a write to persistent storage
3463
class GlobalStack(_CompatibleStack):
3464
"""Global options only stack."""
3468
gstore = GlobalStore()
3469
super(GlobalStack, self).__init__(
3470
[self._get_overrides, NameMatcher(gstore, 'DEFAULT').get_sections],
3471
gstore, mutable_section_id='DEFAULT')
3474
class LocationStack(_CompatibleStack):
3475
"""Per-location options falling back to global options stack."""
3477
def __init__(self, location):
3478
"""Make a new stack for a location and global configuration.
3480
:param location: A URL prefix to """
3481
lstore = LocationStore()
3482
if location.startswith('file://'):
3483
location = urlutils.local_path_from_url(location)
3484
matcher = LocationMatcher(lstore, location)
3485
gstore = GlobalStore()
3486
super(LocationStack, self).__init__(
3487
[self._get_overrides,
3488
matcher.get_sections, NameMatcher(gstore, 'DEFAULT').get_sections],
3489
lstore, mutable_section_id=location)
3492
class BranchStack(_CompatibleStack):
3493
"""Per-location options falling back to branch then global options stack."""
3495
def __init__(self, branch):
3496
bstore = branch._get_config_store()
3497
lstore = LocationStore()
3498
matcher = LocationMatcher(lstore, branch.base)
3499
gstore = GlobalStore()
3500
super(BranchStack, self).__init__(
3501
[self._get_overrides,
3502
matcher.get_sections, bstore.get_sections,
3503
NameMatcher(gstore, 'DEFAULT').get_sections],
3505
self.branch = branch
3508
class RemoteControlStack(_CompatibleStack):
3509
"""Remote control-only options stack."""
3511
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3512
# with the stack used for remote bzr dirs. RemoteControlStack only uses
3513
# control.conf and is used only for stack options.
3515
def __init__(self, bzrdir):
3516
cstore = bzrdir._get_config_store()
3517
super(RemoteControlStack, self).__init__(
3518
[cstore.get_sections],
3520
self.bzrdir = bzrdir
3523
class RemoteBranchStack(_CompatibleStack):
3524
"""Remote branch-only options stack."""
3526
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3527
# with the stack used for remote branches. RemoteBranchStack only uses
3528
# branch.conf and is used only for the stack options.
3530
def __init__(self, branch):
3531
bstore = branch._get_config_store()
3532
super(RemoteBranchStack, self).__init__(
3533
[bstore.get_sections],
3535
self.branch = branch
3537
# Use a an empty dict to initialize an empty configobj avoiding all
3538
# parsing and encoding checks
3539
_quoting_config = configobj.ConfigObj(
3540
{}, encoding='utf-8', interpolation=False)
3542
class cmd_config(commands.Command):
3543
__doc__ = """Display, set or remove a configuration option.
3545
Display the active value for a given option.
3547
If --all is specified, NAME is interpreted as a regular expression and all
3548
matching options are displayed mentioning their scope. The active value
3549
that bzr will take into account is the first one displayed for each option.
3551
If no NAME is given, --all .* is implied.
3553
Setting a value is achieved by using name=value without spaces. The value
3554
is set in the most relevant scope and can be checked by displaying the
3558
takes_args = ['name?']
3562
# FIXME: This should be a registry option so that plugins can register
3563
# their own config files (or not) and will also address
3564
# http://pad.lv/788991 -- vila 20101115
3565
commands.Option('scope', help='Reduce the scope to the specified'
3566
' configuration file.',
3568
commands.Option('all',
3569
help='Display all the defined values for the matching options.',
3571
commands.Option('remove', help='Remove the option from'
3572
' the configuration file.'),
3575
_see_also = ['configuration']
3577
@commands.display_command
3578
def run(self, name=None, all=False, directory=None, scope=None,
3580
if directory is None:
3582
directory = urlutils.normalize_url(directory)
3584
raise errors.BzrError(
3585
'--all and --remove are mutually exclusive.')
3587
# Delete the option in the given scope
3588
self._remove_config_option(name, directory, scope)
3590
# Defaults to all options
3591
self._show_matching_options('.*', directory, scope)
3594
name, value = name.split('=', 1)
3596
# Display the option(s) value(s)
3598
self._show_matching_options(name, directory, scope)
3600
self._show_value(name, directory, scope)
3603
raise errors.BzrError(
3604
'Only one option can be set.')
3605
# Set the option value
3606
self._set_config_option(name, value, directory, scope)
3608
def _get_stack(self, directory, scope=None):
3609
"""Get the configuration stack specified by ``directory`` and ``scope``.
3611
:param directory: Where the configurations are derived from.
3613
:param scope: A specific config to start from.
3615
# FIXME: scope should allow access to plugin-specific stacks (even
3616
# reduced to the plugin-specific store), related to
3617
# http://pad.lv/788991 -- vila 2011-11-15
3618
if scope is not None:
3619
if scope == 'bazaar':
3620
return GlobalStack()
3621
elif scope == 'locations':
3622
return LocationStack(directory)
3623
elif scope == 'branch':
3625
controldir.ControlDir.open_containing_tree_or_branch(
3627
return br.get_config_stack()
3628
raise errors.NoSuchConfig(scope)
3632
controldir.ControlDir.open_containing_tree_or_branch(
3634
return br.get_config_stack()
3635
except errors.NotBranchError:
3636
return LocationStack(directory)
3638
def _show_value(self, name, directory, scope):
3639
conf = self._get_stack(directory, scope)
3640
value = conf.get(name, expand=True)
3641
if value is not None:
3642
# Quote the value appropriately
3643
value = _quoting_config._quote(value)
3644
self.outf.write('%s\n' % (value,))
3646
raise errors.NoSuchConfigOption(name)
3648
def _show_matching_options(self, name, directory, scope):
3649
name = lazy_regex.lazy_compile(name)
3650
# We want any error in the regexp to be raised *now* so we need to
3651
# avoid the delay introduced by the lazy regexp. But, we still do
3652
# want the nicer errors raised by lazy_regex.
3653
name._compile_and_collapse()
3656
conf = self._get_stack(directory, scope)
3657
for sections in conf.sections_def:
3658
for store, section in sections():
3659
for oname in section.iter_option_names():
3660
if name.search(oname):
3661
if cur_store_id != store.id:
3662
# Explain where the options are defined
3663
self.outf.write('%s:\n' % (store.id,))
3664
cur_store_id = store.id
3666
if (section.id not in (None, 'DEFAULT')
3667
and cur_section != section.id):
3668
# Display the section if it's not the default (or
3670
self.outf.write(' [%s]\n' % (section.id,))
3671
cur_section = section.id
3672
value = section.get(oname, expand=False)
3673
value = _quoting_config._quote(value)
3674
self.outf.write(' %s = %s\n' % (oname, value))
3676
def _set_config_option(self, name, value, directory, scope):
3677
conf = self._get_stack(directory, scope)
3678
conf.set(name, value)
3680
def _remove_config_option(self, name, directory, scope):
3682
raise errors.BzrCommandError(
3683
'--remove expects an option to remove.')
3684
conf = self._get_stack(directory, scope)
3688
raise errors.NoSuchConfigOption(name)
3693
# We need adapters that can build a Store or a Stack in a test context. Test
3694
# classes, based on TestCaseWithTransport, can use the registry to parametrize
3695
# themselves. The builder will receive a test instance and should return a
3696
# ready-to-use store or stack. Plugins that define new store/stacks can also
3697
# register themselves here to be tested against the tests defined in
3698
# bzrlib.tests.test_config. Note that the builder can be called multiple times
3699
# for the same test.
3701
# The registered object should be a callable receiving a test instance
3702
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
3704
test_store_builder_registry = registry.Registry()
3706
# The registered object should be a callable receiving a test instance
3707
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
3709
test_stack_builder_registry = registry.Registry()