/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 breezy/config.py

  • Committer: Jelmer Vernooij
  • Date: 2019-03-05 07:32:38 UTC
  • mto: (7290.1.21 work)
  • mto: This revision was merged to the branch mainline in revision 7311.
  • Revision ID: jelmer@jelmer.uk-20190305073238-zlqn981opwnqsmzi
Add appveyor configuration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
up=pull
75
75
"""
76
76
 
 
77
from __future__ import absolute_import
77
78
import os
78
79
import sys
79
80
 
80
81
import configobj
81
 
from io import BytesIO
82
82
 
83
83
import breezy
84
84
from .lazy_import import lazy_import
90
90
import stat
91
91
 
92
92
from breezy import (
93
 
    cmdline,
 
93
    atomicfile,
94
94
    controldir,
95
95
    debug,
96
96
    directory_service,
108
108
""")
109
109
from . import (
110
110
    commands,
111
 
    bedding,
112
111
    errors,
113
112
    hooks,
114
113
    lazy_regex,
115
114
    registry,
116
115
    )
 
116
from .sixish import (
 
117
    binary_type,
 
118
    BytesIO,
 
119
    PY3,
 
120
    string_types,
 
121
    text_type,
 
122
    )
117
123
 
118
124
 
119
125
CHECK_IF_POSSIBLE = 0
226
232
        errors.BzrError.__init__(self, option_name=option_name)
227
233
 
228
234
 
 
235
class NoWhoami(errors.BzrError):
 
236
 
 
237
    _fmt = ('Unable to determine your name.\n'
 
238
            "Please, set your name with the 'whoami' command.\n"
 
239
            'E.g. brz whoami "Your Name <name@example.com>"')
 
240
 
 
241
 
229
242
def signature_policy_from_unicode(signature_string):
230
243
    """Convert a string to a signing policy."""
231
244
    if signature_string.lower() == 'check-available':
250
263
                     % signature_string)
251
264
 
252
265
 
 
266
def _has_decode_bug():
 
267
    """True if configobj will fail to decode to unicode on Python 2."""
 
268
    if sys.version_info > (3,):
 
269
        return False
 
270
    conf = configobj.ConfigObj()
 
271
    decode = getattr(conf, "_decode", None)
 
272
    if decode:
 
273
        result = decode(b"\xc2\xa7", "utf-8")
 
274
        if isinstance(result[0], str):
 
275
            return True
 
276
    return False
 
277
 
 
278
 
253
279
def _has_triplequote_bug():
254
280
    """True if triple quote logic is reversed, see lp:710410."""
255
281
    conf = configobj.ConfigObj()
267
293
                                        interpolation=False,
268
294
                                        **kwargs)
269
295
 
 
296
    if _has_decode_bug():
 
297
        def _decode(self, infile, encoding):
 
298
            if isinstance(infile, str) and encoding:
 
299
                return infile.decode(encoding).splitlines(True)
 
300
            return super(ConfigObj, self)._decode(infile, encoding)
 
301
 
270
302
    if _has_triplequote_bug():
271
303
        def _get_triple_quote(self, value):
272
304
            quot = super(ConfigObj, self)._get_triple_quote(value)
302
334
        cmd = self._get_change_editor()
303
335
        if cmd is None:
304
336
            return None
305
 
        cmd = cmd.replace('@old_path', '{old_path}')
306
 
        cmd = cmd.replace('@new_path', '{new_path}')
307
 
        cmd = cmdline.split(cmd)
308
 
        if '{old_path}' not in cmd:
309
 
            cmd.extend(['{old_path}', '{new_path}'])
310
337
        return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
311
338
                                             sys.stdout)
312
339
 
493
520
            otherwise.
