/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: Alexander Belchenko
  • Date: 2007-10-26 21:49:15 UTC
  • mto: (2947.4.2 0.92)
  • mto: This revision was merged to the branch mainline in revision 2971.
  • Revision ID: bialix@ukr.net-20071026214915-5eacqh9k2ps6jagj
windows python-based installer: shortcut for uninstall action

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
    mail_client,
 
79
    osutils,
 
80
    symbol_versioning,
 
81
    trace,
 
82
    urlutils,
 
83
    win32utils,
 
84
    )
 
85
import bzrlib.util.configobj.configobj as configobj
 
86
""")
 
87
 
75
88
from bzrlib.trace import mutter, warning
76
 
import bzrlib.util.configobj.configobj as configobj
77
89
 
78
90
 
79
91
CHECK_IF_POSSIBLE=0
86
98
SIGN_NEVER=2
87
99
 
88
100
 
 
101
POLICY_NONE = 0
 
102
POLICY_NORECURSE = 1
 
103
POLICY_APPENDPATH = 2
 
104
 
 
105
_policy_name = {
 
106
    POLICY_NONE: None,
 
107
    POLICY_NORECURSE: 'norecurse',
 
108
    POLICY_APPENDPATH: 'appendpath',
 
109
    }
 
110
_policy_value = {
 
111
    None: POLICY_NONE,
 
112
    'none': POLICY_NONE,
 
113
    'norecurse': POLICY_NORECURSE,
 
114
    'appendpath': POLICY_APPENDPATH,
 
115
    }
 
116
 
 
117
 
 
118
STORE_LOCATION = POLICY_NONE
 
119
STORE_LOCATION_NORECURSE = POLICY_NORECURSE
 
120
STORE_LOCATION_APPENDPATH = POLICY_APPENDPATH
 
121
STORE_BRANCH = 3
 
122
STORE_GLOBAL = 4
 
123
 
 
124
 
89
125
class ConfigObj(configobj.ConfigObj):
90
126
 
91
127
    def get_bool(self, section, key):
108
144
        """Get the users pop up editor."""
109
145
        raise NotImplementedError
110
146
 
 
147
    def get_mail_client(self):
 
148
        """Get a mail client to use"""
 
149
        selected_client = self.get_user_option('mail_client')
 
150
        try:
 
151
            mail_client_class = {
 
152
                None: mail_client.DefaultMail,
 
153
                # Specific clients
 
154
                'evolution': mail_client.Evolution,
 
155
                'kmail': mail_client.KMail,
 
156
                'mutt': mail_client.Mutt,
 
157
                'thunderbird': mail_client.Thunderbird,
 
158
                # Generic options
 
159
                'default': mail_client.DefaultMail,
 
160
                'editor': mail_client.Editor,
 
161
                'mapi': mail_client.MAPIClient,
 
162
                'xdg-email': mail_client.XDGEmail,
 
163
            }[selected_client]
 
164
        except KeyError:
 
165
            raise errors.UnknownMailClient(selected_client)
 
166
        return mail_client_class(self)
 
167
 
111
168
    def _get_signature_checking(self):
112
169
        """Template method to override signature checking policy."""
113
170
 
238
295
    def _get_nickname(self):
239
296
        return None
240
297
 
 
298
    def get_bzr_remote_path(self):
 
299
        try:
 
300
            return os.environ['BZR_REMOTE_PATH']
 
301
        except KeyError:
 
302
            path = self.get_user_option("bzr_remote_path")
 
303
            if path is None:
 
304
                path = 'bzr'
 
305
            return path
 
306
 
241
307
 
242
308
class IniBasedConfig(Config):
243
309
    """A configuration policy that draws from ini files."""
255
321
            raise errors.ParseConfigError(e.errors, e.config.filename)
256
322
        return self._parser
257
323
 
 
324
    def _get_matching_sections(self):
 
325
        """Return an ordered list of (section_name, extra_path) pairs.
 
326
 
 
327
        If the section contains inherited configuration, extra_path is
 
328
        a string containing the additional path components.
 
