/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
 
1
# Copyright (C) 2005, 2007 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
 
3
#            and others
3
4
#
4
5
# This program is free software; you can redistribute it and/or modify
5
6
# it under the terms of the GNU General Public License as published by
61
62
up=pull
62
63
"""
63
64
 
 
65
import os
 
66
import sys
64
67
 
 
68
from bzrlib.lazy_import import lazy_import
 
69
lazy_import(globals(), """
65
70
import errno
66
71
from fnmatch import fnmatch
67
 
import os
68
72
import re
69
 
import sys
70
73
from StringIO import StringIO
71
74
 
72
75
import bzrlib
73
 
from bzrlib import errors, urlutils
74
 
from bzrlib.osutils import pathjoin
 
76
from bzrlib import (
 
77
    errors,
 
78
    osutils,
 
79
    symbol_versioning,
 
80
    urlutils,
 
81
    win32utils,
 
82
    )
 
83
import bzrlib.util.configobj.configobj as configobj
 
84
""")
 
85
 
75
86
from bzrlib.trace import mutter, warning
76
 
import bzrlib.util.configobj.configobj as configobj
77
87
 
78
88
 
79
89
CHECK_IF_POSSIBLE=0
86
96
SIGN_NEVER=2
87
97
 
88
98
 
 
99
POLICY_NONE = 0
 
100
POLICY_NORECURSE = 1
 
101
POLICY_APPENDPATH = 2
 
102
 
 
103
_policy_name = {
 
104
    POLICY_NONE: None,
 
105
    POLICY_NORECURSE: 'norecurse',
 
106
    POLICY_APPENDPATH: 'appendpath',
 
107
    }
 
108
_policy_value = {
 
109
    None: POLICY_NONE,
 
110
    'none': POLICY_NONE,
 
111
    'norecurse': POLICY_NORECURSE,
 
112
    'appendpath': POLICY_APPENDPATH,
 
113
    }
 
114
 
 
115
 
 
116
STORE_LOCATION = POLICY_NONE
 
117
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
 
118
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
 
119
STORE_BRANCH = 3
 
120
STORE_GLOBAL = 4
 
121
 
 
122
 
89
123
class ConfigObj(configobj.ConfigObj):
90
124
 
91
125
    def get_bool(self, section, key):
255
289
            raise errors.ParseConfigError(e.errors, e.config.filename)
256
290
        return self._parser
257
291
 
 
292
    def _get_matching_sections(self):
 
293
        """Return an ordered list of (section_name, extra_path) pairs.
 
294
 
 
295
        If the section contains inherited configuration, extra_path is
 
296
        a string containing the additional path components.
 
297
        """
 
298
        section = self._get_section()
 
299
        if section is not None:
 
300
            return [(section, '')]
 
301
        else:
 
302
            return []
 
303
 
258
304
    def _get_section(self):
259
305
        """Override this to define the section used by the config."""
260
306
        return "DEFAULT"
261
307
 
 
308
    def _get_option_policy(self, section, option_name):
 
309
        """Return the policy for the given (section, option_name) pair."""
 
310
        return POLICY_NONE
 
311
 
262
312
    def _get_signature_checking(self):
263
313
        """See Config._get_signature_checking."""
264
314
        policy = self._get_user_option('check_signatures')
277
327
 
278
328
    def _get_user_option(self, option_name):
279
329
        """See Config._get_user_option."""
280
 
        try:
281
 
            return self._get_parser().get_value(self._get_section(),
282
 
                                                option_name)
283
 
        except KeyError:
284
 
            pass
 
330
        for (section, extra_path) in self._get_matching_sections():
 
331
            try:
 
332
                value = self._get_parser().get_value(section, option_name)
 
333
            except KeyError:
 
334
                continue
 
335
            policy = self._get_option_policy(section, option_name)
 
336
            if policy == POLICY_NONE:
 
337
                return value
 
338
            elif policy == POLICY_NORECURSE:
 
339
                # norecurse items only apply to the exact path
 
340
                if extra_path:
 
341
                    continue
 
342
                else:
 
343
                    return value
 
344
            elif policy == POLICY_APPENDPATH:
 
345
                if extra_path:
 
346
                    value = urlutils.join(value, extra_path)
 
347
                return value
 
348
            else:
 
349
                raise AssertionError('Unexpected config policy %r' % policy)
 
350
        else:
 
351
            return None
285
352
 
286
353
    def _gpg_signing_command(self):
287
354
        """See Config.gpg_signing_command."""
379
446
            location = urlutils.local_path_from_url(location)
380
447
        self.location = location
381
448
 
382
 
    def _get_section(self):
383
 
        """Get the section we should look in for config items.
