~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Martin Pool
  • Date: 2006-08-10 01:16:16 UTC
  • mto: (1904.1.2 0.9)
  • mto: This revision was merged to the branch mainline in revision 1913.
  • Revision ID: mbp@sourcefrog.net-20060810011616-d74881eba696e746
compare_trees is deprecated in 0.9 not 0.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
49
49
create_signatures - this option controls whether bzr will always create 
50
50
                    gpg signatures, never create them, or create them if the
51
51
                    branch is configured to require them.
52
 
log_format - this option sets the default log format.  Possible values are
53
 
             long, short, line, or a plugin can register new formats.
 
52
log_format - This options set the default log format.  Options are long, 
 
53
             short, line, or a plugin can register new formats
54
54
 
55
55
In bazaar.conf you can also define aliases in the ALIASES sections, example
56
56
 
61
61
up=pull
62
62
"""
63
63
 
64
 
import os
65
 
import sys
66
64
 
67
 
from bzrlib.lazy_import import lazy_import
68
 
lazy_import(globals(), """
69
65
import errno
70
66
from fnmatch import fnmatch
 
67
import os
71
68
import re
 
69
import sys
72
70
from StringIO import StringIO
73
71
 
74
72
import bzrlib
75
 
from bzrlib import (
76
 
    errors,
77
 
    osutils,
78
 
    symbol_versioning,
79
 
    urlutils,
80
 
    )
 
73
from bzrlib import errors, urlutils
 
74
from bzrlib.osutils import pathjoin
 
75
from bzrlib.trace import mutter, warning
81
76
import bzrlib.util.configobj.configobj as configobj
82
 
""")
83
 
 
84
 
from bzrlib.trace import mutter, warning
85
77
 
86
78
 
87
79
CHECK_IF_POSSIBLE=0
94
86
SIGN_NEVER=2
95
87
 
96
88
 
97
 
POLICY_NONE = 0
98
 
POLICY_NORECURSE = 1
99
 
POLICY_APPENDPATH = 2
100
 
 
101
 
_policy_name = {
102
 
    POLICY_NONE: None,
103
 
    POLICY_NORECURSE: 'norecurse',
104
 
    POLICY_APPENDPATH: 'appendpath',
105
 
    }
106
 
_policy_value = {
107
 
    None: POLICY_NONE,
108
 
    'none': POLICY_NONE,
109
 
    'norecurse': POLICY_NORECURSE,
110
 
    'appendpath': POLICY_APPENDPATH,
111
 
    }
112
 
 
113
 
 
114
 
STORE_LOCATION = POLICY_NONE
115
 
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
116
 
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
117
 
STORE_BRANCH = 3
118
 
STORE_GLOBAL = 4
119
 
 
120
 
 
121
89
class ConfigObj(configobj.ConfigObj):
122
90
 
123
91
    def get_bool(self, section, key):
199
167
    
200
168
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
201
169
        
202
 
        $BZR_EMAIL can be set to override this (as well as the
203
 
        deprecated $BZREMAIL), then
 
170
        $BZREMAIL can be set to override this, then
204
171
        the concrete policy type is checked, and finally
205
172
        $EMAIL is examined.
206
173
        If none is found, a reasonable default is (hopefully)
208
175
    
209
176
        TODO: Check it's reasonably well-formed.
210
177
        """
211
 
        v = os.environ.get('BZR_EMAIL')
212
 
        if v:
213
 
            return v.decode(bzrlib.user_encoding)
214
178
        v = os.environ.get('BZREMAIL')
215
179
        if v:
216
 
            warning('BZREMAIL is deprecated in favor of BZR_EMAIL. Please update your configuration.')
217
180
            return v.decode(bzrlib.user_encoding)
218
181
    
219
182
        v = self._get_user_id()
287
250
            raise errors.ParseConfigError(e.errors, e.config.filename)
288
251
        return self._parser
289
252
 
290
 
    def _get_matching_sections(self):
291
 
        """Return an ordered list of (section_name, extra_path) pairs.
292
 
 
293
 
        If the section contains inherited configuration, extra_path is
294
 
        a string containing the additional path components.
295
 
        """
296
 
        section = self._get_section()
297
 
        if section is not None:
298
 
            return [(section, '')]
299
 
        else:
300
 
            return []
301
 
 
302
253
    def _get_section(self):
303
254
        """Override this to define the section used by the config."""
304
255
        return "DEFAULT"
305
256
 
306
 
    def _get_option_policy(self, section, option_name):