329
        """
 
330
        section = self._get_section()
 
331
        if section is not None:
 
332
            return [(section, '')]
 
333
        else:
 
334
            return []
 
335
 
258
336
    def _get_section(self):
259
337
        """Override this to define the section used by the config."""
260
338
        return "DEFAULT"
261
339
 
 
340
    def _get_option_policy(self, section, option_name):
 
341
        """Return the policy for the given (section, option_name) pair."""
 
342
        return POLICY_NONE
 
343
 
262
344
    def _get_signature_checking(self):
263
345
        """See Config._get_signature_checking."""
264
346
        policy = self._get_user_option('check_signatures')
277
359
 
278
360
    def _get_user_option(self, option_name):
279
361
        """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
 
362
        for (section, extra_path) in self._get_matching_sections():
 
363
            try:
 
364
                value = self._get_parser().get_value(section, option_name)
 
365
            except KeyError:
 
366
                continue
 
367
            policy = self._get_option_policy(section, option_name)
 
368
            if policy == POLICY_NONE:
 
369
                return value
 
370
            elif policy == POLICY_NORECURSE:
 
371
                # norecurse items only apply to the exact path
 
372
                if extra_path:
 
373
                    continue
 
374
                else:
 
375
                    return value
 
376
            elif policy == POLICY_APPENDPATH:
 
377
                if extra_path:
 
378
                    value = urlutils.join(value, extra_path)
 
379
                return value
 
380
            else:
 
381
                raise AssertionError('Unexpected config policy %r' % policy)
 
382
        else:
 
383
            return None
285
384
 
286
385
    def _gpg_signing_command(self):
287
386
        """See Config.gpg_signing_command."""
379
478
            location = urlutils.local_path_from_url(location)
380
479
        self.location = location
381
480
 
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
 
        """
 
481
    def _get_matching_sections(self):
 
482
        """Return an ordered list of section names matching this location."""
389
483
        sections = self._get_parser()
390
484
        location_names = self.location.split('/')
391
485
        if self.location.endswith('/'):
415
509
            # if section is longer, no match.
416
510
            if len(section_names) > len(location_names):
417
511
                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
 
512
            matches.append((len(section_names), section,
 
513
                            '/'.join(location_names[len(section_names):])))
428
514
        matches.sort(reverse=True)
429
 
        return matches[0][1]
430
 
 
431
 
    def set_user_option(self, option, value):
 
515
        sections = []
 
516
        for (length, section, extra_path) in matches:
 
517
            sections.append((section, extra_path))
 
518
            # should we stop looking for parent configs here?
 
519
            try:
 
520
                if self._get_parser()[section].as_bool('ignore_parents'):
 
521
                    break
 
522
            except KeyError:
 
523
                pass
 
524
        return sections
 
525
 
 
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
 
529
        try:
 
530
            recurse = self._get_parser()[section].as_bool('recurse')
 
531
        except KeyError:
 
532
            recurse = True
 
533
        if not recurse:
 
534
            return POLICY_NORECURSE
 
535
 
 
536
        policy_key = option_name + ':policy'
 
537
        try:
 
538
            policy_name = self._get_parser()[section][policy_key]
 
539
        except KeyError:
 
540
            policy_name = None
 
541
 
 
542
        return _policy_value[policy_name]
 
543
 
 
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.
 
549
        try:
 
550
            recurse = self._get_parser()[section].as_bool('recurse')
 
551
        except KeyError:
 
552
            pass
 
553
        else:
 
554
            symbol_versioning.warn(
 
555
                'The recurse option is deprecated as of 0.14.  '
 
556
                'The section "%s" has been converted to use policies.'
 
557
                % section,
 
558
                DeprecationWarning)
 
559
            del self._get_parser()[section]['recurse']
 
560
            if not 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'
 
565
 
 
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
 
570
        else:
 
571
            if policy_key in self._get_parser()[section]:
 
572
                del self._get_parser()[section][policy_key]
 
573
 
 
574
    def set_user_option(self, option, value, store=STORE_LOCATION):
432
575
        """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'
433
579
        # FIXME: RBC 20051029 This should refresh the parser and also take a
434
580
        # file lock on locations.conf.
435
581
        conf_dir = os.path.dirname(self._get_filename())
443
589
        elif location + '/' in self._get_parser():
444
590
            location = location + '/'
445
591
        self._get_parser()[location][option]=value
 
592
        # the allowed values of store match the config policies
 
593
        self._set_option_policy(location, option, store)
446
594
        self._get_parser().write(file(self._get_filename(), 'wb'))
447
595
 
448
596
 
523
671
                return value
