1508
2256
configobj[name] = value
1510
2258
configobj.setdefault(section, {})[name] = value
2259
for hook in OldConfigHooks['set']:
2260
hook(self, name, value)
2261
self._set_configobj(configobj)
2263
def remove_option(self, option_name, section_name=None):
2264
configobj = self._get_configobj()
2265
if section_name is None:
2266
del configobj[option_name]
2268
del configobj[section_name][option_name]
2269
for hook in OldConfigHooks['remove']:
2270
hook(self, option_name)
1511
2271
self._set_configobj(configobj)
1513
2273
def _get_config_file(self):
1515
return StringIO(self._transport.get_bytes(self._filename))
2275
f = StringIO(self._transport.get_bytes(self._filename))
2276
for hook in OldConfigHooks['load']:
1516
2279
except errors.NoSuchFile:
1517
2280
return StringIO()
2282
def _external_url(self):
2283
return urlutils.join(self._transport.external_url(), self._filename)
1519
2285
def _get_configobj(self):
1520
return ConfigObj(self._get_config_file(), encoding='utf-8')
2286
f = self._get_config_file()
2289
conf = ConfigObj(f, encoding='utf-8')
2290
except configobj.ConfigObjError, e:
2291
raise errors.ParseConfigError(e.errors, self._external_url())
2292
except UnicodeDecodeError:
2293
raise errors.ConfigContentError(self._external_url())
1522
2298
def _set_configobj(self, configobj):
1523
2299
out_file = StringIO()
1524
2300
configobj.write(out_file)
1525
2301
out_file.seek(0)
1526
2302
self._transport.put_file(self._filename, out_file)
2303
for hook in OldConfigHooks['save']:
2307
class Option(object):
2308
"""An option definition.
2310
The option *values* are stored in config files and found in sections.
2312
Here we define various properties about the option itself, its default
2313
value, how to convert it from stores, what to do when invalid values are
2314
encoutered, in which config files it can be stored.
2317
def __init__(self, name, default=None, default_from_env=None,
2319
from_unicode=None, invalid=None):
2320
"""Build an option definition.
2322
:param name: the name used to refer to the option.
2324
:param default: the default value to use when none exist in the config
2327
:param default_from_env: A list of environment variables which can
2328
provide a default value. 'default' will be used only if none of the
2329
variables specified here are set in the environment.
2331
:param help: a doc string to explain the option to the user.
2333
:param from_unicode: a callable to convert the unicode string
2334
representing the option value in a store. This is not called for
2337
:param invalid: the action to be taken when an invalid value is
2338
encountered in a store. This is called only when from_unicode is
2339
invoked to convert a string and returns None or raise ValueError or
2340
TypeError. Accepted values are: None (ignore invalid values),
2341
'warning' (emit a warning), 'error' (emit an error message and
2344
if default_from_env is None:
2345
default_from_env = []
2347
self.default = default
2348
self.default_from_env = default_from_env
2350
self.from_unicode = from_unicode
2351
if invalid and invalid not in ('warning', 'error'):
2352
raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2353
self.invalid = invalid
2355
def get_default(self):
2356
for var in self.default_from_env:
2358
return os.environ[var]
2363
def get_help_text(self, additional_see_also=None, plain=True):
2365
from bzrlib import help_topics
2366
result += help_topics._format_see_also(additional_see_also)
2368
result = help_topics.help_as_plain_text(result)
2372
# Predefined converters to get proper values from store
2374
def bool_from_store(unicode_str):
2375
return ui.bool_from_string(unicode_str)
2378
def int_from_store(unicode_str):
2379
return int(unicode_str)
2382
def list_from_store(unicode_str):
2383
# ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2384
if isinstance(unicode_str, (str, unicode)):
2386
# A single value, most probably the user forgot (or didn't care to
2387
# add) the final ','
2390
# The empty string, convert to empty list
2393
# We rely on ConfigObj providing us with a list already
2398
class OptionRegistry(registry.Registry):
2399
"""Register config options by their name.
2401
This overrides ``registry.Registry`` to simplify registration by acquiring
2402
some information from the option object itself.
2405
def register(self, option):
2406
"""Register a new option to its name.
2408
:param option: The option to register. Its name is used as the key.
2410
super(OptionRegistry, self).register(option.name, option,
2413
def register_lazy(self, key, module_name, member_name):
2414
"""Register a new option to be loaded on request.
2416
:param key: the key to request the option later. Since the registration
2417
is lazy, it should be provided and match the option name.
2419
:param module_name: the python path to the module. Such as 'os.path'.
2421
:param member_name: the member of the module to return. If empty or
2422
None, get() will return the module itself.
2424
super(OptionRegistry, self).register_lazy(key,
2425
module_name, member_name)
2427
def get_help(self, key=None):
2428
"""Get the help text associated with the given key"""
2429
option = self.get(key)
2430
the_help = option.help
2431
if callable(the_help):
2432
return the_help(self, key)
2436
option_registry = OptionRegistry()
2439
# Registered options in lexicographical order
2441
option_registry.register(
2442
Option('bzr.workingtree.worth_saving_limit', default=10,
2443
from_unicode=int_from_store, invalid='warning',
2445
How many changes before saving the dirstate.
2447
-1 means that we will never rewrite the dirstate file for only
2448
stat-cache changes. Regardless of this setting, we will always rewrite
2449
the dirstate file if a file is added/removed/renamed/etc. This flag only
2450
affects the behavior of updating the dirstate file after we notice that
2451
a file has been touched.
2453
option_registry.register(
2454
Option('dirstate.fdatasync', default=True,
2455
from_unicode=bool_from_store,
2457
Flush dirstate changes onto physical disk?
2459
If true (default), working tree metadata changes are flushed through the
2460
OS buffers to physical disk. This is somewhat slower, but means data
2461
should not be lost if the machine crashes. See also repository.fdatasync.
2463
option_registry.register(
2464
Option('debug_flags', default=[], from_unicode=list_from_store,
2465
help='Debug flags to activate.'))
2466
option_registry.register(
2467
Option('default_format', default='2a',
2468
help='Format used when creating branches.'))
2469
option_registry.register(
2471
help='The command called to launch an editor to enter a message.'))
2472
option_registry.register(
2473
Option('ignore_missing_extensions', default=False,
2474
from_unicode=bool_from_store,
2476
Control the missing extensions warning display.
2478
The warning will not be emitted if set to True.
2480
option_registry.register(
2482
help='Language to translate messages into.'))
2483
option_registry.register(
2484
Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2486
Steal locks that appears to be dead.
2488
If set to True, bzr will check if a lock is supposed to be held by an
2489
active process from the same user on the same machine. If the user and
2490
machine match, but no process with the given PID is active, then bzr
2491
will automatically break the stale lock, and create a new lock for
2493
Otherwise, bzr will prompt as normal to break the lock.
2495
option_registry.register(
2496
Option('output_encoding',
2497
help= 'Unicode encoding for output'
2498
' (terminal encoding if not specified).'))
2499
option_registry.register(
2500
Option('repository.fdatasync', default=True, from_unicode=bool_from_store,
2502
Flush repository changes onto physical disk?
2504
If true (default), repository changes are flushed through the OS buffers
2505
to physical disk. This is somewhat slower, but means data should not be
2506
lost if the machine crashes. See also dirstate.fdatasync.
2510
class Section(object):
2511
"""A section defines a dict of option name => value.
2513
This is merely a read-only dict which can add some knowledge about the
2514
options. It is *not* a python dict object though and doesn't try to mimic
2518
def __init__(self, section_id, options):
2519
self.id = section_id
2520
# We re-use the dict-like object received
2521
self.options = options
2523
def get(self, name, default=None):
2524
return self.options.get(name, default)
2527
# Mostly for debugging use
2528
return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2531
_NewlyCreatedOption = object()
2532
"""Was the option created during the MutableSection lifetime"""
2535
class MutableSection(Section):
2536
"""A section allowing changes and keeping track of the original values."""
2538
def __init__(self, section_id, options):
2539
super(MutableSection, self).__init__(section_id, options)
2542
def set(self, name, value):
2543
if name not in self.options:
2544
# This is a new option
2545
self.orig[name] = _NewlyCreatedOption
2546
elif name not in self.orig:
2547
self.orig[name] = self.get(name, None)
2548
self.options[name] = value
2550
def remove(self, name):
2551
if name not in self.orig:
2552
self.orig[name] = self.get(name, None)
2553
del self.options[name]
2556
class Store(object):
2557
"""Abstract interface to persistent storage for configuration options."""
2559
readonly_section_class = Section
2560
mutable_section_class = MutableSection
2562
def is_loaded(self):
2563
"""Returns True if the Store has been loaded.
2565
This is used to implement lazy loading and ensure the persistent
2566
storage is queried only when needed.
2568
raise NotImplementedError(self.is_loaded)
2571
"""Loads the Store from persistent storage."""
2572
raise NotImplementedError(self.load)
2574
def _load_from_string(self, bytes):
2575
"""Create a store from a string in configobj syntax.
2577
:param bytes: A string representing the file content.
2579
raise NotImplementedError(self._load_from_string)
2582
"""Unloads the Store.
2584
This should make is_loaded() return False. This is used when the caller
2585
knows that the persistent storage has changed or may have change since
2588
raise NotImplementedError(self.unload)
2591
"""Saves the Store to persistent storage."""
2592
raise NotImplementedError(self.save)
2594
def external_url(self):
2595
raise NotImplementedError(self.external_url)
2597
def get_sections(self):
2598
"""Returns an ordered iterable of existing sections.
2600
:returns: An iterable of (name, dict).
2602
raise NotImplementedError(self.get_sections)
2604
def get_mutable_section(self, section_name=None):
2605
"""Returns the specified mutable section.
2607
:param section_name: The section identifier
2609
raise NotImplementedError(self.get_mutable_section)
2612
# Mostly for debugging use
2613
return "<config.%s(%s)>" % (self.__class__.__name__,
2614
self.external_url())
2617
class IniFileStore(Store):
2618
"""A config Store using ConfigObj for storage.
2620
:ivar transport: The transport object where the config file is located.
2622
:ivar file_name: The config file basename in the transport directory.
2624
:ivar _config_obj: Private member to hold the ConfigObj instance used to
2625
serialize/deserialize the config file.
2628
def __init__(self, transport, file_name):
2629
"""A config Store using ConfigObj for storage.
2631
:param transport: The transport object where the config file is located.
2633
:param file_name: The config file basename in the transport directory.
2635
super(IniFileStore, self).__init__()
2636
self.transport = transport
2637
self.file_name = file_name
2638
self._config_obj = None
2640
def is_loaded(self):
2641
return self._config_obj != None
2644
self._config_obj = None
2647
"""Load the store from the associated file."""
2648
if self.is_loaded():
2650
content = self.transport.get_bytes(self.file_name)
2651
self._load_from_string(content)
2652
for hook in ConfigHooks['load']:
2655
def _load_from_string(self, bytes):
2656
"""Create a config store from a string.
2658
:param bytes: A string representing the file content.
2660
if self.is_loaded():
2661
raise AssertionError('Already loaded: %r' % (self._config_obj,))
2662
co_input = StringIO(bytes)
2664
# The config files are always stored utf8-encoded
2665
self._config_obj = ConfigObj(co_input, encoding='utf-8')
2666
except configobj.ConfigObjError, e:
2667
self._config_obj = None
2668
raise errors.ParseConfigError(e.errors, self.external_url())
2669
except UnicodeDecodeError:
2670
raise errors.ConfigContentError(self.external_url())
2673
if not self.is_loaded():
2677
self._config_obj.write(out)
2678
self.transport.put_bytes(self.file_name, out.getvalue())
2679
for hook in ConfigHooks['save']:
2682
def external_url(self):
2683
# FIXME: external_url should really accepts an optional relpath
2684
# parameter (bug #750169) :-/ -- vila 2011-04-04
2685
# The following will do in the interim but maybe we don't want to
2686
# expose a path here but rather a config ID and its associated
2687
# object </hand wawe>.
2688
return urlutils.join(self.transport.external_url(), self.file_name)
2690
def get_sections(self):
2691
"""Get the configobj section in the file order.
2693
:returns: An iterable of (name, dict).
2695
# We need a loaded store
2698
except errors.NoSuchFile:
2699
# If the file doesn't exist, there is no sections
2701
cobj = self._config_obj
2703
yield self.readonly_section_class(None, cobj)
2704
for section_name in cobj.sections:
2705
yield self.readonly_section_class(section_name, cobj[section_name])
2707
def get_mutable_section(self, section_name=None):
2708
# We need a loaded store
2711
except errors.NoSuchFile:
2712
# The file doesn't exist, let's pretend it was empty
2713
self._load_from_string('')
2714
if section_name is None:
2715
section = self._config_obj
2717
section = self._config_obj.setdefault(section_name, {})
2718
return self.mutable_section_class(section_name, section)
2721
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
2722
# unlockable stores for use with objects that can already ensure the locking
2723
# (think branches). If different stores (not based on ConfigObj) are created,
2724
# they may face the same issue.
2727
class LockableIniFileStore(IniFileStore):
2728
"""A ConfigObjStore using locks on save to ensure store integrity."""
2730
def __init__(self, transport, file_name, lock_dir_name=None):
2731
"""A config Store using ConfigObj for storage.
2733
:param transport: The transport object where the config file is located.
2735
:param file_name: The config file basename in the transport directory.
2737
if lock_dir_name is None:
2738
lock_dir_name = 'lock'
2739
self.lock_dir_name = lock_dir_name
2740
super(LockableIniFileStore, self).__init__(transport, file_name)
2741
self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
2743
def lock_write(self, token=None):
2744
"""Takes a write lock in the directory containing the config file.
2746
If the directory doesn't exist it is created.
2748
# FIXME: This doesn't check the ownership of the created directories as
2749
# ensure_config_dir_exists does. It should if the transport is local
2750
# -- vila 2011-04-06
2751
self.transport.create_prefix()
2752
return self._lock.lock_write(token)
2757
def break_lock(self):
2758
self._lock.break_lock()
2762
# We need to be able to override the undecorated implementation
2763
self.save_without_locking()
2765
def save_without_locking(self):
2766
super(LockableIniFileStore, self).save()
2769
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
2770
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
2771
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
2773
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
2774
# functions or a registry will make it easier and clearer for tests, focusing
2775
# on the relevant parts of the API that needs testing -- vila 20110503 (based
2776
# on a poolie's remark)
2777
class GlobalStore(LockableIniFileStore):
2779
def __init__(self, possible_transports=None):
2780
t = transport.get_transport_from_path(
2781
config_dir(), possible_transports=possible_transports)
2782
super(GlobalStore, self).__init__(t, 'bazaar.conf')
2785
class LocationStore(LockableIniFileStore):
2787
def __init__(self, possible_transports=None):
2788
t = transport.get_transport_from_path(
2789
config_dir(), possible_transports=possible_transports)
2790
super(LocationStore, self).__init__(t, 'locations.conf')
2793
class BranchStore(IniFileStore):
2795
def __init__(self, branch):
2796
super(BranchStore, self).__init__(branch.control_transport,
2798
self.branch = branch
2800
def lock_write(self, token=None):
2801
return self.branch.lock_write(token)
2804
return self.branch.unlock()
2808
# We need to be able to override the undecorated implementation
2809
self.save_without_locking()
2811
def save_without_locking(self):
2812
super(BranchStore, self).save()
2815
class SectionMatcher(object):
2816
"""Select sections into a given Store.
2818
This intended to be used to postpone getting an iterable of sections from a
2822
def __init__(self, store):
2825
def get_sections(self):
2826
# This is where we require loading the store so we can see all defined
2828
sections = self.store.get_sections()
2829
# Walk the revisions in the order provided
2834
def match(self, secion):
2835
raise NotImplementedError(self.match)
2838
class LocationSection(Section):
2840
def __init__(self, section, length, extra_path):
2841
super(LocationSection, self).__init__(section.id, section.options)
2842
self.length = length
2843
self.extra_path = extra_path
2845
def get(self, name, default=None):
2846
value = super(LocationSection, self).get(name, default)
2847
if value is not None:
2848
policy_name = self.get(name + ':policy', None)
2849
policy = _policy_value.get(policy_name, POLICY_NONE)
2850
if policy == POLICY_APPENDPATH:
2851
value = urlutils.join(value, self.extra_path)
2855
class LocationMatcher(SectionMatcher):
2857
def __init__(self, store, location):
2858
super(LocationMatcher, self).__init__(store)
2859
if location.startswith('file://'):
2860
location = urlutils.local_path_from_url(location)
2861
self.location = location
2863
def _get_matching_sections(self):
2864
"""Get all sections matching ``location``."""
2865
# We slightly diverge from LocalConfig here by allowing the no-name
2866
# section as the most generic one and the lower priority.
2867
no_name_section = None
2869
# Filter out the no_name_section so _iter_for_location_by_parts can be
2870
# used (it assumes all sections have a name).
2871
for section in self.store.get_sections():
2872
if section.id is None:
2873
no_name_section = section
2875
all_sections.append(section)
2876
# Unfortunately _iter_for_location_by_parts deals with section names so
2877
# we have to resync.
2878
filtered_sections = _iter_for_location_by_parts(
2879
[s.id for s in all_sections], self.location)
2880
iter_all_sections = iter(all_sections)
2881
matching_sections = []
2882
if no_name_section is not None:
2883
matching_sections.append(
2884
LocationSection(no_name_section, 0, self.location))
2885
for section_id, extra_path, length in filtered_sections:
2886
# a section id is unique for a given store so it's safe to take the
2887
# first matching section while iterating. Also, all filtered
2888
# sections are part of 'all_sections' and will always be found
2891
section = iter_all_sections.next()
2892
if section_id == section.id:
2893
matching_sections.append(
2894
LocationSection(section, length, extra_path))
2896
return matching_sections
2898
def get_sections(self):
2899
# Override the default implementation as we want to change the order
2900
matching_sections = self._get_matching_sections()
2901
# We want the longest (aka more specific) locations first
2902
sections = sorted(matching_sections,
2903
key=lambda section: (section.length, section.id),
2905
# Sections mentioning 'ignore_parents' restrict the selection
2906
for section in sections:
2907
# FIXME: We really want to use as_bool below -- vila 2011-04-07
2908
ignore = section.get('ignore_parents', None)
2909
if ignore is not None:
2910
ignore = ui.bool_from_string(ignore)
2913
# Finally, we have a valid section
2917
class Stack(object):
2918
"""A stack of configurations where an option can be defined"""
2920
def __init__(self, sections_def, store=None, mutable_section_name=None):
2921
"""Creates a stack of sections with an optional store for changes.
2923
:param sections_def: A list of Section or callables that returns an
2924
iterable of Section. This defines the Sections for the Stack and
2925
can be called repeatedly if needed.
2927
:param store: The optional Store where modifications will be
2928
recorded. If none is specified, no modifications can be done.
2930
:param mutable_section_name: The name of the MutableSection where
2931
changes are recorded. This requires the ``store`` parameter to be
2934
self.sections_def = sections_def
2936
self.mutable_section_name = mutable_section_name
2938
def get(self, name):
2939
"""Return the *first* option value found in the sections.
2941
This is where we guarantee that sections coming from Store are loaded
2942
lazily: the loading is delayed until we need to either check that an
2943
option exists or get its value, which in turn may require to discover
2944
in which sections it can be defined. Both of these (section and option
2945
existence) require loading the store (even partially).
2947
# FIXME: No caching of options nor sections yet -- vila 20110503
2949
# Ensuring lazy loading is achieved by delaying section matching (which
2950
# implies querying the persistent storage) until it can't be avoided
2951
# anymore by using callables to describe (possibly empty) section
2953
for section_or_callable in self.sections_def:
2954
# Each section can expand to multiple ones when a callable is used
2955
if callable(section_or_callable):
2956
sections = section_or_callable()
2958
sections = [section_or_callable]
2959
for section in sections:
2960
value = section.get(name)
2961
if value is not None:
2963
if value is not None:
2965
# If the option is registered, it may provide additional info about
2968
opt = option_registry.get(name)
2972
if (opt is not None and opt.from_unicode is not None
2973
and value is not None):
2974
# If a value exists and the option provides a converter, use it
2976
converted = opt.from_unicode(value)
2977
except (ValueError, TypeError):
2978
# Invalid values are ignored
2980
if converted is None and opt.invalid is not None:
2981
# The conversion failed
2982
if opt.invalid == 'warning':
2983
trace.warning('Value "%s" is not valid for "%s"',
2985
elif opt.invalid == 'error':
2986
raise errors.ConfigOptionValueError(name, value)
2989
# If the option is registered, it may provide a default value
2991
value = opt.get_default()
2992
for hook in ConfigHooks['get']:
2993
hook(self, name, value)
2996
def _get_mutable_section(self):
2997
"""Get the MutableSection for the Stack.
2999
This is where we guarantee that the mutable section is lazily loaded:
3000
this means we won't load the corresponding store before setting a value
3001
or deleting an option. In practice the store will often be loaded but
3002
this allows helps catching some programming errors.
3004
section = self.store.get_mutable_section(self.mutable_section_name)
3007
def set(self, name, value):
3008
"""Set a new value for the option."""
3009
section = self._get_mutable_section()
3010
section.set(name, value)
3011
for hook in ConfigHooks['set']:
3012
hook(self, name, value)
3014
def remove(self, name):
3015
"""Remove an existing option."""
3016
section = self._get_mutable_section()
3017
section.remove(name)
3018
for hook in ConfigHooks['remove']:
3022
# Mostly for debugging use
3023
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3026
class _CompatibleStack(Stack):
3027
"""Place holder for compatibility with previous design.
3029
This is intended to ease the transition from the Config-based design to the
3030
Stack-based design and should not be used nor relied upon by plugins.
3032
One assumption made here is that the daughter classes will all use Stores
3033
derived from LockableIniFileStore).
3035
It implements set() by re-loading the store before applying the
3036
modification and saving it.
3038
The long term plan being to implement a single write by store to save
3039
all modifications, this class should not be used in the interim.
3042
def set(self, name, value):
3045
super(_CompatibleStack, self).set(name, value)
3046
# Force a write to persistent storage
3050
class GlobalStack(_CompatibleStack):
3054
gstore = GlobalStore()
3055
super(GlobalStack, self).__init__([gstore.get_sections], gstore)
3058
class LocationStack(_CompatibleStack):
3060
def __init__(self, location):
3061
"""Make a new stack for a location and global configuration.
3063
:param location: A URL prefix to """
3064
lstore = LocationStore()
3065
matcher = LocationMatcher(lstore, location)
3066
gstore = GlobalStore()
3067
super(LocationStack, self).__init__(
3068
[matcher.get_sections, gstore.get_sections], lstore)
3070
class BranchStack(_CompatibleStack):
3072
def __init__(self, branch):
3073
bstore = BranchStore(branch)
3074
lstore = LocationStore()
3075
matcher = LocationMatcher(lstore, branch.base)
3076
gstore = GlobalStore()
3077
super(BranchStack, self).__init__(
3078
[matcher.get_sections, bstore.get_sections, gstore.get_sections],
3080
self.branch = branch
3083
class cmd_config(commands.Command):
3084
__doc__ = """Display, set or remove a configuration option.
3086
Display the active value for a given option.
3088
If --all is specified, NAME is interpreted as a regular expression and all
3089
matching options are displayed mentioning their scope. The active value
3090
that bzr will take into account is the first one displayed for each option.
3092
If no NAME is given, --all .* is implied.
3094
Setting a value is achieved by using name=value without spaces. The value
3095
is set in the most relevant scope and can be checked by displaying the
3099
takes_args = ['name?']
3103
# FIXME: This should be a registry option so that plugins can register
3104
# their own config files (or not) -- vila 20101002
3105
commands.Option('scope', help='Reduce the scope to the specified'
3106
' configuration file',
3108
commands.Option('all',
3109
help='Display all the defined values for the matching options.',
3111
commands.Option('remove', help='Remove the option from'
3112
' the configuration file'),
3115
_see_also = ['configuration']
3117
@commands.display_command
3118
def run(self, name=None, all=False, directory=None, scope=None,
3120
if directory is None:
3122
directory = urlutils.normalize_url(directory)
3124
raise errors.BzrError(
3125
'--all and --remove are mutually exclusive.')
3127
# Delete the option in the given scope
3128
self._remove_config_option(name, directory, scope)
3130
# Defaults to all options
3131
self._show_matching_options('.*', directory, scope)
3134
name, value = name.split('=', 1)
3136
# Display the option(s) value(s)
3138
self._show_matching_options(name, directory, scope)
3140
self._show_value(name, directory, scope)
3143
raise errors.BzrError(
3144
'Only one option can be set.')
3145
# Set the option value
3146
self._set_config_option(name, value, directory, scope)
3148
def _get_configs(self, directory, scope=None):
3149
"""Iterate the configurations specified by ``directory`` and ``scope``.
3151
:param directory: Where the configurations are derived from.
3153
:param scope: A specific config to start from.
3155
if scope is not None:
3156
if scope == 'bazaar':
3157
yield GlobalConfig()
3158
elif scope == 'locations':
3159
yield LocationConfig(directory)
3160
elif scope == 'branch':
3161
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
3163
yield br.get_config()
3166
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
3168
yield br.get_config()
3169
except errors.NotBranchError:
3170
yield LocationConfig(directory)
3171
yield GlobalConfig()
3173
def _show_value(self, name, directory, scope):
3175
for c in self._get_configs(directory, scope):
3178
for (oname, value, section, conf_id, parser) in c._get_options():
3180
# Display only the first value and exit
3182
# FIXME: We need to use get_user_option to take policies
3183
# into account and we need to make sure the option exists
3184
# too (hence the two for loops), this needs a better API
3186
value = c.get_user_option(name)
3187
# Quote the value appropriately
3188
value = parser._quote(value)
3189
self.outf.write('%s\n' % (value,))
3193
raise errors.NoSuchConfigOption(name)
3195
def _show_matching_options(self, name, directory, scope):
3196
name = lazy_regex.lazy_compile(name)
3197
# We want any error in the regexp to be raised *now* so we need to
3198
# avoid the delay introduced by the lazy regexp. But, we still do
3199
# want the nicer errors raised by lazy_regex.
3200
name._compile_and_collapse()
3203
for c in self._get_configs(directory, scope):
3204
for (oname, value, section, conf_id, parser) in c._get_options():
3205
if name.search(oname):
3206
if cur_conf_id != conf_id:
3207
# Explain where the options are defined
3208
self.outf.write('%s:\n' % (conf_id,))
3209
cur_conf_id = conf_id
3211
if (section not in (None, 'DEFAULT')
3212
and cur_section != section):
3213
# Display the section if it's not the default (or only)
3215
self.outf.write(' [%s]\n' % (section,))
3216
cur_section = section
3217
self.outf.write(' %s = %s\n' % (oname, value))
3219
def _set_config_option(self, name, value, directory, scope):
3220
for conf in self._get_configs(directory, scope):
3221
conf.set_user_option(name, value)
3224
raise errors.NoSuchConfig(scope)
3226
def _remove_config_option(self, name, directory, scope):
3228
raise errors.BzrCommandError(
3229
'--remove expects an option to remove.')
3231
for conf in self._get_configs(directory, scope):
3232
for (section_name, section, conf_id) in conf._get_sections():
3233
if scope is not None and conf_id != scope:
3234
# Not the right configuration file
3237
if conf_id != conf.config_id():
3238
conf = self._get_configs(directory, conf_id).next()
3239
# We use the first section in the first config where the
3240
# option is defined to remove it
3241
conf.remove_user_option(name, section_name)
3246
raise errors.NoSuchConfig(scope)
3248
raise errors.NoSuchConfigOption(name)
3252
# We need adapters that can build a Store or a Stack in a test context. Test
3253
# classes, based on TestCaseWithTransport, can use the registry to parametrize
3254
# themselves. The builder will receive a test instance and should return a
3255
# ready-to-use store or stack. Plugins that define new store/stacks can also
3256
# register themselves here to be tested against the tests defined in
3257
# bzrlib.tests.test_config. Note that the builder can be called multiple times
3258
# for the same tests.
3260
# The registered object should be a callable receiving a test instance
3261
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
3263
test_store_builder_registry = registry.Registry()
3265
# The registered object should be a callable receiving a test instance
3266
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
3268
test_stack_builder_registry = registry.Registry()