133
class ConfigObj(configobj.ConfigObj):
135
def __init__(self, infile=None, **kwargs):
136
# We define our own interpolation mechanism
137
super(ConfigObj, self).__init__(infile=infile,
142
def get_bool(self, section, key):
143
return self[section].as_bool(key)
145
def get_value(self, section, name):
146
# Try [] for the old DEFAULT section.
147
if section == "DEFAULT":
152
return self[section][name]
132
def ConfigObj(*args, **kwargs):
134
if _ConfigObj is None:
135
class ConfigObj(configobj.ConfigObj):
137
def get_bool(self, section, key):
138
return self[section].as_bool(key)
140
def get_value(self, section, name):
141
# Try [] for the old DEFAULT section.
142
if section == "DEFAULT":
147
return self[section][name]
148
_ConfigObj = ConfigObj
149
return _ConfigObj(*args, **kwargs)
156
152
class Config(object):
192
188
def _get_signing_policy(self):
193
189
"""Template method to override signature creation policy."""
197
def interpolate(self, string, env=None):
198
"""Interpolate the string in the configuration context.
200
:param string: The string to interpolate
202
:param env: An option dict defining additional configuration options or
203
overriding existing ones.
205
:returns: The interpolated string.
207
return self._interpolate_string(string, env)
209
def _interpolate_list(self, slist, env=None, _ref_stack=None):
210
"""Interpolate a list of strings in the configuration context.
212
:param slist: A list of strings.
214
:param env: An option dict defining additional configuration options or
215
overriding existing ones.
217
:param _ref_stack: Private list containing the options being
218
interpolated to detect loops.
220
:returns: The flatten list of interpolated strings.
222
# interpolate each value separately flattening lists
225
value = self._interpolate_string(s, env, _ref_stack)
226
if isinstance(value, list):
232
def _interpolate_string(self, string, env=None, _ref_stack=None):
233
"""Interpolate the string in the configuration context.
235
:param string: The string to interpolate
237
:param env: An option dict defining additional configuration options or
238
overriding existing ones.
240
:param _ref_stack: Private list containing the options being
241
interpolated to detect loops.
243
:returns: The interpolated string.
246
# Not much to interpolate there
248
if _ref_stack is None:
249
# What references are currently resolved (to detect loops)
251
if self.option_ref_re is None:
252
# We want to match the most embedded reference first (i.e. for
253
# '{{foo}}' we will get '{foo}',
254
# for '{bar{baz}}' we will get '{baz}'
255
self.option_ref_re = re.compile('({[^{}]+})')
257
# We need to iterate until no more refs appear ({{foo}} will need two
258
# iterations for example).
261
raw_chunks = self.option_ref_re.split(result)
263
import pdb; pdb.set_trace()
264
if len(raw_chunks) == 1:
265
# Shorcut the trivial case: no refs
269
# Split will isolate refs so that every other chunk is a ref
271
for chunk in raw_chunks:
274
# Keep only non-empty strings
279
if name in _ref_stack:
280
raise errors.InterpolationLoop(string, _ref_stack)
281
_ref_stack.append(name)
282
value = self._interpolate_option(name, env, _ref_stack)
284
raise errors.InterpolationUnknownOption(name, string)
285
if isinstance(value, list):
293
# Once a list appears as the result of an interpolation, all
294
# callers will get a list result. This allows a consistent
295
# behavior even when some options in the interpolation chain
296
# may be seen defined as strings even if their interpolated
298
return self._interpolate_list(chunks, env, _ref_stack)
300
result = ''.join(chunks)
303
def _interpolate_option(self, name, env, _ref_stack):
304
if env is not None and name in env:
305
# Special case, values provided in env takes precedence over
309
# FIXME: This is a limited implementation, what we really need
310
# is a way to query the bzr config for the value of an option,
311
# respecting the scope rules -- vila 20101222
312
value = self.get_user_option(name, interpolate=False)
313
if isinstance(value, list):
314
value = self._interpolate_list(value, env, _ref_stack)
316
value = self._interpolate_string(value, env, _ref_stack)
319
191
def _get_user_option(self, option_name):
320
192
"""Template method to provide a user option."""
323
def get_user_option(self, option_name, interpolate=True):
195
def get_user_option(self, option_name):
324
196
"""Get a generic option - no special process, no default."""
325
value = self._get_user_option(option_name)
327
if isinstance(value, list):
328
value = self._interpolate_list(value)
329
elif isinstance(value, dict):
330
trace.warning('Cannot expand "%s":'
331
' Dicts do not support option expansion'
334
value = self._interpolate_string(value)
197
return self._get_user_option(option_name)
337
199
def get_user_option_as_bool(self, option_name):
338
200
"""Get a generic option as a boolean - no special process, no default.
499
def get_merge_tools(self):
501
for (oname, value, section, conf_id, parser) in self._get_options():
502
if oname.startswith('bzr.mergetool.'):
503
tool_name = oname[len('bzr.mergetool.'):]
504
tools[tool_name] = value
505
trace.mutter('loaded merge tools: %r' % tools)
508
def find_merge_tool(self, name):
509
# We fake a defaults mechanism here by checking if the given name can
510
# be found in the known_merge_tools if it's not found in the config.
511
# This should be done through the proposed config defaults mechanism
512
# when it becomes available in the future.
513
command_line = (self.get_user_option('bzr.mergetool.%s' % name,
515
or mergetools.known_merge_tools.get(name, None))
519
361
class IniBasedConfig(Config):
520
362
"""A configuration policy that draws from ini files."""
1286
1121
def config_dir():
1287
1122
"""Return per-user configuration directory.
1289
By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1290
and Linux. On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1291
that will be used instead.
1124
By default this is ~/.bazaar/
1293
1126
TODO: Global option --config-dir to override this.
1295
1128
base = os.environ.get('BZR_HOME', None)
1296
1129
if sys.platform == 'win32':
1297
# environ variables on Windows are in user encoding/mbcs. So decode
1299
if base is not None:
1300
base = base.decode('mbcs')
1301
1130
if base is None:
1302
1131
base = win32utils.get_appdata_location_unicode()
1303
1132
if base is None:
1304
1133
base = os.environ.get('HOME', None)
1305
if base is not None:
1306
base = base.decode('mbcs')
1307
1134
if base is None:
1308
1135
raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1309
1136
' or HOME set')
1310
1137
return osutils.pathjoin(base, 'bazaar', '2.0')
1311
elif sys.platform == 'darwin':
1313
# this takes into account $HOME
1314
base = os.path.expanduser("~")
1315
return osutils.pathjoin(base, '.bazaar')
1317
1139
if base is None:
1319
xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1321
xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1322
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1323
if osutils.isdir(xdg_dir):
1325
"Using configuration in XDG directory %s." % xdg_dir)
1328
1140
base = os.path.expanduser("~")
1329
1141
return osutils.pathjoin(base, ".bazaar")
2050
1862
for c in self._get_configs(directory, scope):
2053
for (oname, value, section, conf_id, parser) in c._get_options():
1865
for (oname, value, section, conf_id) in c._get_options():
2054
1866
if name == oname:
2055
1867
# Display only the first value and exit
2057
# FIXME: We need to use get_user_option to take policies
2058
# into account and we need to make sure the option exists
2059
# too (hence the two for loops), this needs a better API
2061
value = c.get_user_option(name)
2062
# Quote the value appropriately
2063
value = parser._quote(value)
2064
self.outf.write('%s\n' % (value,))
1868
self.outf.write('%s\n' % (value))
2065
1869
displayed = True
2067
1871
if not displayed:
2073
1877
# avoid the delay introduced by the lazy regexp.
2074
1878
name._compile_and_collapse()
2075
1879
cur_conf_id = None
2077
1880
for c in self._get_configs(directory, scope):
2078
for (oname, value, section, conf_id, parser) in c._get_options():
1881
for (oname, value, section, conf_id) in c._get_options():
2079
1882
if name.search(oname):
2080
1883
if cur_conf_id != conf_id:
2081
1884
# Explain where the options are defined
2082
1885
self.outf.write('%s:\n' % (conf_id,))
2083
1886
cur_conf_id = conf_id
2085
if (section not in (None, 'DEFAULT')
2086
and cur_section != section):
2087
# Display the section if it's not the default (or only)
2089
self.outf.write(' [%s]\n' % (section,))
2090
cur_section = section
2091
1887
self.outf.write(' %s = %s\n' % (oname, value))
2093
1889
def _set_config_option(self, name, value, directory, scope):