68
from bzrlib.lazy_import import lazy_import
69
lazy_import(globals(), """
71
66
from fnmatch import fnmatch
73
70
from StringIO import StringIO
73
from bzrlib import errors, urlutils
74
from bzrlib.osutils import pathjoin
75
from bzrlib.trace import mutter, warning
85
76
import bzrlib.util.configobj.configobj as configobj
88
from bzrlib.trace import mutter, warning
91
79
CHECK_IF_POSSIBLE=0
103
POLICY_APPENDPATH = 2
107
POLICY_NORECURSE: 'norecurse',
108
POLICY_APPENDPATH: 'appendpath',
113
'norecurse': POLICY_NORECURSE,
114
'appendpath': POLICY_APPENDPATH,
118
STORE_LOCATION = POLICY_NONE
119
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
120
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
125
89
class ConfigObj(configobj.ConfigObj):
127
91
def get_bool(self, section, key):
144
108
"""Get the users pop up editor."""
145
109
raise NotImplementedError
147
def get_mail_client(self):
148
"""Get a mail client to use"""
149
selected_client = self.get_user_option('mail_client')
151
mail_client_class = {
152
None: mail_client.DefaultMail,
154
'evolution': mail_client.Evolution,
155
'kmail': mail_client.KMail,
156
'mutt': mail_client.Mutt,
157
'thunderbird': mail_client.Thunderbird,
159
'default': mail_client.DefaultMail,
160
'editor': mail_client.Editor,
161
'mapi': mail_client.MAPIClient,
162
'xdg-email': mail_client.XDGEmail,
165
raise errors.UnknownMailClient(selected_client)
166
return mail_client_class(self)
168
111
def _get_signature_checking(self):
169
112
"""Template method to override signature checking policy."""
321
255
raise errors.ParseConfigError(e.errors, e.config.filename)
322
256
return self._parser
324
def _get_matching_sections(self):
325
"""Return an ordered list of (section_name, extra_path) pairs.
327
If the section contains inherited configuration, extra_path is
328
a string containing the additional path components.
330
section = self._get_section()
331
if section is not None:
332
return [(section, '')]
336
258
def _get_section(self):
337
259
"""Override this to define the section used by the config."""
340
def _get_option_policy(self, section, option_name):
341
"""Return the policy for the given (section, option_name) pair."""
344
262
def _get_signature_checking(self):
345
263
"""See Config._get_signature_checking."""
346
264
policy = self._get_user_option('check_signatures')
360
278
def _get_user_option(self, option_name):
361
279
"""See Config._get_user_option."""
362
for (section, extra_path) in self._get_matching_sections():
364
value = self._get_parser().get_value(section, option_name)
367
policy = self._get_option_policy(section, option_name)
368
if policy == POLICY_NONE:
370
elif policy == POLICY_NORECURSE:
371
# norecurse items only apply to the exact path
376
elif policy == POLICY_APPENDPATH:
378
value = urlutils.join(value, extra_path)
381
raise AssertionError('Unexpected config policy %r' % policy)
281
return self._get_parser().get_value(self._get_section(),
385
286
def _gpg_signing_command(self):
386
287
"""See Config.gpg_signing_command."""
478
379
location = urlutils.local_path_from_url(location)
479
380
self.location = location
481
def _get_matching_sections(self):
482
"""Return an ordered list of section names matching this location."""
382
def _get_section(self):
383
"""Get the section we should look in for config items.
385
Returns None if none exists.
386
TODO: perhaps return a NullSection that thunks through to the
483
389
sections = self._get_parser()
484
390
location_names = self.location.split('/')
485
391
if self.location.endswith('/'):
509
415
# if section is longer, no match.
510
416
if len(section_names) > len(location_names):
512
matches.append((len(section_names), section,
513
'/'.join(location_names[len(section_names):])))
418
# if path is longer, and recurse is not true, no match
419
if len(section_names) < len(location_names):
421
if not self._get_parser()[section].as_bool('recurse'):
425
matches.append((len(section_names), section))
514
428
matches.sort(reverse=True)
516
for (length, section, extra_path) in matches:
517
sections.append((section, extra_path))
518
# should we stop looking for parent configs here?
520
if self._get_parser()[section].as_bool('ignore_parents'):
526
def _get_option_policy(self, section, option_name):
527
"""Return the policy for the given (section, option_name) pair."""
528
# check for the old 'recurse=False' flag
530
recurse = self._get_parser()[section].as_bool('recurse')
534
return POLICY_NORECURSE
536
policy_key = option_name + ':policy'
538
policy_name = self._get_parser()[section][policy_key]
542
return _policy_value[policy_name]
544
def _set_option_policy(self, section, option_name, option_policy):
545
"""Set the policy for the given option name in the given section."""
546
# The old recurse=False option affects all options in the
547
# section. To handle multiple policies in the section, we
548
# need to convert it to a policy_norecurse key.
550
recurse = self._get_parser()[section].as_bool('recurse')
554
symbol_versioning.warn(
555
'The recurse option is deprecated as of 0.14. '
556
'The section "%s" has been converted to use policies.'
559
del self._get_parser()[section]['recurse']
561
for key in self._get_parser()[section].keys():
562
if not key.endswith(':policy'):
563
self._get_parser()[section][key +
564
':policy'] = 'norecurse'
566
policy_key = option_name + ':policy'
567
policy_name = _policy_name[option_policy]
568
if policy_name is not None:
569
self._get_parser()[section][policy_key] = policy_name
571
if policy_key in self._get_parser()[section]:
572
del self._get_parser()[section][policy_key]
574
def set_user_option(self, option, value, store=STORE_LOCATION):
431
def set_user_option(self, option, value):
575
432
"""Save option and its value in the configuration."""
576
assert store in [STORE_LOCATION,
577
STORE_LOCATION_NORECURSE,
578
STORE_LOCATION_APPENDPATH], 'bad storage policy'
579
433
# FIXME: RBC 20051029 This should refresh the parser and also take a
580
434
# file lock on locations.conf.
581
435
conf_dir = os.path.dirname(self._get_filename())
674
def set_user_option(self, name, value, store=STORE_BRANCH,
676
if store == STORE_BRANCH:
526
def set_user_option(self, name, value, local=False):
528
self._get_location_config().set_user_option(name, value)
677
530
self._get_branch_data_config().set_option(value, name)
678
elif store == STORE_GLOBAL:
679
self._get_global_config().set_user_option(name, value)
681
self._get_location_config().set_user_option(name, value, store)
684
if store in (STORE_GLOBAL, STORE_BRANCH):
685
mask_value = self._get_location_config().get_user_option(name)
686
if mask_value is not None:
687
trace.warning('Value "%s" is masked by "%s" from'
688
' locations.conf', value, mask_value)
690
if store == STORE_GLOBAL:
691
branch_config = self._get_branch_data_config()
692
mask_value = branch_config.get_user_option(name)
693
if mask_value is not None:
694
trace.warning('Value "%s" is masked by "%s" from'
695
' branch.conf', value, mask_value)
698
533
def _gpg_signing_command(self):
759
594
base = os.environ.get('BZR_HOME', None)
760
595
if sys.platform == 'win32':
762
base = win32utils.get_appdata_location_unicode()
597
base = os.environ.get('APPDATA', None)
764
599
base = os.environ.get('HOME', None)
766
601
raise errors.BzrError('You must have one of BZR_HOME, APPDATA, or HOME set')
767
return osutils.pathjoin(base, 'bazaar', '2.0')
602
return pathjoin(base, 'bazaar', '2.0')
769
604
# cygwin, linux, and darwin all have a $HOME directory
771
606
base = os.path.expanduser("~")
772
return osutils.pathjoin(base, ".bazaar")
607
return pathjoin(base, ".bazaar")
775
610
def config_filename():
776
611
"""Return per-user configuration ini file filename."""
777
return osutils.pathjoin(config_dir(), 'bazaar.conf')
612
return pathjoin(config_dir(), 'bazaar.conf')
780
615
def branches_config_filename():
781
616
"""Return per-user configuration ini file filename."""
782
return osutils.pathjoin(config_dir(), 'branches.conf')
617
return pathjoin(config_dir(), 'branches.conf')
785
620
def locations_config_filename():
786
621
"""Return per-user configuration ini file filename."""
787
return osutils.pathjoin(config_dir(), 'locations.conf')
622
return pathjoin(config_dir(), 'locations.conf')
790
625
def user_ignore_config_filename():
791
626
"""Return the user default ignore filename"""
792
return osutils.pathjoin(config_dir(), 'ignore')
627
return pathjoin(config_dir(), 'ignore')
795
630
def _auto_user_id():
808
if sys.platform == 'win32':
809
name = win32utils.get_user_name_unicode()
811
raise errors.BzrError("Cannot autodetect user name.\n"
812
"Please, set your name with command like:\n"
813
'bzr whoami "Your Name <name@domain.com>"')
814
host = win32utils.get_host_name_unicode()
816
host = socket.gethostname()
817
return name, (name + '@' + host)
643
# XXX: Any good way to get real user name on win32?