307
 
        """Return the policy for the given (section, option_name) pair."""
308
 
        return POLICY_NONE
309
 
 
310
257
    def _get_signature_checking(self):
311
258
        """See Config._get_signature_checking."""
312
259
        policy = self._get_user_option('check_signatures')
325
272
 
326
273
    def _get_user_option(self, option_name):
327
274
        """See Config._get_user_option."""
328
 
        for (section, extra_path) in self._get_matching_sections():
329
 
            try:
330
 
                value = self._get_parser().get_value(section, option_name)
331
 
            except KeyError:
332
 
                continue
333
 
            policy = self._get_option_policy(section, option_name)
334
 
            if policy == POLICY_NONE:
335
 
                return value
336
 
            elif policy == POLICY_NORECURSE:
337
 
                # norecurse items only apply to the exact path
338
 
                if extra_path:
339
 
                    continue
340
 
                else:
341
 
                    return value
342
 
            elif policy == POLICY_APPENDPATH:
343
 
                if extra_path:
344
 
                    value = urlutils.join(value, extra_path)
345
 
                return value
346
 
            else:
347
 
                raise AssertionError('Unexpected config policy %r' % policy)
348
 
        else:
349
 
            return None
 
275
        try:
 
276
            return self._get_parser().get_value(self._get_section(),
 
277
                                                option_name)
 
278
        except KeyError:
 
279
            pass
350
280
 
351
281
    def _gpg_signing_command(self):
352
282
        """See Config.gpg_signing_command."""
444
374
            location = urlutils.local_path_from_url(location)
445
375
        self.location = location
446
376
 
447
 
    def _get_matching_sections(self):
448
 
        """Return an ordered list of section names matching this location."""
 
377
    def _get_section(self):
 
378
        """Get the section we should look in for config items.
 
379
 
 
380
        Returns None if none exists. 
 
381
        TODO: perhaps return a NullSection that thunks through to the 
 
382
              global config.
 
383
        """
449
384
        sections = self._get_parser()
450
385
        location_names = self.location.split('/')
451
386
        if self.location.endswith('/'):
475
410
            # if section is longer, no match.
476
411
            if len(section_names) > len(location_names):
477
412
                continue
478
 
            matches.append((len(section_names), section,
479
 
                            '/'.join(location_names[len(section_names):])))
 
413
            # if path is longer, and recurse is not true, no match
 
414
            if len(section_names) < len(location_names):
 
415
                try:
 
416
                    if not self._get_parser()[section].as_bool('recurse'):
 
417
                        continue
 
418
                except KeyError:
 
419
                    pass
 
420
            matches.append((len(section_names), section))
 
421
        if not len(matches):
 
422
            return None
480
423
        matches.sort(reverse=True)
481
 
        sections = []
482
 
        for (length, section, extra_path) in matches:
483
 
            sections.append((section, extra_path))
484
 
            # should we stop looking for parent configs here?
485
 
            try:
486
 
                if self._get_parser()[section].as_bool('ignore_parents'):
487
 
                    break
488
 
            except KeyError:
489
 
                pass
490
 
        return sections
491
 
 
492
 
    def _get_option_policy(self, section, option_name):
493
 
        """Return the policy for the given (section, option_name) pair."""
494
 
        # check for the old 'recurse=False' flag
495
 
        try:
496
 
            recurse = self._get_parser()[section].as_bool('recurse')
497
 
        except KeyError:
498
 
            recurse = True
499
 
        if not recurse:
500
 
            return POLICY_NORECURSE
501
 
 
502
 
        policy_key = option_name + ':policy'
503
 
        try:
504
 
            policy_name = self._get_parser()[section][policy_key]
505
 
        except KeyError:
506
 
            policy_name = None
507
 
 
508
 
        return _policy_value[policy_name]
509
 
 
510
 
    def _set_option_policy(self, section, option_name, option_policy):
511
 
        """Set the policy for the given option name in the given section."""
512
 
        # The old recurse=False option affects all options in the
513
 
        # section.  To handle multiple policies in the section, we
514
 
        # need to convert it to a policy_norecurse key.
515
 
        try:
516
 
            recurse = self._get_parser()[section].as_bool('recurse')
517
 
        except KeyError:
518
 
            pass
519
 
        else:
520
 
            symbol_versioning.warn(
521
 
                'The recurse option is deprecated as of 0.14.  '
522
 
                'The section "%s" has been converted to use policies.'
523
 
                % section,
524
 
                DeprecationWarning)
525
 
            del self._get_parser()[section]['recurse']