524
672
        return None
525
673
 
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:
 
674
    def set_user_option(self, name, value, store=STORE_BRANCH,
 
675
        warn_masked=False):
 
676
        if store == STORE_BRANCH:
530
677
            self._get_branch_data_config().set_option(value, name)
 
678
        elif store == STORE_GLOBAL:
 
679
            self._get_global_config().set_user_option(name, value)
 
680
        else:
 
681
            self._get_location_config().set_user_option(name, value, store)
 
682
        if not warn_masked:
 
683
            return
 
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)
 
689
            else:
 
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)
531
696
 
532
697
 
533
698
    def _gpg_signing_command(self):
552
717
        value = self._get_explicit_nickname()
553
718
        if value is not None:
554
719
            return value
555
 
        return self.branch.base.split('/')[-2]
 
720
        return urlutils.unescape(self.branch.base.split('/')[-2])
556
721
 
557
722
    def has_explicit_nickname(self):
558
723
        """Return true if a nickname has been explicitly assigned."""
594
759
    base = os.environ.get('BZR_HOME', None)
595
760
    if sys.platform == 'win32':
596
761
        if base is None:
597
 
            base = os.environ.get('APPDATA', None)
 
762
            base = win32utils.get_appdata_location_unicode()
598
763
        if base is None:
599
764
            base = os.environ.get('HOME', None)
600
765
        if base is None:
601
766
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA, or HOME set')
602
 
        return pathjoin(base, 'bazaar', '2.0')
 
767
        return osutils.pathjoin(base, 'bazaar', '2.0')
603
768
    else:
604
769
        # cygwin, linux, and darwin all have a $HOME directory
605
770
        if base is None:
606
771
            base = os.path.expanduser("~")
607
 
        return pathjoin(base, ".bazaar")
 
772
        return osutils.pathjoin(base, ".bazaar")
608
773
 
609
774
 
610
775
def config_filename():
611
776
    """Return per-user configuration ini file filename."""
612
 
    return pathjoin(config_dir(), 'bazaar.conf')
 
777
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
613
778
 
614
779
 
615
780
def branches_config_filename():
616
781
    """Return per-user configuration ini file filename."""
617
 
    return pathjoin(config_dir(), 'branches.conf')
 
782
    return osutils.pathjoin(config_dir(), 'branches.conf')
618
783
 
619
784
 
620
785
def locations_config_filename():
621
786
    """Return per-user configuration ini file filename."""
622
 
    return pathjoin(config_dir(), 'locations.conf')
 
787
    return osutils.pathjoin(config_dir(), 'locations.conf')
623
788
 
624
789
 
625
790
def user_ignore_config_filename():
626
791
    """Return the user default ignore filename"""
627
 
    return pathjoin(config_dir(), 'ignore')
 
792
    return osutils.pathjoin(config_dir(), 'ignore')
628
793
 
629
794
 
630
795
def _auto_user_id():
640
805
    """
641
806
    import socket
642
807
 
643
 
    # XXX: Any good way to get real user name on win32?
 
808
    if sys.platform == 'win32':
 
809
        name = win32utils.get_user_name_unicode()
 
810
        if name is None:
 
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()
 
815
        if host is None:
 
816
            host = socket.gethostname()
 
817
        return name, (name + '@' + host)
644
818
 
645
819
    try:
646
820
        import pwd
698
872
    """
699
873
    m = re.search(r'[\w+.-]+@[\w+.-]+', e)
700
874
    if not m:
701
 
        raise errors.BzrError("%r doesn't seem to contain "
702
 
                              "a reasonable email address" % e)
 
875
        raise errors.NoEmailInUsername(e)
703
876
    return m.group(0)
704
877
 
705
878
 
715
888
 
716
889
    def _get_config(self):
717
890
        try:
718
 
            obj = ConfigObj(self.branch.control_files.get('branch.conf'), 
 
891
            obj = ConfigObj(self.branch.control_files.get('branch.conf'),
719
892
                            encoding='utf-8')
720
893
        except errors.NoSuchFile:
721
894
            obj = ConfigObj(encoding='utf=8')
727
900
            obj = self._get_config()
728
901
            try:
729
902
                if section is not None:
730
 
                    obj[section]
 
903
                    obj = obj[section]
731
904
                result = obj[name]
732
905
            except KeyError:
733
906
                result = default