236
236
class NoWhoami(errors.BzrError):
238
238
_fmt = ('Unable to determine your name.\n'
239
"Please, set your name with the 'whoami' command.\n"
240
'E.g. brz whoami "Your Name <name@example.com>"')
239
"Please, set your name with the 'whoami' command.\n"
240
'E.g. brz whoami "Your Name <name@example.com>"')
243
243
def signature_policy_from_unicode(signature_string):
628
628
# This should be done through the proposed config defaults mechanism
629
629
# when it becomes available in the future.
630
630
command_line = (self.get_user_option('bzr.mergetool.%s' % name,
632
or mergetools.known_merge_tools.get(name, None))
632
mergetools.known_merge_tools.get(name, None))
633
633
return command_line
678
680
These are all empty initially, because by default nothing should get
681
super(_OldConfigHooks, self).__init__('breezy.config', 'OldConfigHooks')
683
super(_OldConfigHooks, self).__init__(
684
'breezy.config', 'OldConfigHooks')
682
685
self.add_hook('load',
683
686
'Invoked when a config store is loaded.'
684
687
' The signature is (config).',
1009
1014
def remove_user_option(self, option_name, section_name=None):
1010
1015
with self.lock_write():
1011
1016
super(LockableConfig, self).remove_user_option(
1012
option_name, section_name)
1017
option_name, section_name)
1014
1019
def _write_config_file(self):
1015
1020
if self._lock is None or not self._lock.is_held:
1096
1101
# We need to avoid the LockableConfig implementation or we'll lock
1098
1103
super(LockableConfig, self).remove_user_option(
1099
option_name, section_name)
1104
option_name, section_name)
1102
1107
def _iter_for_location_by_parts(sections, location):
1373
1378
def set_user_option(self, name, value, store=STORE_BRANCH,
1375
1380
if store == STORE_BRANCH:
1376
1381
self._get_branch_data_config().set_option(value, name)
1377
1382
elif store == STORE_GLOBAL:
1440
1445
if sys.platform == 'win32':
1441
1446
parent_dir = os.path.dirname(path)
1442
1447
if not os.path.isdir(parent_dir):
1443
trace.mutter('creating config parent directory: %r', parent_dir)
1449
'creating config parent directory: %r', parent_dir)
1444
1450
os.mkdir(parent_dir)
1445
1451
trace.mutter('creating config directory: %r', path)
1741
1747
def __init__(self, _file=None):
1742
self._config = None # The ConfigObj
1748
self._config = None # The ConfigObj
1743
1749
if _file is None:
1744
1750
self._filename = authentication_config_filename()
1745
1751
self._input = self._filename = authentication_config_filename()
1775
1781
trace.mutter('Unable to stat %r: %r', self._filename, e)
1777
1783
mode = stat.S_IMODE(st.st_mode)
1778
if ((stat.S_IXOTH | stat.S_IWOTH | stat.S_IROTH | stat.S_IXGRP |
1779
stat.S_IWGRP | stat.S_IRGRP ) & mode):
1784
if ((stat.S_IXOTH | stat.S_IWOTH | stat.S_IROTH | stat.S_IXGRP
1785
| stat.S_IWGRP | stat.S_IRGRP ) & mode):
1780
1786
# Only warn once
1781
if (not self._filename in _authentication_config_permission_errors
1782
and not GlobalConfig().suppress_warning(
1787
if (not self._filename in _authentication_config_permission_errors and
1788
not GlobalConfig().suppress_warning(
1783
1789
'insecure_permissions')):
1784
1790
trace.warning("The file '%s' has insecure "
1785
"file permissions. Saved passwords may be accessible "
1786
"by other users.", self._filename)
1791
"file permissions. Saved passwords may be accessible "
1792
"by other users.", self._filename)
1787
1793
_authentication_config_permission_errors.add(self._filename)
1789
1795
def _save(self):
1790
1796
"""Save the config file, only tests should use it for now."""
1791
1797
conf_dir = os.path.dirname(self._filename)
1792
1798
ensure_config_dir_exists(conf_dir)
1793
fd = os.open(self._filename, os.O_RDWR|os.O_CREAT, 0o600)
1799
fd = os.open(self._filename, os.O_RDWR | os.O_CREAT, 0o600)
1795
1801
f = os.fdopen(fd, 'wb')
1796
1802
self._get_config().write(f)
1841
1847
credentials = None
1842
1848
for auth_def_name, auth_def in self._get_config().iteritems():
1843
1849
if not isinstance(auth_def, configobj.Section):
1844
raise ValueError("%s defined outside a section" % auth_def_name)
1850
raise ValueError("%s defined outside a section" %
1846
1853
a_scheme, a_host, a_user, a_path = map(
1847
1854
auth_def.get, ['scheme', 'host', 'user', 'path'])
1864
1871
if a_scheme is not None and scheme != a_scheme:
1866
1873
if a_host is not None:
1867
if not (host == a_host
1868
or (a_host.startswith('.') and host.endswith(a_host))):
1874
if not (host == a_host or
1875
(a_host.startswith('.') and host.endswith(a_host))):
1870
1877
if a_port is not None and port != a_port:
1872
if (a_path is not None and path is not None
1873
and not path.startswith(a_path)):
1879
if (a_path is not None and path is not None and
1880
not path.startswith(a_path)):
1875
if (a_user is not None and user is not None
1876
and a_user != user):
1882
if (a_user is not None and user is not None and
1877
1884
# Never contradict the caller about the user to be used
1879
1886
if a_user is None:
2170
2176
# should probably propogate as something more useful.
2171
2177
return base64.standard_b64decode(credentials['password'])
2173
2180
credential_store_registry.register('base64', Base64CredentialStore,
2174
2181
help=Base64CredentialStore.__doc__)
2281
2288
return BytesIO()
2282
2289
except errors.PermissionDenied as e:
2283
2290
trace.warning("Permission denied while trying to open "
2284
"configuration file %s.", urlutils.unescape_for_display(
2285
urlutils.join(self._transport.base, self._filename), "utf-8"))
2291
"configuration file %s.", urlutils.unescape_for_display(
2292
urlutils.join(self._transport.base, self._filename), "utf-8"))
2286
2293
return BytesIO()
2288
2295
def _external_url(self):
2476
2483
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2478
2486
def int_SI_from_store(unicode_str):
2479
2487
"""Convert a human readable size in SI units, e.g 10MB into an integer.
2593
2602
for '{bar{baz}}' we will get '{baz}'
2596
2606
def iter_option_refs(string):
2597
2607
# Split isolate refs so every other chunk is a ref
2599
for chunk in _option_ref_re.split(string):
2609
for chunk in _option_ref_re.split(string):
2600
2610
yield is_ref, chunk
2601
2611
is_ref = not is_ref
2666
2676
option_registry.register(
2667
2677
ListOption('acceptable_keys',
2670
2680
List of GPG key patterns which are acceptable for verification.
2672
2682
option_registry.register(
2702
2712
See also: bound.
2704
2714
option_registry.register(
2705
Option('branch.fetch_tags', default=False, from_unicode=bool_from_store,
2715
Option('branch.fetch_tags', default=False, from_unicode=bool_from_store,
2707
2717
Whether revisions associated with tags should be fetched.
2710
2720
'transform.orphan_policy', 'breezy.transform', 'opt_transform_orphan')
2711
2721
option_registry.register(
2712
2722
Option('bzr.workingtree.worth_saving_limit', default=10,
2713
from_unicode=int_from_store, invalid='warning',
2723
from_unicode=int_from_store, invalid='warning',
2715
2725
How many changes before saving the dirstate.
2771
2781
option_registry.register(
2772
2782
ListOption('debug_flags', default=[],
2773
help='Debug flags to activate.'))
2783
help='Debug flags to activate.'))
2774
2784
option_registry.register(
2775
2785
Option('default_format', default='2a',
2776
2786
help='Format used when creating branches.'))
2816
2826
option_registry.register(
2817
2827
Option('log_format', default='long',
2819
2829
Log format to use when displaying revisions.
2821
2831
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2822
2832
may be provided by plugins.
2824
2834
option_registry.register_lazy('mail_client', 'breezy.mail_client',
2826
2836
option_registry.register(
2827
2837
Option('output_encoding',
2828
help= 'Unicode encoding for output'
2838
help='Unicode encoding for output'
2829
2839
' (terminal encoding if not specified).'))
2830
2840
option_registry.register(
2831
2841
Option('parent_location',
2884
2894
lost if the machine crashes. See also dirstate.fdatasync.
2886
2896
option_registry.register_lazy('smtp_server',
2887
'breezy.smtp_connection', 'smtp_server')
2897
'breezy.smtp_connection', 'smtp_server')
2888
2898
option_registry.register_lazy('smtp_password',
2889
'breezy.smtp_connection', 'smtp_password')
2899
'breezy.smtp_connection', 'smtp_password')
2890
2900
option_registry.register_lazy('smtp_username',
2891
'breezy.smtp_connection', 'smtp_username')
2901
'breezy.smtp_connection', 'smtp_username')
2892
2902
option_registry.register(
2893
2903
Option('selftest.timeout',
2895
from_unicode=int_from_store,
2896
help='Abort selftest if one test takes longer than this many seconds',
2905
from_unicode=int_from_store,
2906
help='Abort selftest if one test takes longer than this many seconds',
2899
2909
option_registry.register(
2900
2910
Option('send_strict', default=None,
2929
2939
help='''Where submissions from this branch are mailed to.'''))
2930
2940
option_registry.register(
2931
2941
ListOption('suppress_warnings',
2933
help="List of warning classes to suppress."))
2943
help="List of warning classes to suppress."))
2934
2944
option_registry.register(
2935
2945
Option('validate_signatures_in_log', default=False,
2936
2946
from_unicode=bool_from_store, invalid='warning',
2937
2947
help='''Whether to validate signatures in brz log.'''))
2938
2948
option_registry.register_lazy('ssl.ca_certs',
2939
'breezy.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2949
'breezy.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2941
2951
option_registry.register_lazy('ssl.cert_reqs',
2942
'breezy.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2952
'breezy.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2945
2955
class Section(object):
3028
3038
# Someone changed the value since we get it from the persistent
3030
3040
trace.warning(gettext(
3031
"Option {0} in section {1} of {2} was changed"
3032
" from {3} to {4}. The {5} value will be saved.".format(
3033
k, self.id, store.external_url(), expected,
3041
"Option {0} in section {1} of {2} was changed"
3042
" from {3} to {4}. The {5} value will be saved.".format(
3043
k, self.id, store.external_url(), expected,
3035
3045
# No need to keep track of these changes
3036
3046
self.reset_changes()
3183
3193
return 'cmdline'
3185
3195
def get_sections(self):
3186
yield self, self.readonly_section_class(None, self.options)
3196
yield self, self.readonly_section_class(None, self.options)
3189
3199
class IniFileStore(Store):
3476
3486
def __init__(self, bzrdir):
3477
3487
super(ControlStore, self).__init__(bzrdir.transport,
3479
3489
lock_dir_name='branch_lock')
3480
3490
self.id = 'control'
3592
3602
# the location is already a local path or URL, convert the
3593
3603
# section id to the same format
3594
3604
section_path = urlutils.local_path_from_url(section_path)
3595
if (self.location.startswith(section_path)
3596
or fnmatch.fnmatch(self.location, section_path)):
3605
if (self.location.startswith(section_path) or
3606
fnmatch.fnmatch(self.location, section_path)):
3597
3607
section_parts = section_path.rstrip('/').split('/')
3598
3608
extra_path = '/'.join(location_parts[len(section_parts):])
3599
3609
yield store, LocationSection(section, extra_path)
3724
3735
# FIXME: No caching of options nor sections yet -- vila 20110503
3726
found_store = None # Where the option value has been found
3737
found_store = None # Where the option value has been found
3727
3738
# If the option is registered, it may provide additional info about
3728
3739
# value handling
4145
4157
' configuration file.',
4146
4158
type=text_type),
4147
4159
commands.Option('all',
4148
help='Display all the defined values for the matching options.',
4160
help='Display all the defined values for the matching options.',
4150
4162
commands.Option('remove', help='Remove the option from'
4151
4163
' the configuration file.'),