1648
1652
raise errors.NoWhoami()
1651
def email_from_store(unicode_str):
1652
"""Unlike other env vars, BZR_EMAIL takes precedence over config settings.
1654
Whatever comes from a config file is then overridden.
1656
value = os.environ.get('BZR_EMAIL')
1658
return value.decode(osutils.get_user_encoding())
1662
1655
def _auto_user_id():
1663
1656
"""Calculate automatic user identification.
2339
2332
encoutered, in which config files it can be stored.
2342
def __init__(self, name, default=None, default_from_env=None,
2343
help=None, from_unicode=None, invalid=None):
2335
def __init__(self, name, override_from_env=None,
2336
default=None, default_from_env=None,
2337
help=None, from_unicode=None, invalid=None, unquote=True):
2344
2338
"""Build an option definition.
2346
2340
:param name: the name used to refer to the option.
2342
:param override_from_env: A list of environment variables which can
2343
provide override any configuration setting.
2348
2345
:param default: the default value to use when none exist in the config
2349
2346
stores. This is either a string that ``from_unicode`` will convert
2350
2347
into the proper type, a callable returning a unicode string so that
2368
2365
TypeError. Accepted values are: None (ignore invalid values),
2369
2366
'warning' (emit a warning), 'error' (emit an error message and
2369
:param unquote: should the unicode value be unquoted before conversion.
2370
This should be used only when the store providing the values cannot
2371
safely unquote them (see http://pad.lv/906897). It is provided so
2372
daughter classes can handle the quoting themselves.
2374
if override_from_env is None:
2375
override_from_env = []
2372
2376
if default_from_env is None:
2373
2377
default_from_env = []
2374
2378
self.name = name
2379
self.override_from_env = override_from_env
2375
2380
# Convert the default value to a unicode string so all values are
2376
2381
# strings internally before conversion (via from_unicode) is attempted.
2377
2382
if default is None:
2394
2399
self.default_from_env = default_from_env
2395
2400
self.help = help
2396
2401
self.from_unicode = from_unicode
2402
self.unquote = unquote
2397
2403
if invalid and invalid not in ('warning', 'error'):
2398
2404
raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2399
2405
self.invalid = invalid
2401
def convert_from_unicode(self, unicode_value):
2407
def convert_from_unicode(self, store, unicode_value):
2408
if self.unquote and store is not None and unicode_value is not None:
2409
unicode_value = store.unquote(unicode_value)
2402
2410
if self.from_unicode is None or unicode_value is None:
2403
2411
# Don't convert or nothing to convert
2404
2412
return unicode_value
2455
2474
return int(unicode_str)
2477
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2479
def int_SI_from_store(unicode_str):
2480
"""Convert a human readable size in SI units, e.g 10MB into an integer.
2482
Accepted suffixes are K,M,G. It is case-insensitive and may be followed
2483
by a trailing b (i.e. Kb, MB). This is intended to be practical and not
2486
:return Integer, expanded to its base-10 value if a proper SI unit is
2487
found, None otherwise.
2489
regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
2490
p = re.compile(regexp, re.IGNORECASE)
2491
m = p.match(unicode_str)
2494
val, _, unit = m.groups()
2498
coeff = _unit_suffixes[unit.upper()]
2500
raise ValueError(gettext('{0} is not an SI unit.').format(unit))
2458
2505
def float_from_store(unicode_str):
2459
2506
return float(unicode_str)
2465
2512
{}, encoding='utf-8', list_values=True, interpolation=False)
2468
def list_from_store(unicode_str):
2469
if not isinstance(unicode_str, basestring):
2471
# Now inject our string directly as unicode. All callers got their value
2472
# from configobj, so values that need to be quoted are already properly
2474
_list_converter_config.reset()
2475
_list_converter_config._parse([u"list=%s" % (unicode_str,)])
2476
maybe_list = _list_converter_config['list']
2477
# ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2478
if isinstance(maybe_list, basestring):
2480
# A single value, most probably the user forgot (or didn't care to
2481
# add) the final ','
2515
class ListOption(Option):
2517
def __init__(self, name, default=None, default_from_env=None,
2518
help=None, invalid=None):
2519
"""A list Option definition.
2521
This overrides the base class so the conversion from a unicode string
2522
can take quoting into account.
2524
super(ListOption, self).__init__(
2525
name, default=default, default_from_env=default_from_env,
2526
from_unicode=self.from_unicode, help=help,
2527
invalid=invalid, unquote=False)
2529
def from_unicode(self, unicode_str):
2530
if not isinstance(unicode_str, basestring):
2532
# Now inject our string directly as unicode. All callers got their
2533
# value from configobj, so values that need to be quoted are already
2535
_list_converter_config.reset()
2536
_list_converter_config._parse([u"list=%s" % (unicode_str,)])
2537
maybe_list = _list_converter_config['list']
2538
if isinstance(maybe_list, basestring):
2540
# A single value, most probably the user forgot (or didn't care
2541
# to add) the final ','
2544
# The empty string, convert to empty list
2484
# The empty string, convert to empty list
2487
# We rely on ConfigObj providing us with a list already
2547
# We rely on ConfigObj providing us with a list already
2492
2552
class OptionRegistry(registry.Registry):
2542
2602
existing mainline of the branch.
2544
2604
option_registry.register(
2545
Option('acceptable_keys',
2546
default=None, from_unicode=list_from_store,
2605
ListOption('acceptable_keys',
2548
2608
List of GPG key patterns which are acceptable for verification.
2550
2610
option_registry.register(
2611
Option('add.maximum_file_size',
2612
default=u'20MB', from_unicode=int_SI_from_store,
2614
Size above which files should be added manually.
2616
Files below this size are added automatically when using ``bzr add`` without
2619
A negative value means disable the size check.
2621
option_registry.register(
2623
default=None, from_unicode=bool_from_store,
2625
Is the branch bound to ``bound_location``.
2627
If set to "True", the branch should act as a checkout, and push each commit to
2628
the bound_location. This option is normally set by ``bind``/``unbind``.
2630
See also: bound_location.
2632
option_registry.register(
2633
Option('bound_location',
2636
The location that commits should go to when acting as a checkout.
2638
This option is normally set by ``bind``.
2642
option_registry.register(
2643
Option('branch.fetch_tags', default=False, from_unicode=bool_from_store,
2645
Whether revisions associated with tags should be fetched.
2647
option_registry.register(
2551
2648
Option('bzr.workingtree.worth_saving_limit', default=10,
2552
2649
from_unicode=int_from_store, invalid='warning',
2593
2690
should not be lost if the machine crashes. See also repository.fdatasync.
2595
2692
option_registry.register(
2596
Option('debug_flags', default=[], from_unicode=list_from_store,
2693
ListOption('debug_flags', default=[],
2597
2694
help='Debug flags to activate.'))
2598
2695
option_registry.register(
2599
2696
Option('default_format', default='2a',
2612
2709
Option('editor',
2613
2710
help='The command called to launch an editor to enter a message.'))
2614
2711
option_registry.register(
2615
Option('email', default=default_email,
2616
from_unicode=email_from_store,
2712
Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2617
2713
help='The users identity'))
2618
2714
option_registry.register(
2619
2715
Option('gpg_signing_command',
2667
2763
help= 'Unicode encoding for output'
2668
2764
' (terminal encoding if not specified).'))
2669
2765
option_registry.register(
2766
Option('parent_location',
2769
The location of the default branch for pull or merge.
2771
This option is normally set when creating a branch, the first ``pull`` or by
2772
``pull --remember``.
2774
option_registry.register(
2670
2775
Option('post_commit', default=None,
2672
2777
Post commit functions.
2676
2781
Each function takes branch, rev_id as parameters.
2678
2783
option_registry.register(
2784
Option('public_branch',
2787
A publically-accessible version of this branch.
2789
This implies that the branch setting this option is not publically-accessible.
2790
Used and set by ``bzr send``.
2792
option_registry.register(
2793
Option('push_location',
2796
The location of the default branch for push.
2798
This option is normally set by the first ``push`` or ``push --remember``.
2800
option_registry.register(
2679
2801
Option('push_strict', default=None,
2680
2802
from_unicode=bool_from_store,
2694
2816
to physical disk. This is somewhat slower, but means data should not be
2695
2817
lost if the machine crashes. See also dirstate.fdatasync.
2819
option_registry.register_lazy('smtp_server',
2820
'bzrlib.smtp_connection', 'smtp_server')
2821
option_registry.register_lazy('smtp_password',
2822
'bzrlib.smtp_connection', 'smtp_password')
2823
option_registry.register_lazy('smtp_username',
2824
'bzrlib.smtp_connection', 'smtp_username')
2698
2825
option_registry.register(
2699
2826
Option('selftest.timeout',
2717
2844
default=300.0, from_unicode=float_from_store,
2718
2845
help="If we wait for a new request from a client for more than"
2719
2846
" X seconds, consider the client idle, and hangup."))
2847
option_registry.register(
2848
Option('stacked_on_location',
2850
help="""The location where this branch is stacked on."""))
2851
option_registry.register(
2852
Option('submit_branch',
2855
The branch you intend to submit your current work to.
2857
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2858
by the ``submit:`` revision spec.
2722
2862
class Section(object):
2804
2944
raise NotImplementedError(self.unload)
2946
def quote(self, value):
2947
"""Quote a configuration option value for storing purposes.
2949
This allows Stacks to present values as they will be stored.
2953
def unquote(self, value):
2954
"""Unquote a configuration option value into unicode.
2956
The received value is quoted as stored.
2806
2960
def save(self):
2807
2961
"""Saves the Store to persistent storage."""
2808
2962
raise NotImplementedError(self.save)
2975
3129
section = self._config_obj.setdefault(section_id, {})
2976
3130
return self.mutable_section_class(section_id, section)
3132
def quote(self, value):
3134
# configobj conflates automagical list values and quoting
3135
self._config_obj.list_values = True
3136
return self._config_obj._quote(value)
3138
self._config_obj.list_values = False
3140
def unquote(self, value):
3141
if value and isinstance(value, basestring):
3142
# _unquote doesn't handle None nor empty strings nor anything that
3143
# is not a string, really.
3144
value = self._config_obj._unquote(value)
2979
3148
class TransportIniFileStore(IniFileStore):
2980
3149
"""IniFileStore that loads files from a transport.
3305
3475
if expand is None:
3306
3476
expand = _get_expand_default_value()
3308
# Ensuring lazy loading is achieved by delaying section matching (which
3309
# implies querying the persistent storage) until it can't be avoided
3310
# anymore by using callables to describe (possibly empty) section
3312
for sections in self.sections_def:
3313
for store, section in sections():
3314
value = section.get(name)
3315
if value is not None:
3317
if value is not None:
3478
found_store = None # Where the option value has been found
3319
3479
# If the option is registered, it may provide additional info about
3320
3480
# value handling
3323
3483
except KeyError:
3324
3484
# Not registered
3326
3487
def expand_and_convert(val):
3327
# This may need to be called twice if the value is None or ends up
3328
# being None during expansion or conversion.
3488
# This may need to be called in different contexts if the value is
3489
# None or ends up being None during expansion or conversion.
3329
3490
if val is not None:
3331
3492
if isinstance(val, basestring):
3334
3495
trace.warning('Cannot expand "%s":'
3335
3496
' %s does not support option expansion'
3336
3497
% (name, type(val)))
3338
val = opt.convert_from_unicode(val)
3499
val = found_store.unquote(val)
3501
val = opt.convert_from_unicode(found_store, val)
3340
value = expand_and_convert(value)
3341
if opt is not None and value is None:
3342
# If the option is registered, it may provide a default value
3343
value = opt.get_default()
3344
value = expand_and_convert(value)
3504
# First of all, check if the environment can override the configuration
3506
if opt is not None and opt.override_from_env:
3507
value = opt.get_override()
3508
value = expand_and_convert(value)
3510
# Ensuring lazy loading is achieved by delaying section matching
3511
# (which implies querying the persistent storage) until it can't be
3512
# avoided anymore by using callables to describe (possibly empty)
3514
for sections in self.sections_def:
3515
for store, section in sections():
3516
value = section.get(name)
3517
if value is not None:
3520
if value is not None:
3522
value = expand_and_convert(value)
3523
if opt is not None and value is None:
3524
# If the option is registered, it may provide a default value
3525
value = opt.get_default()
3526
value = expand_and_convert(value)
3345
3527
for hook in ConfigHooks['get']:
3346
3528
hook(self, name, value)
3419
3601
or deleting an option. In practice the store will often be loaded but
3420
3602
this helps catching some programming errors.
3422
section = self.store.get_mutable_section(self.mutable_section_id)
3605
section = store.get_mutable_section(self.mutable_section_id)
3606
return store, section
3425
3608
def set(self, name, value):
3426
3609
"""Set a new value for the option."""
3427
section = self._get_mutable_section()
3428
section.set(name, value)
3610
store, section = self._get_mutable_section()
3611
section.set(name, store.quote(value))
3429
3612
for hook in ConfigHooks['set']:
3430
3613
hook(self, name, value)
3432
3615
def remove(self, name):
3433
3616
"""Remove an existing option."""
3434
section = self._get_mutable_section()
3617
_, section = self._get_mutable_section()
3435
3618
section.remove(name)
3436
3619
for hook in ConfigHooks['remove']:
3437
3620
hook(self, name)
3633
class MemoryStack(Stack):
3634
"""A configuration stack defined from a string.
3636
This is mainly intended for tests and requires no disk resources.
3639
def __init__(self, content=None):
3640
"""Create an in-memory stack from a given content.
3642
It uses a single store based on configobj and support reading and
3645
:param content: The initial content of the store. If None, the store is
3646
not loaded and ``_load_from_string`` can and should be used if
3649
store = IniFileStore()
3650
if content is not None:
3651
store._load_from_string(content)
3652
super(MemoryStack, self).__init__(
3653
[store.get_sections], store)
3450
3656
class _CompatibleStack(Stack):
3451
3657
"""Place holder for compatibility with previous design.
3579
3785
self.bzrdir = bzrdir
3582
class RemoteBranchStack(_CompatibleStack):
3583
"""Remote branch-only options stack."""
3788
class BranchOnlyStack(_CompatibleStack):
3789
"""Branch-only options stack."""
3585
# FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
3586
# with the stack used for remote branches. RemoteBranchStack only uses
3587
# branch.conf and is used only for the stack options.
3791
# FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
3792
# stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
3793
# -- vila 2011-12-16
3589
3795
def __init__(self, branch):
3590
3796
bstore = branch._get_config_store()
3591
super(RemoteBranchStack, self).__init__(
3797
super(BranchOnlyStack, self).__init__(
3592
3798
[NameMatcher(bstore, None).get_sections],
3594
3800
self.branch = branch
3596
3803
# Use a an empty dict to initialize an empty configobj avoiding all
3597
3804
# parsing and encoding checks
3598
3805
_quoting_config = configobj.ConfigObj(
3599
{}, encoding='utf-8', interpolation=False)
3806
{}, encoding='utf-8', interpolation=False, list_values=True)
3601
3808
class cmd_config(commands.Command):
3602
3809
__doc__ = """Display, set or remove a configuration option.
3722
3929
self.outf.write('%s:\n' % (store.id,))
3723
3930
cur_store_id = store.id
3724
3931
cur_section = None
3725
if (section.id not in (None, 'DEFAULT')
3932
if (section.id is not None
3726
3933
and cur_section != section.id):
3727
# Display the section if it's not the default (or
3934
# Display the section id as it appears in the store
3935
# (None doesn't appear by definition)
3729
3936
self.outf.write(' [%s]\n' % (section.id,))
3730
3937
cur_section = section.id
3731
3938
value = section.get(oname, expand=False)
3939
# Since we don't use the stack, we need to restore a
3942
opt = option_registry.get(oname)
3943
value = opt.convert_from_unicode(store, value)
3945
value = store.unquote(value)
3732
3946
value = _quoting_config._quote(value)
3733
3947
self.outf.write(' %s = %s\n' % (oname, value))