494
521
        """
495
522
        l = self.get_user_option(option_name, expand=expand)
496
 
        if isinstance(l, str):
 
523
        if isinstance(l, string_types):
497
524
            # A single value, most probably the user forgot (or didn't care to
498
525
            # add) the final ','
499
526
            l = [l]
529
556
 
530
557
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
531
558
 
532
 
        $BRZ_EMAIL or $BZR_EMAIL can be set to override this, then
 
559
        $BRZ_EMAIL can be set to override this, then
533
560
        the concrete policy type is checked, and finally
534
561
        $EMAIL is examined.
535
562
        If no username can be found, NoWhoami exception is raised.
536
563
        """
537
 
        v = os.environ.get('BRZ_EMAIL') or os.environ.get('BZR_EMAIL')
 
564
        v = os.environ.get('BRZ_EMAIL')
538
565
        if v:
 
566
            if not PY3:
 
567
                v = v.decode(osutils.get_user_encoding())
539
568
            return v
540
569
        v = self._get_user_id()
541
570
        if v:
542
571
            return v
543
 
        return bedding.default_email()
 
572
        return default_email()
 
573
 
 
574
    def ensure_username(self):
 
575
        """Raise NoWhoami if username is not set.
 
576
 
 
577
        This method relies on the username() function raising the error.
 
578
        """
 
579
        self.username()
544
580
 
545
581
    def get_alias(self, value):
546
582
        return self._get_alias(value)
701
737
        return conf
702
738
 
703
739
    def _create_from_string(self, str_or_unicode, save):
704
 
        if isinstance(str_or_unicode, str):
 
740
        if isinstance(str_or_unicode, text_type):
705
741
            str_or_unicode = str_or_unicode.encode('utf-8')
706
742
        self._content = BytesIO(str_or_unicode)
707
743
        # Some tests use in-memory configs, some other always need the config
808
844
        return POLICY_NONE
809
845
 
810
846
    def _get_change_editor(self):
811
 
        return self.get_user_option('change_editor', expand=False)
 
847
        return self.get_user_option('change_editor')
812
848
 
813
849
    def _get_signature_checking(self):
814
850
        """See Config._get_signature_checking."""
902
938
    def _write_config_file(self):
903
939
        if self.file_name is None:
904
940
            raise AssertionError('We cannot save, self.file_name is None')
905
 
        from . import atomicfile
906
941
        conf_dir = os.path.dirname(self.file_name)
907
 
        bedding.ensure_config_dir_exists(conf_dir)
 
942
        ensure_config_dir_exists(conf_dir)
908
943
        with atomicfile.AtomicFile(self.file_name) as atomic_file:
909
944
            self._get_parser().write(atomic_file)
910
945
        osutils.copy_ownership_from_path(self.file_name)
964
999
 
965
1000
        If the directory doesn't exist it is created.
966
1001
        """
967
 
        bedding.ensure_config_dir_exists(self.dir)
 
1002
        ensure_config_dir_exists(self.dir)
968
1003
        token = self._lock.lock_write(token)
969
1004
        return lock.LogicalLockResult(self.unlock, token)
970
1005
 
991
1026
    """The configuration that should be used for a specific location."""
992
1027
 
993
1028
    def __init__(self):
994
 
        super(GlobalConfig, self).__init__(file_name=bedding.config_path())
 
1029
        super(GlobalConfig, self).__init__(file_name=config_filename())
995
1030
 
996
1031
    def config_id(self):
997
1032
        return 'breezy'
1123
1158
 
1124
1159
    def __init__(self, location):
1125
1160
        super(LocationConfig, self).__init__(
1126
 
            file_name=bedding.locations_config_path())
 
1161
            file_name=locations_config_filename())
1127
1162
        # local file locations are looked up by local path, rather than
1128
1163
        # by file url. This is because the config file is a user
1129
1164
        # file, and we would rather not expose the user to file urls.
1395
1430
        return self._get_best_value('_acceptable_keys')
1396
1431
 
1397
1432
 
 
1433
def ensure_config_dir_exists(path=None):
 
1434
    """Make sure a configuration directory exists.
 
1435
    This makes sure that the directory exists.
 
1436
    On windows, since configuration directories are 2 levels deep,
 
