55
55
turns on create_signatures.
56
56
create_signatures - this option controls whether bzr will always create
57
57
gpg signatures or not on commits. There is an unused
58
option which in future is expected to work if
58
option which in future is expected to work if
59
59
branch settings require signatures.
60
60
log_format - this option sets the default log format. Possible values are
61
61
long, short, line, or a plugin can register new formats.
196
197
return self[section][name]
199
# FIXME: Until we can guarantee that each config file is loaded once and
200
# only once for a given bzrlib session, we don't want to re-read the file every
201
# time we query for an option so we cache the value (bad ! watch out for tests
202
# needing to restore the proper value). -- vila 20110219
203
_expand_default_value = None
204
def _get_expand_default_value():
205
global _expand_default_value
206
if _expand_default_value is not None:
207
return _expand_default_value
208
conf = GlobalConfig()
209
# Note that we must not use None for the expand value below or we'll run
210
# into infinite recursion. Using False really would be quite silly ;)
211
expand = conf.get_user_option_as_bool('bzr.config.expand', expand=True)
213
# This is an opt-in feature, you *really* need to clearly say you want
216
_expand_default_value = expand
220
200
class Config(object):
221
201
"""A configuration policy - what username, editor, gpg needs etc."""
227
207
"""Returns a unique ID for the config."""
228
208
raise NotImplementedError(self.config_id)
230
@deprecated_method(deprecated_in((2, 4, 0)))
231
def get_editor(self):
232
"""Get the users pop up editor."""
233
raise NotImplementedError
235
210
def get_change_editor(self, old_tree, new_tree):
236
211
from bzrlib import diff
237
212
cmd = self._get_change_editor()
240
215
return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
243
def get_mail_client(self):
244
"""Get a mail client to use"""
245
selected_client = self.get_user_option('mail_client')
246
_registry = mail_client.mail_client_registry
248
mail_client_class = _registry.get(selected_client)
250
raise errors.UnknownMailClient(selected_client)
251
return mail_client_class(self)
253
218
def _get_signature_checking(self):
254
219
"""Template method to override signature checking policy."""
384
349
"""Template method to provide a user option."""
387
def get_user_option(self, option_name, expand=None):
352
def get_user_option(self, option_name, expand=True):
388
353
"""Get a generic option - no special process, no default.
390
355
:param option_name: The queried option.
648
611
for (oname, value, section, conf_id, parser) in self._get_options():
649
612
if oname.startswith('bzr.mergetool.'):
650
613
tool_name = oname[len('bzr.mergetool.'):]
651
tools[tool_name] = self.get_user_option(oname)
614
tools[tool_name] = self.get_user_option(oname, False)
652
615
trace.mutter('loaded merge tools: %r' % tools)
1090
1053
conf._create_from_string(str_or_unicode, save)
1093
@deprecated_method(deprecated_in((2, 4, 0)))
1094
def get_editor(self):
1095
return self._get_user_option('editor')
1097
1056
@needs_write_lock
1098
1057
def set_user_option(self, option, value):
1099
1058
"""Save option and its value in the configuration."""
1533
1494
TODO: Global option --config-dir to override this.
1535
base = os.environ.get('BZR_HOME', None)
1496
base = osutils.path_from_environ('BZR_HOME')
1536
1497
if sys.platform == 'win32':
1537
# environ variables on Windows are in user encoding/mbcs. So decode
1539
if base is not None:
1540
base = base.decode('mbcs')
1542
base = win32utils.get_appdata_location_unicode()
1544
base = os.environ.get('HOME', None)
1545
if base is not None:
1546
base = base.decode('mbcs')
1548
raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1499
base = win32utils.get_appdata_location()
1501
base = win32utils.get_home_location()
1502
# GZ 2012-02-01: Really the two level subdirs only make sense inside
1503
# APPDATA, but hard to move. See bug 348640 for more.
1550
1504
return osutils.pathjoin(base, 'bazaar', '2.0')
1552
if base is not None:
1553
base = base.decode(osutils._fs_enc)
1554
if sys.platform == 'darwin':
1556
# this takes into account $HOME
1557
base = os.path.expanduser("~")
1558
return osutils.pathjoin(base, '.bazaar')
1561
xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1506
# GZ 2012-02-01: What should OSX use instead of XDG if anything?
1507
if sys.platform != 'darwin':
1508
xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1562
1509
if xdg_dir is None:
1563
xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1510
xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1564
1511
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1565
1512
if osutils.isdir(xdg_dir):
1567
1514
"Using configuration in XDG directory %s." % xdg_dir)
1569
base = os.path.expanduser("~")
1570
return osutils.pathjoin(base, ".bazaar")
1516
base = osutils._get_home_dir()
1517
return osutils.pathjoin(base, ".bazaar")
1573
1520
def config_filename():
2186
2133
credential_store_registry.default_key = 'plain'
2136
class Base64CredentialStore(CredentialStore):
2137
__doc__ = """Base64 credential store for the authentication.conf file"""
2139
def decode_password(self, credentials):
2140
"""See CredentialStore.decode_password."""
2141
# GZ 2012-07-28: Will raise binascii.Error if password is not base64,
2142
# should probably propogate as something more useful.
2143
return base64.decodestring(credentials['password'])
2145
credential_store_registry.register('base64', Base64CredentialStore,
2146
help=Base64CredentialStore.__doc__)
2189
2149
class BzrDirConfig(object):
2191
2151
def __init__(self, bzrdir):
2198
2158
It may be set to a location, or None.
2200
This policy affects all branches contained by this bzrdir, except for
2201
those under repositories.
2160
This policy affects all branches contained by this control dir, except
2161
for those under repositories.
2203
2163
if self._config is None:
2204
2164
raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
2453
2413
value = self.default()
2454
2414
if not isinstance(value, unicode):
2455
2415
raise AssertionError(
2456
'Callable default values should be unicode')
2416
"Callable default value for '%s' should be unicode"
2458
2419
value = self.default
2422
def get_help_topic(self):
2461
2425
def get_help_text(self, additional_see_also=None, plain=True):
2462
2426
result = self.help
2463
2427
from bzrlib import help_topics
2684
2648
Whether revisions associated with tags should be fetched.
2650
option_registry.register_lazy(
2651
'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
2686
2652
option_registry.register(
2687
2653
Option('bzr.workingtree.worth_saving_limit', default=10,
2688
2654
from_unicode=int_from_store, invalid='warning',
2696
2662
a file has been touched.
2698
2664
option_registry.register(
2665
Option('bugtracker', default=None,
2667
Default bug tracker to use.
2669
This bug tracker will be used for example when marking bugs
2670
as fixed using ``bzr commit --fixes``, if no explicit
2671
bug tracker was specified.
2673
option_registry.register(
2699
2674
Option('check_signatures', default=CHECK_IF_POSSIBLE,
2700
2675
from_unicode=signature_policy_from_unicode,
3094
3069
# get_mutable_section() call below.
3096
3071
# Apply the changes from the preserved dirty sections
3097
for dirty in dirty_sections:
3098
clean = self.get_mutable_section(dirty.id)
3072
for section_id, dirty in dirty_sections.iteritems():
3073
clean = self.get_mutable_section(section_id)
3099
3074
clean.apply_changes(dirty, self)
3100
3075
# Everything is clean now
3101
self.dirty_sections = []
3076
self.dirty_sections = {}
3103
3078
def save_changes(self):
3104
3079
"""Saves the Store to persistent storage if changes occurred.
3280
3254
except errors.NoSuchFile:
3281
3255
# The file doesn't exist, let's pretend it was empty
3282
3256
self._load_from_string('')
3257
if section_id in self.dirty_sections:
3258
# We already created a mutable section for this id
3259
return self.dirty_sections[section_id]
3283
3260
if section_id is None:
3284
3261
section = self._config_obj
3286
3263
section = self._config_obj.setdefault(section_id, {})
3287
3264
mutable_section = self.mutable_section_class(section_id, section)
3288
3265
# All mutable sections can become dirty
3289
self.dirty_sections.append(mutable_section)
3266
self.dirty_sections[section_id] = mutable_section
3290
3267
return mutable_section
3292
3269
def quote(self, value):
3431
3421
self.branch = branch
3432
3422
self.id = 'branch'
3434
def lock_write(self, token=None):
3435
return self.branch.lock_write(token)
3438
return self.branch.unlock()
3442
# We need to be able to override the undecorated implementation
3443
self.save_without_locking()
3445
def save_without_locking(self):
3446
super(BranchStore, self).save()
3449
3425
class ControlStore(LockableIniFileStore):
3497
3473
class LocationSection(Section):
3499
def __init__(self, section, extra_path):
3475
def __init__(self, section, extra_path, branch_name=None):
3500
3476
super(LocationSection, self).__init__(section.id, section.options)
3501
3477
self.extra_path = extra_path
3478
if branch_name is None:
3502
3480
self.locals = {'relpath': extra_path,
3503
'basename': urlutils.basename(extra_path)}
3481
'basename': urlutils.basename(extra_path),
3482
'branchname': branch_name}
3505
3484
def get(self, name, default=None, expand=True):
3506
3485
value = super(LocationSection, self).get(name, default)
3577
3556
def __init__(self, store, location):
3578
3557
super(LocationMatcher, self).__init__(store)
3558
url, params = urlutils.split_segment_parameters(location)
3579
3559
if location.startswith('file://'):
3580
3560
location = urlutils.local_path_from_url(location)
3581
3561
self.location = location
3562
branch_name = params.get('branch')
3563
if branch_name is None:
3564
self.branch_name = urlutils.basename(self.location)
3566
self.branch_name = urlutils.unescape(branch_name)
3583
3568
def _get_matching_sections(self):
3584
3569
"""Get all sections matching ``location``."""
3611
3596
section = iter_all_sections.next()
3612
3597
if section_id == section.id:
3613
matching_sections.append(
3614
(length, LocationSection(section, extra_path)))
3598
section = LocationSection(section, extra_path,
3600
matching_sections.append((length, section))
3616
3602
return matching_sections
3672
3662
self.store = store
3673
3663
self.mutable_section_id = mutable_section_id
3675
def get(self, name, expand=None):
3665
def iter_sections(self):
3666
"""Iterate all the defined sections."""
3667
# Ensuring lazy loading is achieved by delaying section matching (which
3668
# implies querying the persistent storage) until it can't be avoided
3669
# anymore by using callables to describe (possibly empty) section
3671
for sections in self.sections_def:
3672
for store, section in sections():
3673
yield store, section
3675
def get(self, name, expand=True, convert=True):
3676
3676
"""Return the *first* option value found in the sections.
3678
3678
This is where we guarantee that sections coming from Store are loaded
3686
3686
:param expand: Whether options references should be expanded.
3688
:param convert: Whether the option value should be converted from
3689
unicode (do nothing for non-registered options).
3688
3691
:returns: The value of the option.
3690
3693
# FIXME: No caching of options nor sections yet -- vila 20110503
3692
expand = _get_expand_default_value()
3694
3695
found_store = None # Where the option value has been found
3695
3696
# If the option is registered, it may provide additional info about
3723
3724
value = opt.get_override()
3724
3725
value = expand_and_convert(value)
3725
3726
if value is None:
3726
# Ensuring lazy loading is achieved by delaying section matching
3727
# (which implies querying the persistent storage) until it can't be
3728
# avoided anymore by using callables to describe (possibly empty)
3730
for sections in self.sections_def:
3731
for store, section in sections():
3732
value = section.get(name)
3733
if value is not None:
3727
for store, section in self.iter_sections():
3728
value = section.get(name)
3736
3729
if value is not None:
3738
3732
value = expand_and_convert(value)
3739
3733
if opt is not None and value is None:
3840
3834
return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3842
3836
def _get_overrides(self):
3843
# Hack around library_state.initialize never called
3837
# FIXME: Hack around library_state.initialize never called
3844
3838
if bzrlib.global_state is not None:
3845
3839
return bzrlib.global_state.cmdline_overrides.get_sections()
3842
def get_shared_store(self, store, state=None):
3843
"""Get a known shared store.
3845
Store urls uniquely identify them and are used to ensure a single copy
3846
is shared across all users.
3848
:param store: The store known to the caller.
3850
:param state: The library state where the known stores are kept.
3852
:returns: The store received if it's not a known one, an already known
3856
state = bzrlib.global_state
3858
global _shared_stores_at_exit_installed
3859
stores = _shared_stores
3860
def save_config_changes():
3861
for k, store in stores.iteritems():
3862
store.save_changes()
3863
if not _shared_stores_at_exit_installed:
3864
# FIXME: Ugly hack waiting for library_state to always be
3865
# available. -- vila 20120731
3867
atexit.register(save_config_changes)
3868
_shared_stores_at_exit_installed = True
3870
stores = state.config_stores
3871
url = store.external_url()
3849
3879
class MemoryStack(Stack):
3850
3880
"""A configuration stack defined from a string.
3916
3946
def __init__(self):
3917
gstore = GlobalStore()
3947
gstore = self.get_shared_store(GlobalStore())
3918
3948
super(GlobalStack, self).__init__(
3919
3949
[self._get_overrides,
3920
3950
NameMatcher(gstore, 'DEFAULT').get_sections],
3921
3951
gstore, mutable_section_id='DEFAULT')
3924
class LocationStack(_CompatibleStack):
3954
class LocationStack(Stack):
3925
3955
"""Per-location options falling back to global options stack.
3943
3973
"""Make a new stack for a location and global configuration.
3945
3975
:param location: A URL prefix to """
3946
lstore = LocationStore()
3976
lstore = self.get_shared_store(LocationStore())
3947
3977
if location.startswith('file://'):
3948
3978
location = urlutils.local_path_from_url(location)
3949
gstore = GlobalStore()
3979
gstore = self.get_shared_store(GlobalStore())
3950
3980
super(LocationStack, self).__init__(
3951
3981
[self._get_overrides,
3952
3982
LocationMatcher(lstore, location).get_sections,
3976
4006
def __init__(self, branch):
3977
lstore = LocationStore()
4007
lstore = self.get_shared_store(LocationStore())
3978
4008
bstore = branch._get_config_store()
3979
gstore = GlobalStore()
4009
gstore = self.get_shared_store(GlobalStore())
3980
4010
super(BranchStack, self).__init__(
3981
4011
[self._get_overrides,
3982
4012
LocationMatcher(lstore, branch.base).get_sections,
3986
4016
self.branch = branch
3989
class RemoteControlStack(_CompatibleStack):
4018
def lock_write(self, token=None):
4019
return self.branch.lock_write(token)
4022
return self.branch.unlock()
4025
def set(self, name, value):
4026
super(BranchStack, self).set(name, value)
4027
# Unlocking the branch will trigger a store.save_changes() so the last
4028
# unlock saves all the changes.
4031
def remove(self, name):
4032
super(BranchStack, self).remove(name)
4033
# Unlocking the branch will trigger a store.save_changes() so the last
4034
# unlock saves all the changes.
4037
class RemoteControlStack(Stack):
3990
4038
"""Remote control-only options stack."""
3992
4040
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
4016
4064
self.branch = branch
4019
# Use a an empty dict to initialize an empty configobj avoiding all
4020
# parsing and encoding checks
4021
_quoting_config = configobj.ConfigObj(
4022
{}, encoding='utf-8', interpolation=False, list_values=True)
4066
def lock_write(self, token=None):
4067
return self.branch.lock_write(token)
4070
return self.branch.unlock()
4073
def set(self, name, value):
4074
super(BranchOnlyStack, self).set(name, value)
4075
# Force a write to persistent storage
4076
self.store.save_changes()
4079
def remove(self, name):
4080
super(BranchOnlyStack, self).remove(name)
4081
# Force a write to persistent storage
4082
self.store.save_changes()
4024
4085
class cmd_config(commands.Command):
4025
4086
__doc__ = """Display, set or remove a configuration option.
4087
4149
# Set the option value
4088
4150
self._set_config_option(name, value, directory, scope)
4090
def _get_stack(self, directory, scope=None):
4152
def _get_stack(self, directory, scope=None, write_access=False):
4091
4153
"""Get the configuration stack specified by ``directory`` and ``scope``.
4093
4155
:param directory: Where the configurations are derived from.
4095
4157
:param scope: A specific config to start from.
4159
:param write_access: Whether a write access to the stack will be
4097
4162
# FIXME: scope should allow access to plugin-specific stacks (even
4098
4163
# reduced to the plugin-specific store), related to
4114
4181
controldir.ControlDir.open_containing_tree_or_branch(
4184
self.add_cleanup(br.lock_write().unlock)
4116
4185
return br.get_config_stack()
4117
4186
except errors.NotBranchError:
4118
4187
return LocationStack(directory)
4189
def _quote_multiline(self, value):
4191
value = '"""' + value + '"""'
4120
4194
def _show_value(self, name, directory, scope):
4121
4195
conf = self._get_stack(directory, scope)
4122
value = conf.get(name, expand=True)
4196
value = conf.get(name, expand=True, convert=False)
4123
4197
if value is not None:
4124
4198
# Quote the value appropriately
4125
value = _quoting_config._quote(value)
4199
value = self._quote_multiline(value)
4126
4200
self.outf.write('%s\n' % (value,))
4128
4202
raise errors.NoSuchConfigOption(name)
4136
4210
cur_store_id = None
4137
4211
cur_section = None
4138
4212
conf = self._get_stack(directory, scope)
4139
for sections in conf.sections_def:
4140
for store, section in sections():
4141
for oname in section.iter_option_names():
4142
if name.search(oname):
4143
if cur_store_id != store.id:
4144
# Explain where the options are defined
4145
self.outf.write('%s:\n' % (store.id,))
4146
cur_store_id = store.id
4148
if (section.id is not None
4149
and cur_section != section.id):
4150
# Display the section id as it appears in the store
4151
# (None doesn't appear by definition)
4152
self.outf.write(' [%s]\n' % (section.id,))
4153
cur_section = section.id
4154
value = section.get(oname, expand=False)
4155
# Since we don't use the stack, we need to restore a
4158
opt = option_registry.get(oname)
4159
value = opt.convert_from_unicode(store, value)
4161
value = store.unquote(value)
4162
value = _quoting_config._quote(value)
4163
self.outf.write(' %s = %s\n' % (oname, value))
4213
for store, section in conf.iter_sections():
4214
for oname in section.iter_option_names():
4215
if name.search(oname):
4216
if cur_store_id != store.id:
4217
# Explain where the options are defined
4218
self.outf.write('%s:\n' % (store.id,))
4219
cur_store_id = store.id
4221
if (section.id is not None and cur_section != section.id):
4222
# Display the section id as it appears in the store
4223
# (None doesn't appear by definition)
4224
self.outf.write(' [%s]\n' % (section.id,))
4225
cur_section = section.id
4226
value = section.get(oname, expand=False)
4227
# Quote the value appropriately
4228
value = self._quote_multiline(value)
4229
self.outf.write(' %s = %s\n' % (oname, value))
4165
4231
def _set_config_option(self, name, value, directory, scope):
4166
conf = self._get_stack(directory, scope)
4232
conf = self._get_stack(directory, scope, write_access=True)
4167
4233
conf.set(name, value)
4169
4235
def _remove_config_option(self, name, directory, scope):
4170
4236
if name is None:
4171
4237
raise errors.BzrCommandError(
4172
4238
'--remove expects an option to remove.')
4173
conf = self._get_stack(directory, scope)
4239
conf = self._get_stack(directory, scope, write_access=True)
4175
4241
conf.remove(name)
4176
4242
except KeyError: