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',
2574
2671
option_registry.register(
2672
Option('child_submit_format',
2673
help='''The preferred format of submissions to this branch.'''))
2674
option_registry.register(
2675
Option('child_submit_to',
2676
help='''Where submissions to this branch are mailed to.'''))
2677
option_registry.register(
2575
2678
Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2576
2679
from_unicode=signing_policy_from_unicode,
2593
2696
should not be lost if the machine crashes. See also repository.fdatasync.
2595
2698
option_registry.register(
2596
Option('debug_flags', default=[], from_unicode=list_from_store,
2699
ListOption('debug_flags', default=[],
2597
2700
help='Debug flags to activate.'))
2598
2701
option_registry.register(
2599
2702
Option('default_format', default='2a',
2612
2715
Option('editor',
2613
2716
help='The command called to launch an editor to enter a message.'))
2614
2717
option_registry.register(
2615
Option('email', default=default_email,
2616
from_unicode=email_from_store,
2718
Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2617
2719
help='The users identity'))
2618
2720
option_registry.register(
2619
2721
Option('gpg_signing_command',
2667
2769
help= 'Unicode encoding for output'
2668
2770
' (terminal encoding if not specified).'))
2669
2771
option_registry.register(
2772
Option('parent_location',
2775
The location of the default branch for pull or merge.
2777
This option is normally set when creating a branch, the first ``pull`` or by
2778
``pull --remember``.
2780
option_registry.register(
2670
2781
Option('post_commit', default=None,
2672
2783
Post commit functions.
2676
2787
Each function takes branch, rev_id as parameters.
2678
2789
option_registry.register(
2790
Option('public_branch',
2793
A publically-accessible version of this branch.
2795
This implies that the branch setting this option is not publically-accessible.
2796
Used and set by ``bzr send``.
2798
option_registry.register(
2799
Option('push_location',
2802
The location of the default branch for push.
2804
This option is normally set by the first ``push`` or ``push --remember``.
2806
option_registry.register(
2679
2807
Option('push_strict', default=None,
2680
2808
from_unicode=bool_from_store,
2694
2822
to physical disk. This is somewhat slower, but means data should not be
2695
2823
lost if the machine crashes. See also dirstate.fdatasync.
2825
option_registry.register_lazy('smtp_server',
2826
'bzrlib.smtp_connection', 'smtp_server')
2827
option_registry.register_lazy('smtp_password',
2828
'bzrlib.smtp_connection', 'smtp_password')
2829
option_registry.register_lazy('smtp_username',
2830
'bzrlib.smtp_connection', 'smtp_username')
2698
2831
option_registry.register(
2699
2832
Option('selftest.timeout',
2717
2850
default=300.0, from_unicode=float_from_store,
2718
2851
help="If we wait for a new request from a client for more than"
2719
2852
" X seconds, consider the client idle, and hangup."))
2853
option_registry.register(
2854
Option('stacked_on_location',
2856
help="""The location where this branch is stacked on."""))
2857
option_registry.register(
2858
Option('submit_branch',
2861
The branch you intend to submit your current work to.
2863
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2864
by the ``submit:`` revision spec.
2866
option_registry.register(
2868
help='''Where submissions from this branch are mailed to.'''))
2722
2871
class Section(object):
2754
2905
def __init__(self, section_id, options):
2755
2906
super(MutableSection, self).__init__(section_id, options)
2907
self.reset_changes()
2758
2909
def set(self, name, value):
2759
2910
if name not in self.options:
2768
2919
self.orig[name] = self.get(name, None)
2769
2920
del self.options[name]
2922
def reset_changes(self):
2925
def apply_changes(self, dirty, store):
2926
"""Apply option value changes.
2928
``self`` has been reloaded from the persistent storage. ``dirty``
2929
contains the changes made since the previous loading.
2931
:param dirty: the mutable section containing the changes.
2933
:param store: the store containing the section
2935
for k, expected in dirty.orig.iteritems():
2936
actual = dirty.get(k, _DeletedOption)
2937
reloaded = self.get(k, _NewlyCreatedOption)
2938
if actual is _DeletedOption:
2939
if k in self.options:
2943
# Report concurrent updates in an ad-hoc way. This should only
2944
# occurs when different processes try to update the same option
2945
# which is not supported (as in: the config framework is not meant
2946
# to be used a sharing mechanism).
2947
if expected != reloaded:
2948
if actual is _DeletedOption:
2949
actual = '<DELETED>'
2950
if reloaded is _NewlyCreatedOption:
2951
reloaded = '<CREATED>'
2952
if expected is _NewlyCreatedOption:
2953
expected = '<CREATED>'
2954
# Someone changed the value since we get it from the persistent
2956
trace.warning(gettext(
2957
"Option {0} in section {1} of {2} was changed"
2958
" from {3} to {4}. The {5} value will be saved.".format(
2959
k, self.id, store.external_url(), expected,
2961
# No need to keep track of these changes
2962
self.reset_changes()
2772
2965
class Store(object):
2773
2966
"""Abstract interface to persistent storage for configuration options."""
2804
3001
raise NotImplementedError(self.unload)
3003
def quote(self, value):
3004
"""Quote a configuration option value for storing purposes.
3006
This allows Stacks to present values as they will be stored.
3010
def unquote(self, value):
3011
"""Unquote a configuration option value into unicode.
3013
The received value is quoted as stored.
2806
3017
def save(self):
2807
3018
"""Saves the Store to persistent storage."""
2808
3019
raise NotImplementedError(self.save)
3021
def _need_saving(self):
3022
for s in self.dirty_sections:
3024
# At least one dirty section contains a modification
3028
def apply_changes(self, dirty_sections):
3029
"""Apply changes from dirty sections while checking for coherency.
3031
The Store content is discarded and reloaded from persistent storage to
3032
acquire up-to-date values.
3034
Dirty sections are MutableSection which kept track of the value they
3035
are expected to update.
3037
# We need an up-to-date version from the persistent storage, unload the
3038
# store. The reload will occur when needed (triggered by the first
3039
# get_mutable_section() call below.
3041
# Apply the changes from the preserved dirty sections
3042
for dirty in dirty_sections:
3043
clean = self.get_mutable_section(dirty.id)
3044
clean.apply_changes(dirty, self)
3045
# Everything is clean now
3046
self.dirty_sections = []
3048
def save_changes(self):
3049
"""Saves the Store to persistent storage if changes occurred.
3051
Apply the changes recorded in the mutable sections to a store content
3052
refreshed from persistent storage.
3054
raise NotImplementedError(self.save_changes)
2810
3056
def external_url(self):
2811
3057
raise NotImplementedError(self.external_url)
2933
3180
except UnicodeDecodeError:
2934
3181
raise errors.ConfigContentError(self.external_url())
3183
def save_changes(self):
3184
if not self.is_loaded():
3187
if not self._need_saving():
3189
# Preserve the current version
3190
current = self._config_obj
3191
dirty_sections = list(self.dirty_sections)
3192
self.apply_changes(dirty_sections)
3193
# Save to the persistent storage
2936
3196
def save(self):
2937
3197
if not self.is_loaded():
2938
3198
# Nothing to save
2973
3233
section = self._config_obj
2975
3235
section = self._config_obj.setdefault(section_id, {})
2976
return self.mutable_section_class(section_id, section)
3236
mutable_section = self.mutable_section_class(section_id, section)
3237
# All mutable sections can become dirty
3238
self.dirty_sections.append(mutable_section)
3239
return mutable_section
3241
def quote(self, value):
3243
# configobj conflates automagical list values and quoting
3244
self._config_obj.list_values = True
3245
return self._config_obj._quote(value)
3247
self._config_obj.list_values = False
3249
def unquote(self, value):
3250
if value and isinstance(value, basestring):
3251
# _unquote doesn't handle None nor empty strings nor anything that
3252
# is not a string, really.
3253
value = self._config_obj._unquote(value)
2979
3257
class TransportIniFileStore(IniFileStore):
3305
3584
if expand is None:
3306
3585
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:
3587
found_store = None # Where the option value has been found
3319
3588
# If the option is registered, it may provide additional info about
3320
3589
# value handling
3323
3592
except KeyError:
3324
3593
# Not registered
3326
3596
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.
3597
# This may need to be called in different contexts if the value is
3598
# None or ends up being None during expansion or conversion.
3329
3599
if val is not None:
3331
3601
if isinstance(val, basestring):
3334
3604
trace.warning('Cannot expand "%s":'
3335
3605
' %s does not support option expansion'
3336
3606
% (name, type(val)))
3338
val = opt.convert_from_unicode(val)
3608
val = found_store.unquote(val)
3610
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)
3613
# First of all, check if the environment can override the configuration
3615
if opt is not None and opt.override_from_env:
3616
value = opt.get_override()
3617
value = expand_and_convert(value)
3619
# Ensuring lazy loading is achieved by delaying section matching
3620
# (which implies querying the persistent storage) until it can't be
3621
# avoided anymore by using callables to describe (possibly empty)
3623
for sections in self.sections_def:
3624
for store, section in sections():
3625
value = section.get(name)
3626
if value is not None:
3629
if value is not None:
3631
value = expand_and_convert(value)
3632
if opt is not None and value is None:
3633
# If the option is registered, it may provide a default value
3634
value = opt.get_default()
3635
value = expand_and_convert(value)
3345
3636
for hook in ConfigHooks['get']:
3346
3637
hook(self, name, value)
3419
3710
or deleting an option. In practice the store will often be loaded but
3420
3711
this helps catching some programming errors.
3422
section = self.store.get_mutable_section(self.mutable_section_id)
3714
section = store.get_mutable_section(self.mutable_section_id)
3715
return store, section
3425
3717
def set(self, name, value):
3426
3718
"""Set a new value for the option."""
3427
section = self._get_mutable_section()
3428
section.set(name, value)
3719
store, section = self._get_mutable_section()
3720
section.set(name, store.quote(value))
3429
3721
for hook in ConfigHooks['set']:
3430
3722
hook(self, name, value)
3432
3724
def remove(self, name):
3433
3725
"""Remove an existing option."""
3434
section = self._get_mutable_section()
3726
_, section = self._get_mutable_section()
3435
3727
section.remove(name)
3436
3728
for hook in ConfigHooks['remove']:
3437
3729
hook(self, name)
3742
class MemoryStack(Stack):
3743
"""A configuration stack defined from a string.
3745
This is mainly intended for tests and requires no disk resources.
3748
def __init__(self, content=None):
3749
"""Create an in-memory stack from a given content.
3751
It uses a single store based on configobj and support reading and
3754
:param content: The initial content of the store. If None, the store is
3755
not loaded and ``_load_from_string`` can and should be used if
3758
store = IniFileStore()
3759
if content is not None:
3760
store._load_from_string(content)
3761
super(MemoryStack, self).__init__(
3762
[store.get_sections], store)
3450
3765
class _CompatibleStack(Stack):
3451
3766
"""Place holder for compatibility with previous design.
3579
3894
self.bzrdir = bzrdir
3582
class RemoteBranchStack(_CompatibleStack):
3583
"""Remote branch-only options stack."""
3897
class BranchOnlyStack(_CompatibleStack):
3898
"""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.
3900
# FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
3901
# stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
3902
# -- vila 2011-12-16
3589
3904
def __init__(self, branch):
3590
3905
bstore = branch._get_config_store()
3591
super(RemoteBranchStack, self).__init__(
3906
super(BranchOnlyStack, self).__init__(
3592
3907
[NameMatcher(bstore, None).get_sections],
3594
3909
self.branch = branch
3596
3912
# Use a an empty dict to initialize an empty configobj avoiding all
3597
3913
# parsing and encoding checks
3598
3914
_quoting_config = configobj.ConfigObj(
3599
{}, encoding='utf-8', interpolation=False)
3915
{}, encoding='utf-8', interpolation=False, list_values=True)
3601
3917
class cmd_config(commands.Command):
3602
3918
__doc__ = """Display, set or remove a configuration option.
3722
4038
self.outf.write('%s:\n' % (store.id,))
3723
4039
cur_store_id = store.id
3724
4040
cur_section = None
3725
if (section.id not in (None, 'DEFAULT')
4041
if (section.id is not None
3726
4042
and cur_section != section.id):
3727
# Display the section if it's not the default (or
4043
# Display the section id as it appears in the store
4044
# (None doesn't appear by definition)
3729
4045
self.outf.write(' [%s]\n' % (section.id,))
3730
4046
cur_section = section.id
3731
4047
value = section.get(oname, expand=False)
4048
# Since we don't use the stack, we need to restore a
4051
opt = option_registry.get(oname)
4052
value = opt.convert_from_unicode(store, value)
4054
value = store.unquote(value)
3732
4055
value = _quoting_config._quote(value)
3733
4056
self.outf.write(' %s = %s\n' % (oname, value))