1437
    it makes sure both the directory and the parent directory exists.
 
1438
    """
 
1439
    if path is None:
 
1440
        path = config_dir()
 
1441
    if not os.path.isdir(path):
 
1442
        if sys.platform == 'win32':
 
1443
            parent_dir = os.path.dirname(path)
 
1444
            if not os.path.isdir(parent_dir):
 
1445
                trace.mutter(
 
1446
                    'creating config parent directory: %r', parent_dir)
 
1447
                os.mkdir(parent_dir)
 
1448
        trace.mutter('creating config directory: %r', path)
 
1449
        os.mkdir(path)
 
1450
        osutils.copy_ownership_from_path(path)
 
1451
 
 
1452
 
 
1453
def bazaar_config_dir():
 
1454
    """Return per-user configuration directory as unicode string
 
1455
 
 
1456
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1457
    and Linux.  On Mac OS X and Linux, if there is a $XDG_CONFIG_HOME/bazaar
 
1458
    directory, that will be used instead
 
1459
 
 
1460
    TODO: Global option --config-dir to override this.
 
1461
    """
 
1462
    base = osutils.path_from_environ('BZR_HOME')
 
1463
    if sys.platform == 'win32':
 
1464
        if base is None:
 
1465
            base = win32utils.get_appdata_location()
 
1466
        if base is None:
 
1467
            base = win32utils.get_home_location()
 
1468
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1469
    if base is None:
 
1470
        xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
 
1471
        if xdg_dir is None:
 
1472
            xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
 
1473
        xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1474
        if osutils.isdir(xdg_dir):
 
1475
            trace.mutter(
 
1476
                "Using configuration in XDG directory %s." % xdg_dir)
 
1477
            return xdg_dir
 
1478
        base = osutils._get_home_dir()
 
1479
    return osutils.pathjoin(base, ".bazaar")
 
1480
 
 
1481
 
 
1482
def _config_dir():
 
1483
    """Return per-user configuration directory as unicode string
 
1484
 
 
1485
    By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
 
1486
    Mac OS X and Linux. If the breezy config directory doesn't exist but
 
1487
    the bazaar one (see bazaar_config_dir()) does, use that instead.
 
1488
    """
 
1489
    # TODO: Global option --config-dir to override this.
 
1490
    base = osutils.path_from_environ('BRZ_HOME')
 
1491
    if sys.platform == 'win32':
 
1492
        if base is None:
 
1493
            base = win32utils.get_appdata_location()
 
1494
        if base is None:
 
1495
            base = win32utils.get_home_location()
 
1496
    if base is None:
 
1497
        base = osutils.path_from_environ('XDG_CONFIG_HOME')
 
1498
        if base is None:
 
1499
            base = osutils.pathjoin(osutils._get_home_dir(), ".config")
 
1500
    breezy_dir = osutils.pathjoin(base, 'breezy')
 
1501
    if osutils.isdir(breezy_dir):
 
1502
        return (breezy_dir, 'breezy')
 
1503
    # If the breezy directory doesn't exist, but the bazaar one does, use that:
 
1504
    bazaar_dir = bazaar_config_dir()
 
1505
    if osutils.isdir(bazaar_dir):
 
1506
        trace.mutter(
 
1507
            "Using Bazaar configuration directory (%s)", bazaar_dir)
 
1508
        return (bazaar_dir, 'bazaar')
 
1509
    return (breezy_dir, 'breezy')
 
1510
 
 
1511
 
 
1512
def config_dir():
 
1513
    """Return per-user configuration directory as unicode string
 
1514
 
 
1515
    By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
 
1516
    Mac OS X and Linux. If the breezy config directory doesn't exist but
 
1517
    the bazaar one (see bazaar_config_dir()) does, use that instead.
 
