~ubuntu-branches/ubuntu/natty/bzr/natty-proposed

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2010-08-07 00:54:52 UTC
  • mfrom: (1.4.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100807005452-g4zb99ezl3xn44r4
Tags: 2.2.0-1
* New upstream release.
 + Adds support for setting timestamps to originating revisions.
   Closes: #473450
 + Removes remaining string exception. Closes: #585193, LP: #586926
 + Add C extension to work around Python issue 1628205. LP: #583941,
   Closes: #577110
 + Avoids showing progress bars when --quiet is used. Closes: #542105,
   LP: #320035
 + No longer creates ~/.bazaar as root when run under sudo. LP: #376388
 + 'bzr commit' now supports -p as alternative for --show-diff. LP: #571467
 + 'bzr add' no longer adds .THIS/.BASE/.THEIRS files unless
   explicitly requested. LP: #322767
 + When parsing patch files, Bazaar now supports diff lines before each
   patch. LP: #502076
 + WorkingTrees now no longer requires using signal.signal, so can
   be used in a threaded environment. LP: #521989
 + An assertion error is no longer triggered when pushing to a pre-1.6
   Bazaar server. LP: #528041
* Bump standards version to 3.9.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
 
75
75
import bzrlib
76
76
from bzrlib import (
 
77
    atomicfile,
77
78
    debug,
78
79
    errors,
79
80
    mail_client,
193
194
            interpreted as a boolean. Returns True or False otherwise.
194
195
        """
195
196
        s = self._get_user_option(option_name)
196
 
        return ui.bool_from_string(s)
 
197
        if s is None:
 
198
            # The option doesn't exist
 
199
            return None
 
200
        val = ui.bool_from_string(s)
 
201
        if val is None:
 
202
            # The value can't be interpreted as a boolean
 
203
            trace.warning('Value "%s" is not a boolean for "%s"',
 
204
                          s, option_name)
 
205
        return val
197
206
 
198
207
    def get_user_option_as_list(self, option_name):
199
208
        """Get a generic option as a list - no special process, no default.
249
258
 
250
259
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
251
260
 
252
 
        $BZR_EMAIL can be set to override this (as well as the
253
 
        deprecated $BZREMAIL), then
 
261
        $BZR_EMAIL can be set to override this, then
254
262
        the concrete policy type is checked, and finally
255
263
        $EMAIL is examined.
256
 
        If none is found, a reasonable default is (hopefully)
257
 
        created.
 
264
        If no username can be found, errors.NoWhoami exception is raised.
258
265
 
259
266
        TODO: Check it's reasonably well-formed.
260
267
        """
270
277
        if v:
271
278
            return v.decode(osutils.get_user_encoding())
272
279
 
273
 
        name, email = _auto_user_id()
274
 
        if name:
275
 
            return '%s <%s>' % (name, email)
276
 
        else:
277
 
            return email
 
280
        raise errors.NoWhoami()
 
281
 
 
282
    def ensure_username(self):
 
283
        """Raise errors.NoWhoami if username is not set.
 
284
 
 
285
        This method relies on the username() function raising the error.
 
286
        """
 
287
        self.username()
278
288
 
279
289
    def signature_checking(self):
280
290
        """What is the current policy for signature checking?."""
468
478
    def _get_nickname(self):
469
479
        return self.get_user_option('nickname')
470
480
 
 
481
    def _write_config_file(self):
 
482
        filename = self._get_filename()
 
483
        atomic_file = atomicfile.AtomicFile(filename)
 
484
        self._get_parser().write(atomic_file)
 
485
        atomic_file.commit()
 
486
        atomic_file.close()
 
487
        osutils.copy_ownership_from_path(filename)
 
488
 
471
489
 
472
490
class GlobalConfig(IniBasedConfig):
473
491
    """The configuration that should be used for a specific location."""
509
527
        self._get_parser().setdefault(section, {})[option] = value
510
528
        self._write_config_file()
511
529
 
512
 
    def _write_config_file(self):
513
 
        f = open(self._get_filename(), 'wb')
514
 
        self._get_parser().write(f)
515
 
        f.close()
516
 
 
517
530
 
518
531
class LocationConfig(IniBasedConfig):
519
532
    """A configuration object that gives the policy for a location."""
653
666
        self._get_parser()[location][option]=value
654
667
        # the allowed values of store match the config policies
655
668
        self._set_option_policy(location, option, store)
656
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
669
        self._write_config_file()
657
670
 
658
671
 
659
672
class BranchConfig(Config):
810
823
            os.mkdir(parent_dir)
811
824
        trace.mutter('creating config directory: %r', path)
812
825
        os.mkdir(path)
 
826
        osutils.copy_ownership_from_path(path)
813
827
 
814
828
 
815
829
def config_dir():
830
844
                                  ' or HOME set')
831
845
        return osutils.pathjoin(base, 'bazaar', '2.0')
832
846
    else:
833
 
        # cygwin, linux, and darwin all have a $HOME directory
834
847
        if base is None:
835
848
            base = os.path.expanduser("~")
836
849
        return osutils.pathjoin(base, ".bazaar")
866
879
 
867
880
    This doesn't implicitly create it.
868
881
 
869
 
    On Windows it's in the config directory; elsewhere in the XDG cache directory.
 
882
    On Windows it's in the config directory; elsewhere it's /var/crash
 
883
    which may be monitored by apport.  It can be overridden by
 
884
    $APPORT_CRASH_DIR.
870
885
    """
871
886
    if sys.platform == 'win32':
872
887
        return osutils.pathjoin(config_dir(), 'Crash')
873
888
    else:
874
 
        return osutils.pathjoin(xdg_cache_dir(), 'crash')
 
889
        # XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
 
890
        # 2010-01-31
 
891
        return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
875
892
 
876
893
 
877
894
def xdg_cache_dir():
884
901
        return os.path.expanduser('~/.cache')
885
902
 
886
903
 
887
 
def _auto_user_id():
888
 
    """Calculate automatic user identification.
889
 
 
890
 
    Returns (realname, email).
891
 
 
892
 
    Only used when none is set in the environment or the id file.
893
 
 
894
 
    This previously used the FQDN as the default domain, but that can
895
 
    be very slow on machines where DNS is broken.  So now we simply
896
 
    use the hostname.
897
 
    """
898
 
    import socket
899
 
 
900
 
    if sys.platform == 'win32':
901
 
        name = win32utils.get_user_name_unicode()
902
 
        if name is None:
903
 
            raise errors.BzrError("Cannot autodetect user name.\n"
904
 
                                  "Please, set your name with command like:\n"
905
 
                                  'bzr whoami "Your Name <name@domain.com>"')
906
 
        host = win32utils.get_host_name_unicode()
907
 
        if host is None:
908
 
            host = socket.gethostname()
909
 
        return name, (name + '@' + host)
910
 
 
911
 
    try:
912
 
        import pwd
913
 
        uid = os.getuid()
914
 
        try:
915
 
            w = pwd.getpwuid(uid)
916
 
        except KeyError:
917
 
            raise errors.BzrCommandError('Unable to determine your name.  '
918
 
                'Please use "bzr whoami" to set it.')
919
 
 
920
 
        # we try utf-8 first, because on many variants (like Linux),
921
 
        # /etc/passwd "should" be in utf-8, and because it's unlikely to give
922
 
        # false positives.  (many users will have their user encoding set to
923
 
        # latin-1, which cannot raise UnicodeError.)
924
 
        try:
925
 
            gecos = w.pw_gecos.decode('utf-8')
926
 
            encoding = 'utf-8'
927
 
        except UnicodeError:
928
 
            try:
929
 
                encoding = osutils.get_user_encoding()
930
 
                gecos = w.pw_gecos.decode(encoding)
931
 
            except UnicodeError:
932
 
                raise errors.BzrCommandError('Unable to determine your name.  '
933
 
                   'Use "bzr whoami" to set it.')
934
 
        try:
935
 
            username = w.pw_name.decode(encoding)
936
 
        except UnicodeError:
937
 
            raise errors.BzrCommandError('Unable to determine your name.  '
938
 
                'Use "bzr whoami" to set it.')
939
 
 
940
 
        comma = gecos.find(',')
941
 
        if comma == -1:
942
 
            realname = gecos
943
 
        else:
944
 
            realname = gecos[:comma]
945
 
        if not realname:
946
 
            realname = username
947
 
 
948
 
    except ImportError:
949
 
        import getpass
950
 
        try:
951
 
            user_encoding = osutils.get_user_encoding()
952
 
            realname = username = getpass.getuser().decode(user_encoding)
953
 
        except UnicodeDecodeError:
954
 
            raise errors.BzrError("Can't decode username as %s." % \
955
 
                    user_encoding)
956
 
 
957
 
    return realname, (username + '@' + socket.gethostname())
958
 
 
959
 
 
960
904
def parse_username(username):
961
905
    """Parse e-mail username and return a (name, address) tuple."""
962
906
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1048
992
        """Save the config file, only tests should use it for now."""
1049
993
        conf_dir = os.path.dirname(self._filename)
1050
994
        ensure_config_dir_exists(conf_dir)
1051
 
        self._get_config().write(file(self._filename, 'wb'))
 
995
        f = file(self._filename, 'wb')
 
996
        try:
 
997
            self._get_config().write(f)
 
998
        finally:
 
999
            f.close()
1052
1000
 
1053
1001
    def _set_option(self, section_name, option_name, value):
1054
1002
        """Set an authentication configuration option"""
1402
1350
 
1403
1351
 
1404
1352
class PlainTextCredentialStore(CredentialStore):
1405
 
    """Plain text credential store for the authentication.conf file."""
 
1353
    __doc__ = """Plain text credential store for the authentication.conf file"""
1406
1354
 
1407
1355
    def decode_password(self, credentials):
1408
1356
        """See CredentialStore.decode_password."""
1502
1450
            return StringIO()
1503
1451
 
1504
1452
    def _get_configobj(self):
1505
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1453
        f = self._get_config_file()
 
1454
        try:
 
1455
            return ConfigObj(f, encoding='utf-8')
 
1456
        finally:
 
1457
            f.close()
1506
1458
 
1507
1459
    def _set_configobj(self, configobj):
1508
1460
        out_file = StringIO()