526
 
            if not recurse:
527
 
                for key in self._get_parser()[section].keys():
528
 
                    if not key.endswith(':policy'):
529
 
                        self._get_parser()[section][key +
530
 
                                                    ':policy'] = 'norecurse'
531
 
 
532
 
        policy_key = option_name + ':policy'
533
 
        policy_name = _policy_name[option_policy]
534
 
        if policy_name is not None:
535
 
            self._get_parser()[section][policy_key] = policy_name
536
 
        else:
537
 
            if policy_key in self._get_parser()[section]:
538
 
                del self._get_parser()[section][policy_key]
539
 
 
540
 
    def set_user_option(self, option, value, store=STORE_LOCATION):
 
424
        return matches[0][1]
 
425
 
 
426
    def set_user_option(self, option, value):
541
427
        """Save option and its value in the configuration."""
542
 
        assert store in [STORE_LOCATION,
543
 
                         STORE_LOCATION_NORECURSE,
544
 
                         STORE_LOCATION_APPENDPATH], 'bad storage policy'
545
428
        # FIXME: RBC 20051029 This should refresh the parser and also take a
546
429
        # file lock on locations.conf.
547
430
        conf_dir = os.path.dirname(self._get_filename())
555
438
        elif location + '/' in self._get_parser():
556
439
            location = location + '/'
557
440
        self._get_parser()[location][option]=value
558
 
        # the allowed values of store match the config policies
559
 
        self._set_option_policy(location, option, store)
560
441
        self._get_parser().write(file(self._get_filename(), 'wb'))
561
442
 
562
443
 
637
518
                return value
638
519
        return None
639
520
 
640
 
    def set_user_option(self, name, value, store=STORE_BRANCH):
641
 
        if store == STORE_BRANCH:
 
521
    def set_user_option(self, name, value, local=False):
 
522
        if local is True:
 
523
            self._get_location_config().set_user_option(name, value)
 
524
        else:
642
525
            self._get_branch_data_config().set_option(value, name)
643
 
        elif store == STORE_GLOBAL:
644
 
            self._get_global_config().set_user_option(name, value)
645
 
        else:
646
 
            self._get_location_config().set_user_option(name, value, store)
 
526
 
647
527
 
648
528
    def _gpg_signing_command(self):
649
529
        """See Config.gpg_signing_command."""
667
547
        value = self._get_explicit_nickname()
668
548
        if value is not None:
669
549
            return value
670
 
        return urlutils.unescape(self.branch.base.split('/')[-2])
 
550
        return self.branch.base.split('/')[-2]
671
551
 
672
552
    def has_explicit_nickname(self):
673
553
        """Return true if a nickname has been explicitly assigned."""
714
594
            base = os.environ.get('HOME', None)
715
595
        if base is None:
716
596
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA, or HOME set')
717
 
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
597
        return pathjoin(base, 'bazaar', '2.0')
718
598
    else:
719
599
        # cygwin, linux, and darwin all have a $HOME directory
720
600
        if base is None:
721
601
            base = os.path.expanduser("~")
722
 
        return osutils.pathjoin(base, ".bazaar")
 
602
        return pathjoin(base, ".bazaar")
723
603
 
724
604
 
725
605
def config_filename():
726
606
    """Return per-user configuration ini file filename."""
727
 
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
 
607
    return pathjoin(config_dir(), 'bazaar.conf')
728
608
 
729
609
 
730
610
def branches_config_filename():
731
611
    """Return per-user configuration ini file filename."""
732
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
 
612
    return pathjoin(config_dir(), 'branches.conf')
733
613
 
734
614
 
735
615
def locations_config_filename():
736
616
    """Return per-user configuration ini file filename."""
737
 
    return osutils.pathjoin(config_dir(), 'locations.conf')
 
617
    return pathjoin(config_dir(), 'locations.conf')
738
618
 
739
619
 
740
620
def user_ignore_config_filename():
741
621
    """Return the user default ignore filename"""
742
 
    return osutils.pathjoin(config_dir(), 'ignore')
 
622
    return pathjoin(config_dir(), 'ignore')
743
623
 
744
624
 
745
625
def _auto_user_id():
813
693
    """
814
694
    m = re.search(r'[\w+.-]+@[\w+.-]+', e)
815
695
    if not m:
816
 
        raise errors.NoEmailInUsername(e)
 
696
        raise errors.BzrError("%r doesn't seem to contain "
 
697
                              "a reasonable email address" % e)
817
698
    return m.group(0)
818
699
 
819
700