1518
    """
 
1519
    return _config_dir()[0]
 
1520
 
 
1521
 
 
1522
def config_filename():
 
1523
    """Return per-user configuration ini file filename."""
 
1524
    path, kind = _config_dir()
 
1525
    if kind == 'bazaar':
 
1526
        return osutils.pathjoin(path, 'bazaar.conf')
 
1527
    else:
 
1528
        return osutils.pathjoin(path, 'breezy.conf')
 
1529
 
 
1530
 
 
1531
def locations_config_filename():
 
1532
    """Return per-user configuration ini file filename."""
 
1533
    return osutils.pathjoin(config_dir(), 'locations.conf')
 
1534
 
 
1535
 
 
1536
def authentication_config_filename():
 
1537
    """Return per-user authentication ini file filename."""
 
1538
    return osutils.pathjoin(config_dir(), 'authentication.conf')
 
1539
 
 
1540
 
 
1541
def user_ignore_config_filename():
 
1542
    """Return the user default ignore filename"""
 
1543
    return osutils.pathjoin(config_dir(), 'ignore')
 
1544
 
 
1545
 
 
1546
def crash_dir():
 
1547
    """Return the directory name to store crash files.
 
1548
 
 
1549
    This doesn't implicitly create it.
 
1550
 
 
1551
    On Windows it's in the config directory; elsewhere it's /var/crash
 
1552
    which may be monitored by apport.  It can be overridden by
 
1553
    $APPORT_CRASH_DIR.
 
1554
    """
 
1555
    if sys.platform == 'win32':
 
1556
        return osutils.pathjoin(config_dir(), 'Crash')
 
1557
    else:
 
1558
        # XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
 
1559
        # 2010-01-31
 
1560
        return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
 
1561
 
 
1562
 
 
1563
def xdg_cache_dir():
 
1564
    # See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
 
1565
    # Possibly this should be different on Windows?
 
1566
    e = os.environ.get('XDG_CACHE_HOME', None)
 
1567
    if e:
 
1568
        return e
 
1569
    else:
 
1570
        return os.path.expanduser('~/.cache')
 
1571
 
 
1572
 
 
1573
def _get_default_mail_domain(mailname_file='/etc/mailname'):
 
1574
    """If possible, return the assumed default email domain.
 
1575
 
 
1576
    :returns: string mail domain, or None.
 
1577
    """
 
1578
    if sys.platform == 'win32':
 
1579
        # No implementation yet; patches welcome
 
1580
        return None
 
1581
    try:
 
1582
        f = open(mailname_file)
 
1583
    except (IOError, OSError):
 
1584
        return None
 
1585
    try:
 
1586
        domain = f.readline().strip()
 
1587
        return domain
 
1588
    finally:
 
1589
        f.close()
 
1590
 
 
1591
 
 
1592
def default_email():
 
1593
    v = os.environ.get('BRZ_EMAIL')
 
1594
    if v:
 
1595
        if not PY3:
 
1596
            v = v.decode(osutils.get_user_encoding())
 
1597
        return v
 
1598
    v = os.environ.get('EMAIL')
 
1599
    if v:
 
1600
        if not PY3:
 
1601
            v = v.decode(osutils.get_user_encoding())
 
1602
        return v
 
1603
    name, email = _auto_user_id()
 
1604
    if name and email:
 
1605
        return u'%s <%s>' % (name, email)
 
1606
    elif email:
 
1607
        return email
 
1608
    raise NoWhoami()
 
1609
 
 
1610
 
 
1611
def _auto_user_id():
 
1612
    """Calculate automatic user identification.
 
1613
 
 
1614
    :returns: (realname, email), either of which may be None if they can't be
 
1615
    determined.
 
1616
 
 
1617
    Only used when none is set in the environment or the id file.
 
1618
 
 
1619
    This only returns an email address if we can be fairly sure the
 
1620
    address is reasonable, ie if /etc/mailname is set on unix.
 
1621
 
 
1622
    This doesn't use the FQDN as the default domain because that may be
 
1623
    slow, and it doesn't use the hostname alone because that's not normally
 
1624
    a reasonable address.
 
