178
214
def _get_signing_policy(self):
179
215
"""Template method to override signature creation policy."""
219
def expand_options(self, string, env=None):
220
"""Expand option references in the string in the configuration context.
222
:param string: The string containing option to expand.
224
:param env: An option dict defining additional configuration options or
225
overriding existing ones.
227
:returns: The expanded string.
229
return self._expand_options_in_string(string, env)
231
def _expand_options_in_list(self, slist, env=None, _ref_stack=None):
232
"""Expand options in a list of strings in the configuration context.
234
:param slist: A list of strings.
236
:param env: An option dict defining additional configuration options or
237
overriding existing ones.
239
:param _ref_stack: Private list containing the options being
240
expanded to detect loops.
242
:returns: The flatten list of expanded strings.
244
# expand options in each value separately flattening lists
247
value = self._expand_options_in_string(s, env, _ref_stack)
248
if isinstance(value, list):
254
def _expand_options_in_string(self, string, env=None, _ref_stack=None):
255
"""Expand options in the string in the configuration context.
257
:param string: The string to be expanded.
259
:param env: An option dict defining additional configuration options or
260
overriding existing ones.
262
:param _ref_stack: Private list containing the options being
263
expanded to detect loops.
265
:returns: The expanded string.
268
# Not much to expand there
270
if _ref_stack is None:
271
# What references are currently resolved (to detect loops)
273
if self.option_ref_re is None:
274
# We want to match the most embedded reference first (i.e. for
275
# '{{foo}}' we will get '{foo}',
276
# for '{bar{baz}}' we will get '{baz}'
277
self.option_ref_re = re.compile('({[^{}]+})')
279
# We need to iterate until no more refs appear ({{foo}} will need two
280
# iterations for example).
282
raw_chunks = self.option_ref_re.split(result)
283
if len(raw_chunks) == 1:
284
# Shorcut the trivial case: no refs
288
# Split will isolate refs so that every other chunk is a ref
290
for chunk in raw_chunks:
293
# Keep only non-empty strings (or we get bogus empty
294
# slots when a list value is involved).
299
if name in _ref_stack:
300
raise errors.OptionExpansionLoop(string, _ref_stack)
301
_ref_stack.append(name)
302
value = self._expand_option(name, env, _ref_stack)
304
raise errors.ExpandingUnknownOption(name, string)
305
if isinstance(value, list):
313
# Once a list appears as the result of an expansion, all
314
# callers will get a list result. This allows a consistent
315
# behavior even when some options in the expansion chain
316
# defined as strings (no comma in their value) but their
317
# expanded value is a list.
318
return self._expand_options_in_list(chunks, env, _ref_stack)
320
result = ''.join(chunks)
323
def _expand_option(self, name, env, _ref_stack):
324
if env is not None and name in env:
325
# Special case, values provided in env takes precedence over
329
# FIXME: This is a limited implementation, what we really need is a
330
# way to query the bzr config for the value of an option,
331
# respecting the scope rules (That is, once we implement fallback
332
# configs, getting the option value should restart from the top
333
# config, not the current one) -- vila 20101222
334
value = self.get_user_option(name, expand=False)
335
if isinstance(value, list):
336
value = self._expand_options_in_list(value, env, _ref_stack)
338
value = self._expand_options_in_string(value, env, _ref_stack)
181
341
def _get_user_option(self, option_name):
182
342
"""Template method to provide a user option."""
185
def get_user_option(self, option_name):
186
"""Get a generic option - no special process, no default."""
187
return self._get_user_option(option_name)
189
def get_user_option_as_bool(self, option_name):
345
def get_user_option(self, option_name, expand=None):
346
"""Get a generic option - no special process, no default.
348
:param option_name: The queried option.
350
:param expand: Whether options references should be expanded.
352
:returns: The value of the option.
355
expand = _get_expand_default_value()
356
value = self._get_user_option(option_name)
358
if isinstance(value, list):
359
value = self._expand_options_in_list(value)
360
elif isinstance(value, dict):
361
trace.warning('Cannot expand "%s":'
362
' Dicts do not support option expansion'
365
value = self._expand_options_in_string(value)
368
def get_user_option_as_bool(self, option_name, expand=None):
190
369
"""Get a generic option as a boolean - no special process, no default.
192
371
:return None if the option doesn't exist or its value can't be
193
372
interpreted as a boolean. Returns True or False otherwise.
195
s = self._get_user_option(option_name)
374
s = self.get_user_option(option_name, expand=expand)
197
376
# The option doesn't exist
476
780
def _get_nickname(self):
477
781
return self.get_user_option('nickname')
480
class GlobalConfig(IniBasedConfig):
783
def remove_user_option(self, option_name, section_name=None):
784
"""Remove a user option and save the configuration file.
786
:param option_name: The option to be removed.
788
:param section_name: The section the option is defined in, default to
792
parser = self._get_parser()
793
if section_name is None:
796
section = parser[section_name]
798
del section[option_name]
800
raise errors.NoSuchConfigOption(option_name)
801
self._write_config_file()
803
def _write_config_file(self):
804
if self.file_name is None:
805
raise AssertionError('We cannot save, self.file_name is None')
806
conf_dir = os.path.dirname(self.file_name)
807
ensure_config_dir_exists(conf_dir)
808
atomic_file = atomicfile.AtomicFile(self.file_name)
809
self._get_parser().write(atomic_file)
812
osutils.copy_ownership_from_path(self.file_name)
815
class LockableConfig(IniBasedConfig):
816
"""A configuration needing explicit locking for access.
818
If several processes try to write the config file, the accesses need to be
821
Daughter classes should decorate all methods that update a config with the
822
``@needs_write_lock`` decorator (they call, directly or indirectly, the
823
``_write_config_file()`` method. These methods (typically ``set_option()``
824
and variants must reload the config file from disk before calling
825
``_write_config_file()``), this can be achieved by calling the
826
``self.reload()`` method. Note that the lock scope should cover both the
827
reading and the writing of the config file which is why the decorator can't
828
be applied to ``_write_config_file()`` only.
830
This should be enough to implement the following logic:
831
- lock for exclusive write access,
832
- reload the config file from disk,
836
This logic guarantees that a writer can update a value without erasing an
837
update made by another writer.
842
def __init__(self, file_name):
843
super(LockableConfig, self).__init__(file_name=file_name)
844
self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
845
# FIXME: It doesn't matter that we don't provide possible_transports
846
# below since this is currently used only for local config files ;
847
# local transports are not shared. But if/when we start using
848
# LockableConfig for other kind of transports, we will need to reuse
849
# whatever connection is already established -- vila 20100929
850
self.transport = transport.get_transport(self.dir)
851
self._lock = lockdir.LockDir(self.transport, self.lock_name)
853
def _create_from_string(self, unicode_bytes, save):
854
super(LockableConfig, self)._create_from_string(unicode_bytes, False)
856
# We need to handle the saving here (as opposed to IniBasedConfig)
859
self._write_config_file()
862
def lock_write(self, token=None):
863
"""Takes a write lock in the directory containing the config file.
865
If the directory doesn't exist it is created.
867
ensure_config_dir_exists(self.dir)
868
return self._lock.lock_write(token)
873
def break_lock(self):
874
self._lock.break_lock()
877
def remove_user_option(self, option_name, section_name=None):
878
super(LockableConfig, self).remove_user_option(option_name,
881
def _write_config_file(self):
882
if self._lock is None or not self._lock.is_held:
883
# NB: if the following exception is raised it probably means a
884
# missing @needs_write_lock decorator on one of the callers.
885
raise errors.ObjectNotLocked(self)
886
super(LockableConfig, self)._write_config_file()
889
class GlobalConfig(LockableConfig):
481
890
"""The configuration that should be used for a specific location."""
893
super(GlobalConfig, self).__init__(file_name=config_filename())
899
def from_string(cls, str_or_unicode, save=False):
900
"""Create a config object from a string.
902
:param str_or_unicode: A string representing the file content. This
903
will be utf-8 encoded.
905
:param save: Whether the file should be saved upon creation.
908
conf._create_from_string(str_or_unicode, save)
483
911
def get_editor(self):
484
912
return self._get_user_option('editor')
487
super(GlobalConfig, self).__init__(config_filename)
489
915
def set_user_option(self, option, value):
490
916
"""Save option and its value in the configuration."""
491
917
self._set_option(option, value, 'DEFAULT')
510
939
self._write_config_file()
512
941
def _set_option(self, option, value, section):
513
# FIXME: RBC 20051029 This should refresh the parser and also take a
514
# file lock on bazaar.conf.
515
conf_dir = os.path.dirname(self._get_filename())
516
ensure_config_dir_exists(conf_dir)
517
943
self._get_parser().setdefault(section, {})[option] = value
518
944
self._write_config_file()
520
def _write_config_file(self):
521
path = self._get_filename()
523
osutils.copy_ownership_from_path(path)
524
self._get_parser().write(f)
528
class LocationConfig(IniBasedConfig):
947
def _get_sections(self, name=None):
948
"""See IniBasedConfig._get_sections()."""
949
parser = self._get_parser()
950
# We don't give access to options defined outside of any section, we
951
# used the DEFAULT section by... default.
952
if name in (None, 'DEFAULT'):
953
# This could happen for an empty file where the DEFAULT section
954
# doesn't exist yet. So we force DEFAULT when yielding
956
if 'DEFAULT' not in parser:
957
parser['DEFAULT']= {}
958
yield (name, parser[name], self.config_id())
961
def remove_user_option(self, option_name, section_name=None):
962
if section_name is None:
963
# We need to force the default section.
964
section_name = 'DEFAULT'
965
# We need to avoid the LockableConfig implementation or we'll lock
967
super(LockableConfig, self).remove_user_option(option_name,
970
def _iter_for_location_by_parts(sections, location):
971
"""Keep only the sessions matching the specified location.
973
:param sections: An iterable of section names.
975
:param location: An url or a local path to match against.
977
:returns: An iterator of (section, extra_path, nb_parts) where nb is the
978
number of path components in the section name, section is the section
979
name and extra_path is the difference between location and the section
982
location_parts = location.rstrip('/').split('/')
984
for section in sections:
985
# location is a local path if possible, so we need
986
# to convert 'file://' urls to local paths if necessary.
988
# FIXME: I don't think the above comment is still up to date,
989
# LocationConfig is always instantiated with an url -- vila 2011-04-07
991
# This also avoids having file:///path be a more exact
992
# match than '/path'.
994
# FIXME: Not sure about the above either, but since the path components
995
# are compared in sync, adding two empty components (//) is likely to
996
# trick the comparison and also trick the check on the number of
997
# components, so we *should* take only the relevant part of the url. On
998
# the other hand, this means 'file://' urls *can't* be used in sections
999
# so more work is probably needed -- vila 2011-04-07
1001
if section.startswith('file://'):
1002
section_path = urlutils.local_path_from_url(section)
1004
section_path = section
1005
section_parts = section_path.rstrip('/').split('/')
1008
if len(section_parts) > len(location_parts):
1009
# More path components in the section, they can't match
1012
# Rely on zip truncating in length to the length of the shortest
1013
# argument sequence.
1014
names = zip(location_parts, section_parts)
1016
if not fnmatch.fnmatch(name[0], name[1]):
1021
# build the path difference between the section and the location
1022
extra_path = '/'.join(location_parts[len(section_parts):])
1023
yield section, extra_path, len(section_parts)
1026
class LocationConfig(LockableConfig):
529
1027
"""A configuration object that gives the policy for a location."""
531
1029
def __init__(self, location):
532
name_generator = locations_config_filename
533
if (not os.path.exists(name_generator()) and
534
os.path.exists(branches_config_filename())):
535
if sys.platform == 'win32':
536
trace.warning('Please rename %s to %s'
537
% (branches_config_filename(),
538
locations_config_filename()))
540
trace.warning('Please rename ~/.bazaar/branches.conf'
541
' to ~/.bazaar/locations.conf')
542
name_generator = branches_config_filename
543
super(LocationConfig, self).__init__(name_generator)
1030
super(LocationConfig, self).__init__(
1031
file_name=locations_config_filename())
544
1032
# local file locations are looked up by local path, rather than
545
1033
# by file url. This is because the config file is a user
546
1034
# file, and we would rather not expose the user to file urls.
1517
2081
return StringIO()
1519
2083
def _get_configobj(self):
1520
return ConfigObj(self._get_config_file(), encoding='utf-8')
2084
f = self._get_config_file()
2086
return ConfigObj(f, encoding='utf-8')
1522
2090
def _set_configobj(self, configobj):
1523
2091
out_file = StringIO()
1524
2092
configobj.write(out_file)
1525
2093
out_file.seek(0)
1526
2094
self._transport.put_file(self._filename, out_file)
2097
class Section(object):
2098
"""A section defines a dict of options.
2100
This is merely a read-only dict which can add some knowledge about the
2101
options. It is *not* a python dict object though and doesn't try to mimic
2105
def __init__(self, section_id, options):
2106
self.id = section_id
2107
# We re-use the dict-like object received
2108
self.options = options
2110
def get(self, name, default=None):
2111
return self.options.get(name, default)
2114
# Mostly for debugging use
2115
return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2118
_NewlyCreatedOption = object()
2119
"""Was the option created during the MutableSection lifetime"""
2122
class MutableSection(Section):
2123
"""A section allowing changes and keeping track of the original values."""
2125
def __init__(self, section_id, options):
2126
super(MutableSection, self).__init__(section_id, options)
2129
def set(self, name, value):
2130
if name not in self.options:
2131
# This is a new option
2132
self.orig[name] = _NewlyCreatedOption
2133
elif name not in self.orig:
2134
self.orig[name] = self.get(name, None)
2135
self.options[name] = value
2137
def remove(self, name):
2138
if name not in self.orig:
2139
self.orig[name] = self.get(name, None)
2140
del self.options[name]
2143
class Store(object):
2144
"""Abstract interface to persistent storage for configuration options."""
2146
readonly_section_class = Section
2147
mutable_section_class = MutableSection
2149
def is_loaded(self):
2150
"""Returns True if the Store has been loaded.
2152
This is used to implement lazy loading and ensure the persistent
2153
storage is queried only when needed.
2155
raise NotImplementedError(self.is_loaded)
2158
"""Loads the Store from persistent storage."""
2159
raise NotImplementedError(self.load)
2161
def _load_from_string(self, str_or_unicode):
2162
"""Create a store from a string in configobj syntax.
2164
:param str_or_unicode: A string representing the file content. This will
2165
be encoded to suit store needs internally.
2167
This is for tests and should not be used in production unless a
2168
convincing use case can be demonstrated :)
2170
raise NotImplementedError(self._load_from_string)
2173
"""Saves the Store to persistent storage."""
2174
raise NotImplementedError(self.save)
2176
def external_url(self):
2177
raise NotImplementedError(self.external_url)
2179
def get_sections(self):
2180
"""Returns an ordered iterable of existing sections.
2182
:returns: An iterable of (name, dict).
2184
raise NotImplementedError(self.get_sections)
2186
def get_mutable_section(self, section_name=None):
2187
"""Returns the specified mutable section.
2189
:param section_name: The section identifier
2191
raise NotImplementedError(self.get_mutable_section)
2194
# Mostly for debugging use
2195
return "<config.%s(%s)>" % (self.__class__.__name__,
2196
self.external_url())
2199
class IniFileStore(Store):
2200
"""A config Store using ConfigObj for storage.
2202
:ivar transport: The transport object where the config file is located.
2204
:ivar file_name: The config file basename in the transport directory.
2206
:ivar _config_obj: Private member to hold the ConfigObj instance used to
2207
serialize/deserialize the config file.
2210
def __init__(self, transport, file_name):
2211
"""A config Store using ConfigObj for storage.
2213
:param transport: The transport object where the config file is located.
2215
:param file_name: The config file basename in the transport directory.
2217
super(IniFileStore, self).__init__()
2218
self.transport = transport
2219
self.file_name = file_name
2220
self._config_obj = None
2222
def is_loaded(self):
2223
return self._config_obj != None
2226
"""Load the store from the associated file."""
2227
if self.is_loaded():
2229
content = self.transport.get_bytes(self.file_name)
2230
self._load_from_string(content)
2232
def _load_from_string(self, str_or_unicode):
2233
"""Create a config store from a string.
2235
:param str_or_unicode: A string representing the file content. This will
2236
be utf-8 encoded internally.
2238
This is for tests and should not be used in production unless a
2239
convincing use case can be demonstrated :)
2241
if self.is_loaded():
2242
raise AssertionError('Already loaded: %r' % (self._config_obj,))
2243
co_input = StringIO(str_or_unicode.encode('utf-8'))
2245
# The config files are always stored utf8-encoded
2246
self._config_obj = ConfigObj(co_input, encoding='utf-8')
2247
except configobj.ConfigObjError, e:
2248
self._config_obj = None
2249
raise errors.ParseConfigError(e.errors, self.external_url())
2252
if not self.is_loaded():
2256
self._config_obj.write(out)
2257
self.transport.put_bytes(self.file_name, out.getvalue())
2259
def external_url(self):
2260
# FIXME: external_url should really accepts an optional relpath
2261
# parameter (bug #750169) :-/ -- vila 2011-04-04
2262
# The following will do in the interim but maybe we don't want to
2263
# expose a path here but rather a config ID and its associated
2264
# object </hand wawe>.
2265
return urlutils.join(self.transport.external_url(), self.file_name)
2267
def get_sections(self):
2268
"""Get the configobj section in the file order.
2270
:returns: An iterable of (name, dict).
2272
# We need a loaded store
2274
cobj = self._config_obj
2276
yield self.readonly_section_class(None, cobj)
2277
for section_name in cobj.sections:
2278
yield self.readonly_section_class(section_name, cobj[section_name])
2280
def get_mutable_section(self, section_name=None):
2281
# We need a loaded store
2284
except errors.NoSuchFile:
2285
# The file doesn't exist, let's pretend it was empty
2286
self._load_from_string('')
2287
if section_name is None:
2288
section = self._config_obj
2290
section = self._config_obj.setdefault(section_name, {})
2291
return self.mutable_section_class(section_name, section)
2294
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
2295
# unlockable stores for use with objects that can already ensure the locking
2296
# (think branches). If different stores (not based on ConfigObj) are created,
2297
# they may face the same issue.
2300
class LockableIniFileStore(IniFileStore):
2301
"""A ConfigObjStore using locks on save to ensure store integrity."""
2303
def __init__(self, transport, file_name, lock_dir_name=None):
2304
"""A config Store using ConfigObj for storage.
2306
:param transport: The transport object where the config file is located.
2308
:param file_name: The config file basename in the transport directory.
2310
if lock_dir_name is None:
2311
lock_dir_name = 'lock'
2312
self.lock_dir_name = lock_dir_name
2313
super(LockableIniFileStore, self).__init__(transport, file_name)
2314
self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
2316
def lock_write(self, token=None):
2317
"""Takes a write lock in the directory containing the config file.
2319
If the directory doesn't exist it is created.
2321
# FIXME: This doesn't check the ownership of the created directories as
2322
# ensure_config_dir_exists does. It should if the transport is local
2323
# -- vila 2011-04-06
2324
self.transport.create_prefix()
2325
return self._lock.lock_write(token)
2330
def break_lock(self):
2331
self._lock.break_lock()
2335
super(LockableIniFileStore, self).save()
2338
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
2339
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
2340
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
2342
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
2343
# functions or a registry will make it easier and clearer for tests, focusing
2344
# on the relevant parts of the API that needs testing -- vila 20110503 (based
2345
# on a poolie's remark)
2346
class GlobalStore(LockableIniFileStore):
2348
def __init__(self, possible_transports=None):
2349
t = transport.get_transport(config_dir(),
2350
possible_transports=possible_transports)
2351
super(GlobalStore, self).__init__(t, 'bazaar.conf')
2354
class LocationStore(LockableIniFileStore):
2356
def __init__(self, possible_transports=None):
2357
t = transport.get_transport(config_dir(),
2358
possible_transports=possible_transports)
2359
super(LocationStore, self).__init__(t, 'locations.conf')
2362
class BranchStore(IniFileStore):
2364
def __init__(self, branch):
2365
super(BranchStore, self).__init__(branch.control_transport,
2368
class SectionMatcher(object):
2369
"""Select sections into a given Store.
2371
This intended to be used to postpone getting an iterable of sections from a
2375
def __init__(self, store):
2378
def get_sections(self):
2379
# This is where we require loading the store so we can see all defined
2381
sections = self.store.get_sections()
2382
# Walk the revisions in the order provided
2387
def match(self, secion):
2388
raise NotImplementedError(self.match)
2391
class LocationSection(Section):
2393
def __init__(self, section, length, extra_path):
2394
super(LocationSection, self).__init__(section.id, section.options)
2395
self.length = length
2396
self.extra_path = extra_path
2398
def get(self, name, default=None):
2399
value = super(LocationSection, self).get(name, default)
2400
if value is not None:
2401
policy_name = self.get(name + ':policy', None)
2402
policy = _policy_value.get(policy_name, POLICY_NONE)
2403
if policy == POLICY_APPENDPATH:
2404
value = urlutils.join(value, self.extra_path)
2408
class LocationMatcher(SectionMatcher):
2410
def __init__(self, store, location):
2411
super(LocationMatcher, self).__init__(store)
2412
self.location = location
2414
def get_sections(self):
2415
# Override the default implementation as we want to change the order
2417
# The following is a bit hackish but ensures compatibility with
2418
# LocationConfig by reusing the same code
2419
sections = list(self.store.get_sections())
2420
filtered_sections = _iter_for_location_by_parts(
2421
[s.id for s in sections], self.location)
2422
iter_sections = iter(sections)
2423
matching_sections = []
2424
for section_id, extra_path, length in filtered_sections:
2425
# a section id is unique for a given store so it's safe to iterate
2427
section = iter_sections.next()
2428
if section_id == section.id:
2429
matching_sections.append(
2430
LocationSection(section, length, extra_path))
2431
# We want the longest (aka more specific) locations first
2432
sections = sorted(matching_sections,
2433
key=lambda section: (section.length, section.id),
2435
# Sections mentioning 'ignore_parents' restrict the selection
2436
for section in sections:
2437
# FIXME: We really want to use as_bool below -- vila 2011-04-07
2438
ignore = section.get('ignore_parents', None)
2439
if ignore is not None:
2440
ignore = ui.bool_from_string(ignore)
2443
# Finally, we have a valid section
2447
class Stack(object):
2448
"""A stack of configurations where an option can be defined"""
2450
def __init__(self, sections_def, store=None, mutable_section_name=None):
2451
"""Creates a stack of sections with an optional store for changes.
2453
:param sections_def: A list of Section or callables that returns an
2454
iterable of Section. This defines the Sections for the Stack and
2455
can be called repeatedly if needed.
2457
:param store: The optional Store where modifications will be
2458
recorded. If none is specified, no modifications can be done.
2460
:param mutable_section_name: The name of the MutableSection where
2461
changes are recorded. This requires the ``store`` parameter to be
2464
self.sections_def = sections_def
2466
self.mutable_section_name = mutable_section_name
2468
def get(self, name):
2469
"""Return the *first* option value found in the sections.
2471
This is where we guarantee that sections coming from Store are loaded
2472
lazily: the loading is delayed until we need to either check that an
2473
option exists or get its value, which in turn may require to discover
2474
in which sections it can be defined. Both of these (section and option
2475
existence) require loading the store (even partially).
2477
# FIXME: No caching of options nor sections yet -- vila 20110503
2479
# Ensuring lazy loading is achieved by delaying section matching until
2480
# it can be avoided anymore by using callables to describe (possibly
2481
# empty) section lists.
2482
for section_or_callable in self.sections_def:
2483
# Each section can expand to multiple ones when a callable is used
2484
if callable(section_or_callable):
2485
sections = section_or_callable()
2487
sections = [section_or_callable]
2488
for section in sections:
2489
value = section.get(name)
2490
if value is not None:
2492
# No definition was found
2495
def _get_mutable_section(self):
2496
"""Get the MutableSection for the Stack.
2498
This is where we guarantee that the mutable section is lazily loaded:
2499
this means we won't load the corresponding store before setting a value
2500
or deleting an option. In practice the store will often be loaded but
2501
this allows catching some programming errors.
2503
section = self.store.get_mutable_section(self.mutable_section_name)
2506
def set(self, name, value):
2507
"""Set a new value for the option."""
2508
section = self._get_mutable_section()
2509
section.set(name, value)
2511
def remove(self, name):
2512
"""Remove an existing option."""
2513
section = self._get_mutable_section()
2514
section.remove(name)
2517
# Mostly for debugging use
2518
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
2521
class cmd_config(commands.Command):
2522
__doc__ = """Display, set or remove a configuration option.
2524
Display the active value for a given option.
2526
If --all is specified, NAME is interpreted as a regular expression and all
2527
matching options are displayed mentioning their scope. The active value
2528
that bzr will take into account is the first one displayed for each option.
2530
If no NAME is given, --all .* is implied.
2532
Setting a value is achieved by using name=value without spaces. The value
2533
is set in the most relevant scope and can be checked by displaying the
2537
takes_args = ['name?']
2541
# FIXME: This should be a registry option so that plugins can register
2542
# their own config files (or not) -- vila 20101002
2543
commands.Option('scope', help='Reduce the scope to the specified'
2544
' configuration file',
2546
commands.Option('all',
2547
help='Display all the defined values for the matching options.',
2549
commands.Option('remove', help='Remove the option from'
2550
' the configuration file'),
2553
@commands.display_command
2554
def run(self, name=None, all=False, directory=None, scope=None,
2556
if directory is None:
2558
directory = urlutils.normalize_url(directory)
2560
raise errors.BzrError(
2561
'--all and --remove are mutually exclusive.')
2563
# Delete the option in the given scope
2564
self._remove_config_option(name, directory, scope)
2566
# Defaults to all options
2567
self._show_matching_options('.*', directory, scope)
2570
name, value = name.split('=', 1)
2572
# Display the option(s) value(s)
2574
self._show_matching_options(name, directory, scope)
2576
self._show_value(name, directory, scope)
2579
raise errors.BzrError(
2580
'Only one option can be set.')
2581
# Set the option value
2582
self._set_config_option(name, value, directory, scope)
2584
def _get_configs(self, directory, scope=None):
2585
"""Iterate the configurations specified by ``directory`` and ``scope``.
2587
:param directory: Where the configurations are derived from.
2589
:param scope: A specific config to start from.
2591
if scope is not None:
2592
if scope == 'bazaar':
2593
yield GlobalConfig()
2594
elif scope == 'locations':
2595
yield LocationConfig(directory)
2596
elif scope == 'branch':
2597
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2599
yield br.get_config()
2602
(_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
2604
yield br.get_config()
2605
except errors.NotBranchError:
2606
yield LocationConfig(directory)
2607
yield GlobalConfig()
2609
def _show_value(self, name, directory, scope):
2611
for c in self._get_configs(directory, scope):
2614
for (oname, value, section, conf_id, parser) in c._get_options():
2616
# Display only the first value and exit
2618
# FIXME: We need to use get_user_option to take policies
2619
# into account and we need to make sure the option exists
2620
# too (hence the two for loops), this needs a better API
2622
value = c.get_user_option(name)
2623
# Quote the value appropriately
2624
value = parser._quote(value)
2625
self.outf.write('%s\n' % (value,))
2629
raise errors.NoSuchConfigOption(name)
2631
def _show_matching_options(self, name, directory, scope):
2632
name = re.compile(name)
2633
# We want any error in the regexp to be raised *now* so we need to
2634
# avoid the delay introduced by the lazy regexp.
2635
name._compile_and_collapse()
2638
for c in self._get_configs(directory, scope):
2639
for (oname, value, section, conf_id, parser) in c._get_options():
2640
if name.search(oname):
2641
if cur_conf_id != conf_id:
2642
# Explain where the options are defined
2643
self.outf.write('%s:\n' % (conf_id,))
2644
cur_conf_id = conf_id
2646
if (section not in (None, 'DEFAULT')
2647
and cur_section != section):
2648
# Display the section if it's not the default (or only)
2650
self.outf.write(' [%s]\n' % (section,))
2651
cur_section = section
2652
self.outf.write(' %s = %s\n' % (oname, value))
2654
def _set_config_option(self, name, value, directory, scope):
2655
for conf in self._get_configs(directory, scope):
2656
conf.set_user_option(name, value)
2659
raise errors.NoSuchConfig(scope)
2661
def _remove_config_option(self, name, directory, scope):
2663
raise errors.BzrCommandError(
2664
'--remove expects an option to remove.')
2666
for conf in self._get_configs(directory, scope):
2667
for (section_name, section, conf_id) in conf._get_sections():
2668
if scope is not None and conf_id != scope:
2669
# Not the right configuration file
2672
if conf_id != conf.config_id():
2673
conf = self._get_configs(directory, conf_id).next()
2674
# We use the first section in the first config where the
2675
# option is defined to remove it
2676
conf.remove_user_option(name, section_name)
2681
raise errors.NoSuchConfig(scope)
2683
raise errors.NoSuchConfigOption(name)