384
 
 
385
 
        Returns None if none exists. 
386
 
        TODO: perhaps return a NullSection that thunks through to the 
387
 
              global config.
388
 
        """
 
449
    def _get_matching_sections(self):
 
450
        """Return an ordered list of section names matching this location."""
389
451
        sections = self._get_parser()
390
452
        location_names = self.location.split('/')
391
453
        if self.location.endswith('/'):
415
477
            # if section is longer, no match.
416
478
            if len(section_names) > len(location_names):
417
479
                continue
418
 
            # if path is longer, and recurse is not true, no match
419
 
            if len(section_names) < len(location_names):
420
 
                try:
421
 
                    if not self._get_parser()[section].as_bool('recurse'):
422
 
                        continue
423
 
                except KeyError:
424
 
                    pass
425
 
            matches.append((len(section_names), section))
426
 
        if not len(matches):
427
 
            return None
 
480
            matches.append((len(section_names), section,
 
481
                            '/'.join(location_names[len(section_names):])))
428
482
        matches.sort(reverse=True)
429
 
        return matches[0][1]
430
 
 
431
 
    def set_user_option(self, option, value):
 
483
        sections = []
 
484
        for (length, section, extra_path) in matches:
 
485
            sections.append((section, extra_path))
 
486
            # should we stop looking for parent configs here?
 
487
            try:
 
488
                if self._get_parser()[section].as_bool('ignore_parents'):
 
489
                    break
 
490
            except KeyError:
 
491
                pass
 
492
        return sections
 
493
 
 
494
    def _get_option_policy(self, section, option_name):
 
495
        """Return the policy for the given (section, option_name) pair."""
 
496
        # check for the old 'recurse=False' flag
 
497
        try:
 
498
            recurse = self._get_parser()[section].as_bool('recurse')
 
499
        except KeyError:
 
500
            recurse = True
 
501
        if not recurse:
 
502
            return POLICY_NORECURSE
 
503
 
 
504
        policy_key = option_name + ':policy'
 
505
        try:
 
506
            policy_name = self._get_parser()[section][policy_key]
 
507
        except KeyError:
 
508
            policy_name = None
 
509
 
 
510
        return _policy_value[policy_name]
 
511
 
 
512
    def _set_option_policy(self, section, option_name, option_policy):
 
513
        """Set the policy for the given option name in the given section."""
 
514
        # The old recurse=False option affects all options in the
 
515
        # section.  To handle multiple policies in the section, we
 
516
        # need to convert it to a policy_norecurse key.
 
517
        try:
 
518
            recurse = self._get_parser()[section].as_bool('recurse')
 
519
        except KeyError:
 
520
            pass
 
521
        else:
 
522
            symbol_versioning.warn(
 
523
                'The recurse option is deprecated as of 0.14.  '
 
524
                'The section "%s" has been converted to use policies.'
 
525
                % section,
 
526
                DeprecationWarning)
 
527
            del self._get_parser()[section]['recurse']
 
528
            if not recurse:
 
529
                for key in self._get_parser()[section].keys():
 
530
                    if not key.endswith(':policy'):
 
531
                        self._get_parser()[section][key +
 
532
                                                    ':policy'] = 'norecurse'
 
533
 
 
534
        policy_key = option_name + ':policy'
 
535
        policy_name = _policy_name[option_policy]
 
536
        if policy_name is not None:
 
537
            self._get_parser()[section][policy_key] = policy_name
 
538
        else:
 
539
            if policy_key in self._get_parser()[section]:
 
540
                del self._get_parser()[section][policy_key]
 
541
 
 
542
    def set_user_option(self, option, value, store=STORE_LOCATION):
432
543
        """Save option and its value in the configuration."""
 
544
        assert store in [STORE_LOCATION,
 
545
                         STORE_LOCATION_NORECURSE,
 
546
                         STORE_LOCATION_APPENDPATH], 'bad storage policy'
433
547
        # FIXME: RBC 20051029 This should refresh the parser and also take a
434
548
        # file lock on locations.conf.
435
549
        conf_dir = os.path.dirname(self._get_filename())
443
557
        elif location + '/' in self._get_parser():
444
558
            location = location + '/'
445
559
        self._get_parser()[location][option]=value
 
560
        # the allowed values of store match the config policies
 
561
        self._set_option_policy(location, option, store)
446
562
        self._get_parser().write(file(self._get_filename(), 'wb'))
447
563
 
448
564
 
523
639
                return value
524
640
        return None
525
641
 
526
 
    def set_user_option(self, name, value, local=False):
527
 
        if local is True:
528
 
            self._get_location_config().set_user_option(name, value)
529
 
        else:
 
642
    def set_user_option(self, name, value, store=STORE_BRANCH):
 
643
        if store == STORE_BRANCH:
530
644
            self._get_branch_data_config().set_option(value, name)
531
 
 
 
645
        elif store == STORE_GLOBAL:
 
646
            self._get_global_config().set_user_option(name, value)
 
647
        else:
 
648
            self._get_location_config().set_user_option(name, value, store)
532
649
 
533
650
    def _gpg_signing_command(self):
534
651
        """See Config.gpg_signing_command."""
552
669
        value = self._get_explicit_nickname()
553
670
        if value is not None:
554
671
            return value
555
 
        return self.branch.base.split('/')[-2]
 
672
        return urlutils.unescape(self.branch.base.split('/')[-2])
556
673
 
557
674
    def has_explicit_nickname(self):
558
675
        """Return true if a nickname has been explicitly assigned."""
594
711
    base = os.environ.get('BZR_HOME', None)
595
712
    if sys.platform == 'win32':
596
713
        if base is None:
597
 
            base = os.environ.get('APPDATA', None)
 
714
            base = win32utils.get_appdata_location_unicode()
598
715
        if base is None:
599
716
            base = os.environ.get('HOME', None)
600
717
        if base is None:
601
718
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA, or HOME set')
602
 
        return pathjoin(base, 'bazaar', '2.0')
 
719
        return osutils.pathjoin(base, 'bazaar', '2.0')
603
720
    else:
604
721
        # cygwin, linux, and darwin all have a $HOME directory
605
722
        if base is None:
606
723
            base = os.path.expanduser("~")
607
 
        return pathjoin(base, ".bazaar")
 
724
        return osutils.pathjoin(base, ".bazaar")
608
725
 
609
726
 
610
727
def config_filename():
611
728
    """Return per-user configuration ini file filename."""
612
 
    return pathjoin(config_dir(), 'bazaar.conf')
 
729
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
613
730
 
614
731
 
615
732
def branches_config_filename():
616
733
    """Return per-user configuration ini file filename."""
617
 
    return pathjoin(config_dir(), 'branches.conf')
 
734
    return osutils.pathjoin(config_dir(), 'branches.conf')
618
735
 
619
736
 
620
737
def locations_config_filename():
621
738
    """Return per-user configuration ini file filename."""
622
 
    return pathjoin(config_dir(), 'locations.conf')
 
739
    return osutils.pathjoin(config_dir(), 'locations.conf')
623
740
 
624
741
 
625
742
def user_ignore_config_filename():
626
743
    """Return the user default ignore filename"""
627
 
    return pathjoin(config_dir(), 'ignore')
 
744
    return osutils.pathjoin(config_dir(), 'ignore')
628
745
 
629
746
 
630
747
def _auto_user_id():
640
757
    """