1625
    """
 
1626
    if sys.platform == 'win32':
 
1627
        # No implementation to reliably determine Windows default mail
 
1628
        # address; please add one.
 
1629
        return None, None
 
1630
 
 
1631
    default_mail_domain = _get_default_mail_domain()
 
1632
    if not default_mail_domain:
 
1633
        return None, None
 
1634
 
 
1635
    import pwd
 
1636
    uid = os.getuid()
 
1637
    try:
 
1638
        w = pwd.getpwuid(uid)
 
1639
    except KeyError:
 
1640
        trace.mutter('no passwd entry for uid %d?' % uid)
 
1641
        return None, None
 
1642
 
 
1643
    # we try utf-8 first, because on many variants (like Linux),
 
1644
    # /etc/passwd "should" be in utf-8, and because it's unlikely to give
 
1645
    # false positives.  (many users will have their user encoding set to
 
1646
    # latin-1, which cannot raise UnicodeError.)
 
1647
    gecos = w.pw_gecos
 
1648
    if isinstance(gecos, bytes):
 
1649
        try:
 
1650
            gecos = gecos.decode('utf-8')
 
1651
            encoding = 'utf-8'
 
1652
        except UnicodeError:
 
1653
            try:
 
1654
                encoding = osutils.get_user_encoding()
 
1655
                gecos = gecos.decode(encoding)
 
1656
            except UnicodeError:
 
1657
                trace.mutter("cannot decode passwd entry %s" % w)
 
1658
                return None, None
 
1659
 
 
1660
    username = w.pw_name
 
1661
    if isinstance(username, bytes):
 
1662
        try:
 
1663
            username = username.decode(encoding)
 
1664
        except UnicodeError:
 
1665
            trace.mutter("cannot decode passwd entry %s" % w)
 
1666
            return None, None
 
1667
 
 
1668
    comma = gecos.find(',')
 
1669
    if comma == -1:
 
1670
        realname = gecos
 
1671
    else:
 
1672
        realname = gecos[:comma]
 
1673
 
 
1674
    return realname, (username + '@' + default_mail_domain)
 
1675
 
 
1676
 
1398
1677
def parse_username(username):
1399
1678
    """Parse e-mail username and return a (name, address) tuple."""
1400
1679
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1401
1680
    if match is None:
1402
1681
        return (username, '')
1403
 
    return (match.group(1), match.group(2))
 
1682
    else:
 
1683
        return (match.group(1), match.group(2))
1404
1684
 
1405
1685
 
1406
1686
def extract_email_address(e):
1465
1745
    def __init__(self, _file=None):
1466
1746
        self._config = None  # The ConfigObj
1467
1747
        if _file is None:
1468
 
            self._input = self._filename = bedding.authentication_config_path()
 
1748
            self._filename = authentication_config_filename()
 
1749
            self._input = self._filename = authentication_config_filename()
1469
1750
            self._check_permissions()
1470
1751
        else:
1471
1752
            # Tests can provide a string as _file
1512
1793
    def _save(self):
1513
1794
        """Save the config file, only tests should use it for now."""
1514
1795
        conf_dir = os.path.dirname(self._filename)
1515
 
        bedding.ensure_config_dir_exists(conf_dir)
 
1796
        ensure_config_dir_exists(conf_dir)
1516
1797
        fd = os.open(self._filename, os.O_RDWR | os.O_CREAT, 0o600)
1517
1798
        try:
1518
1799
            f = os.fdopen(fd, 'wb')
2101
2382
                raise AssertionError(
2102
2383
                    'Only empty lists are supported as default values')
2103
2384
            self.default = u','
2104
 
        elif isinstance(default, (bytes, str, bool, int, float)):
 
2385
        elif isinstance(default, (binary_type, text_type, bool, int, float)):
2105
2386
            # Rely on python to convert strings, booleans and integers
2106
2387
            self.default = u'%s' % (default,)
2107
2388
        elif callable(default):
2148
2429
            try:
2149
2430
                # If the env variable is defined, its value takes precedence
2150
2431
                value = os.environ[var]
 
2432
                if not PY3:
 
2433
                    value = value.decode(osutils.get_user_encoding())
2151
2434
                break
2152
2435
            except KeyError:
2153
2436
                continue
2159
2442
            try:
2160
2443
                # If the env variable is defined, its value is the default one
2161
2444
                value = os.environ[var]
 
2445
                if not PY3:
 
2446
                    value = value.decode(osutils.get_user_encoding())
2162
2447
                break
2163
2448
            except KeyError:
2164
2449
                continue
2166
2451
            # Otherwise, fallback to the value defined at registration
2167
2452
            if callable(self.default):
2168
2453
                value = self.default()
2169
 
                if not isinstance(value, str):
 
2454
                if not isinstance(value, text_type):
2170
2455
                    raise AssertionError(
2171
2456
                        "Callable default value for '%s' should be unicode"
2172
2457
                        % (self.name))
2251
2536
            invalid=invalid, unquote=False)
2252
2537
 
2253
2538
    def from_unicode(self, unicode_str):
2254
 
        if not isinstance(unicode_str, str):
 
2539
        if not isinstance(unicode_str, string_types):
2255
2540
            raise TypeError
2256
2541
        # Now inject our string directly as unicode. All callers got their
2257
2542
        # value from configobj, so values that need to be quoted are already
2259
2544
        _list_converter_config.reset()
2260
2545
        _list_converter_config._parse([u"list=%s" % (unicode_str,)])
2261
2546
        maybe_list = _list_converter_config['list']
2262
 
        if isinstance(maybe_list, str):
 
2547
        if isinstance(maybe_list, string_types):
2263
2548
            if maybe_list:
2264
2549
                # A single value, most probably the user forgot (or didn't care
2265
2550
                # to add) the final ','
2291
2576
        self.registry = registry
2292
2577
 
2293
2578
    def from_unicode(self, unicode_str):
2294
 
        if not isinstance(unicode_str, str):
 
2579
        if not isinstance(unicode_str, string_types):
2295
2580
            raise TypeError
2296
2581
        try:
2297
2582
            return self.registry.get(unicode_str)
2456
2741
bug tracker was specified.
2457
2742
'''))
2458
2743
option_registry.register(
2459
 
    Option('calculate_revnos', default=True,
2460
 
           from_unicode=bool_from_store,
2461
 
           help='''\
2462
 
Calculate revision numbers if they are not known.
2463
 
 
2464
 
Always show revision numbers, even for branch formats that don't store them
2465
 
natively (such as Git). Calculating the revision number requires traversing
2466
 
the left hand ancestry of the branch and can be slow on very large branches.
2467
 
'''))
2468
 
option_registry.register(
2469
2744
    Option('check_signatures', default=CHECK_IF_POSSIBLE,
2470
2745
           from_unicode=signature_policy_from_unicode,
2471
2746
           help='''\
2514
2789
    Option('editor',
2515
2790
           help='The command called to launch an editor to enter a message.'))
2516
2791
option_registry.register(
2517
 
    Option('email', override_from_env=['BRZ_EMAIL', 'BZR_EMAIL'],
2518
 
           default=bedding.default_email, help='The users identity'))
 
2792
    Option('email', override_from_env=['BRZ_EMAIL'], default=default_email,
 
2793
           help='The users identity'))
2519
2794
option_registry.register(
2520
2795
    Option('gpg_signing_key',
2521
2796
           default=None,
2528
2803
    Option('language',
2529
2804
           help='Language to translate messages into.'))
2530
2805
option_registry.register(
2531
 
    Option('locks.steal_dead', default=True, from_unicode=bool_from_store,
 
2806
    Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2532
2807
           help='''\
2533
2808
Steal locks that appears to be dead.
2534
2809
 
2638
2913
           help="If we wait for a new request from a client for more than"
2639
2914
                " X seconds, consider the client idle, and hangup."))
2640
2915
option_registry.register(
2641
 
    Option('ssh',
2642
 
           default=None, override_from_env=['BRZ_SSH'],
2643
 
           help='SSH vendor to use.'))
2644
 
option_registry.register(
2645
2916
    Option('stacked_on_location',
2646
2917
           default=None,
2647
2918
           help="""The location where this branch is stacked on."""))
2666
2937
           from_unicode=bool_from_store, invalid='warning',
2667
2938
           help='''Whether to validate signatures in brz log.'''))
2668
2939
option_registry.register_lazy('ssl.ca_certs',
2669
 
                              'breezy.transport.http', 'opt_ssl_ca_certs')
 
2940
                              'breezy.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2670
2941
 
2671
2942
option_registry.register_lazy('ssl.cert_reqs',
2672
 
                              'breezy.transport.http', 'opt_ssl_cert_reqs')
 
2943
                              'breezy.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2673
2944
 
2674
2945
 
2675
2946
class Section(object):
2902
3173
            try:
2903
3174
                name, value = over.split('=', 1)
2904
3175
            except ValueError:
2905
 
                raise errors.CommandError(
 
3176
                raise errors.BzrCommandError(
2906
3177
                    gettext("Invalid '%s', should be of the form 'name=value'")
2907
3178
                    % (over,))
2908
3179
            self.options[name] = value
3050
3321
            self._config_obj.list_values = False
3051
3322
 
3052
3323
    def unquote(self, value):
3053
 
        if value and isinstance(value, str):
 
3324
        if value and isinstance(value, string_types):
3054
3325
            # _unquote doesn't handle None nor empty strings nor anything that
3055
3326
            # is not a string, really.
3056
3327
            value = self._config_obj._unquote(value)
3167
3438
    """