641
758
    import socket
642
759
 
643
 
    # XXX: Any good way to get real user name on win32?
 
760
    if sys.platform == 'win32':
 
761
        name = win32utils.get_user_name_unicode()
 
762
        if name is None:
 
763
            raise errors.BzrError("Cannot autodetect user name.\n"
 
764
                                  "Please, set your name with command like:\n"
 
765
                                  'bzr whoami "Your Name <name@domain.com>"')
 
766
        host = win32utils.get_host_name_unicode()
 
767
        if host is None:
 
768
            host = socket.gethostname()
 
769
        return name, (name + '@' + host)
644
770
 
645
771
    try:
646
772
        import pwd
698
824
    """
699
825
    m = re.search(r'[\w+.-]+@[\w+.-]+', e)
700
826
    if not m:
701
 
        raise errors.BzrError("%r doesn't seem to contain "
702
 
                              "a reasonable email address" % e)
 
827
        raise errors.NoEmailInUsername(e)
703
828
    return m.group(0)
704
829
 
705
830
 
715
840
 
716
841
    def _get_config(self):
717
842
        try:
718
 
            obj = ConfigObj(self.branch.control_files.get('branch.conf'), 
 
843
            obj = ConfigObj(self.branch.control_files.get('branch.conf'),
719
844
                            encoding='utf-8')
720
845
        except errors.NoSuchFile:
721
846
            obj = ConfigObj(encoding='utf=8')
727
852
            obj = self._get_config()
728
853
            try:
729
854
                if section is not None:
730
 
                    obj[section]
 
855
                    obj = obj[section]
731
856
                result = obj[name]
732
857
            except KeyError:
733
858
                result = default