3168
3439
 
3169
3440
    def __init__(self, possible_transports=None):
3170
 
        path, kind = bedding._config_dir()
 
3441
        (path, kind) = _config_dir()
3171
3442
        t = transport.get_transport_from_path(
3172
3443
            path, possible_transports=possible_transports)
3173
 
        super(GlobalStore, self).__init__(t, kind + '.conf')
 
3444
        filename = {'bazaar': 'bazaar.conf', 'breezy': 'breezy.conf'}[kind]
 
3445
        super(GlobalStore, self).__init__(t, filename)
3174
3446
        self.id = 'breezy'
3175
3447
 
3176
3448
 
3182
3454
 
3183
3455
    def __init__(self, possible_transports=None):
3184
3456
        t = transport.get_transport_from_path(
3185
 
            bedding.config_dir(), possible_transports=possible_transports)
 
3457
            config_dir(), possible_transports=possible_transports)
3186
3458
        super(LocationStore, self).__init__(t, 'locations.conf')
3187
3459
        self.id = 'locations'
3188
3460
 
3467
3739
            # None or ends up being None during expansion or conversion.
3468
3740
            if val is not None:
3469
3741
                if expand:
3470
 
                    if isinstance(val, str):
 
3742
                    if isinstance(val, string_types):
3471
3743
                        val = self._expand_options_in_string(val)
3472
3744
                    else:
3473
3745
                        trace.warning('Cannot expand "%s":'
3874
4146
        # http://pad.lv/788991 -- vila 20101115
3875
4147
        commands.Option('scope', help='Reduce the scope to the specified'
3876
4148
                        ' configuration file.',
3877
 
                        type=str),
 
4149
                        type=text_type),
3878
4150
        commands.Option('all',
3879
4151
                        help='Display all the defined values for the matching options.',
3880
4152
                        ),
4003
4275
 
4004
4276
    def _remove_config_option(self, name, directory, scope):
4005
4277
        if name is None:
4006
 
            raise errors.CommandError(
 
4278
            raise errors.BzrCommandError(
4007
4279
                '--remove expects an option to remove.')
4008
4280
        conf = self._get_stack(directory, scope, write_access=True)
4009
4281
        try: