1395
1429
return self._get_best_value('_acceptable_keys')
1432
def ensure_config_dir_exists(path=None):
1433
"""Make sure a configuration directory exists.
1434
This makes sure that the directory exists.
1435
On windows, since configuration directories are 2 levels deep,
1436
it makes sure both the directory and the parent directory exists.
1440
if not os.path.isdir(path):
1441
if sys.platform == 'win32':
1442
parent_dir = os.path.dirname(path)
1443
if not os.path.isdir(parent_dir):
1444
trace.mutter('creating config parent directory: %r', parent_dir)
1445
os.mkdir(parent_dir)
1446
trace.mutter('creating config directory: %r', path)
1448
osutils.copy_ownership_from_path(path)
1451
def bazaar_config_dir():
1452
"""Return per-user configuration directory as unicode string
1454
By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1455
and Linux. On Mac OS X and Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1456
that will be used instead.
1458
TODO: Global option --config-dir to override this.
1460
base = osutils.path_from_environ('BZR_HOME')
1461
if sys.platform == 'win32':
1463
base = win32utils.get_appdata_location()
1465
base = win32utils.get_home_location()
1466
return osutils.pathjoin(base, 'bazaar', '2.0')
1468
xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1470
xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1471
xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1472
if osutils.isdir(xdg_dir):
1474
"Using configuration in XDG directory %s." % xdg_dir)
1476
base = osutils._get_home_dir()
1477
return osutils.pathjoin(base, ".bazaar")
1481
"""Return per-user configuration directory as unicode string
1483
By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
1484
Mac OS X and Linux. If the breezy config directory doesn't exist but
1485
the bazaar one (see bazaar_config_dir()) does, use that instead.
1487
# TODO: Global option --config-dir to override this.
1488
base = osutils.path_from_environ('BRZ_HOME')
1489
if sys.platform == 'win32':
1491
base = win32utils.get_appdata_location()
1493
base = win32utils.get_home_location()
1495
base = osutils.path_from_environ('XDG_CONFIG_HOME')
1497
base = osutils.pathjoin(osutils._get_home_dir(), ".config")
1498
breezy_dir = osutils.pathjoin(base, 'breezy')
1499
if osutils.isdir(breezy_dir):
1500
return (breezy_dir, 'breezy')
1501
# If the breezy directory doesn't exist, but the bazaar one does, use that:
1502
bazaar_dir = bazaar_config_dir()
1503
if osutils.isdir(bazaar_dir):
1505
"Using Bazaar configuration directory (%s)", bazaar_dir)
1506
return (bazaar_dir, 'bazaar')
1507
return (breezy_dir, 'breezy')
1511
"""Return per-user configuration directory as unicode string
1513
By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
1514
Mac OS X and Linux. If the breezy config directory doesn't exist but
1515
the bazaar one (see bazaar_config_dir()) does, use that instead.
1517
return _config_dir()[0]
1520
def config_filename():
1521
"""Return per-user configuration ini file filename."""
1522
path, kind = _config_dir()
1523
if kind == 'bazaar':
1524
return osutils.pathjoin(path, 'bazaar.conf')
1526
return osutils.pathjoin(path, 'breezy.conf')
1529
def locations_config_filename():
1530
"""Return per-user configuration ini file filename."""
1531
return osutils.pathjoin(config_dir(), 'locations.conf')
1534
def authentication_config_filename():
1535
"""Return per-user authentication ini file filename."""
1536
return osutils.pathjoin(config_dir(), 'authentication.conf')
1539
def user_ignore_config_filename():
1540
"""Return the user default ignore filename"""
1541
return osutils.pathjoin(config_dir(), 'ignore')
1545
"""Return the directory name to store crash files.
1547
This doesn't implicitly create it.
1549
On Windows it's in the config directory; elsewhere it's /var/crash
1550
which may be monitored by apport. It can be overridden by
1553
if sys.platform == 'win32':
1554
return osutils.pathjoin(config_dir(), 'Crash')
1556
# XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
1558
return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
1561
def xdg_cache_dir():
1562
# See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1563
# Possibly this should be different on Windows?
1564
e = os.environ.get('XDG_CACHE_HOME', None)
1568
return os.path.expanduser('~/.cache')
1571
def _get_default_mail_domain(mailname_file='/etc/mailname'):
1572
"""If possible, return the assumed default email domain.
1574
:returns: string mail domain, or None.
1576
if sys.platform == 'win32':
1577
# No implementation yet; patches welcome
1580
f = open(mailname_file)
1581
except (IOError, OSError) as e:
1584
domain = f.readline().strip()
1590
def default_email():
1591
v = os.environ.get('BRZ_EMAIL')
1594
v = v.decode(osutils.get_user_encoding())
1596
v = os.environ.get('EMAIL')
1599
v = v.decode(osutils.get_user_encoding())
1601
name, email = _auto_user_id()
1603
return u'%s <%s>' % (name, email)
1609
def _auto_user_id():
1610
"""Calculate automatic user identification.
1612
:returns: (realname, email), either of which may be None if they can't be
1615
Only used when none is set in the environment or the id file.
1617
This only returns an email address if we can be fairly sure the
1618
address is reasonable, ie if /etc/mailname is set on unix.
1620
This doesn't use the FQDN as the default domain because that may be
1621
slow, and it doesn't use the hostname alone because that's not normally
1622
a reasonable address.
1624
if sys.platform == 'win32':
1625
# No implementation to reliably determine Windows default mail
1626
# address; please add one.
1629
default_mail_domain = _get_default_mail_domain()
1630
if not default_mail_domain:
1636
w = pwd.getpwuid(uid)
1638
trace.mutter('no passwd entry for uid %d?' % uid)
1641
# we try utf-8 first, because on many variants (like Linux),
1642
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
1643
# false positives. (many users will have their user encoding set to
1644
# latin-1, which cannot raise UnicodeError.)
1646
if isinstance(gecos, bytes):
1648
gecos = gecos.decode('utf-8')
1650
except UnicodeError:
1652
encoding = osutils.get_user_encoding()
1653
gecos = gecos.decode(encoding)
1654
except UnicodeError as e:
1655
trace.mutter("cannot decode passwd entry %s" % w)
1658
username = w.pw_name
1659
if isinstance(username, bytes):
1661
username = username.decode(encoding)
1662
except UnicodeError as e:
1663
trace.mutter("cannot decode passwd entry %s" % w)
1666
comma = gecos.find(',')
1670
realname = gecos[:comma]
1672
return realname, (username + '@' + default_mail_domain)
1398
1675
def parse_username(username):
1399
1676
"""Parse e-mail username and return a (name, address) tuple."""
1400
1677
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1401
1678
if match is None:
1402
1679
return (username, '')
1403
return (match.group(1), match.group(2))
1681
return (match.group(1), match.group(2))
1406
1684
def extract_email_address(e):
1498
1776
trace.mutter('Unable to stat %r: %r', self._filename, e)
1500
1778
mode = stat.S_IMODE(st.st_mode)
1501
if ((stat.S_IXOTH | stat.S_IWOTH | stat.S_IROTH | stat.S_IXGRP
1502
| stat.S_IWGRP | stat.S_IRGRP) & mode):
1779
if ((stat.S_IXOTH | stat.S_IWOTH | stat.S_IROTH | stat.S_IXGRP |
1780
stat.S_IWGRP | stat.S_IRGRP ) & mode):
1503
1781
# Only warn once
1504
if (self._filename not in _authentication_config_permission_errors and
1505
not GlobalConfig().suppress_warning(
1782
if (not self._filename in _authentication_config_permission_errors
1783
and not GlobalConfig().suppress_warning(
1506
1784
'insecure_permissions')):
1507
1785
trace.warning("The file '%s' has insecure "
1508
"file permissions. Saved passwords may be accessible "
1509
"by other users.", self._filename)
1786
"file permissions. Saved passwords may be accessible "
1787
"by other users.", self._filename)
1510
1788
_authentication_config_permission_errors.add(self._filename)
1512
1790
def _save(self):
1513
1791
"""Save the config file, only tests should use it for now."""
1514
1792
conf_dir = os.path.dirname(self._filename)
1515
bedding.ensure_config_dir_exists(conf_dir)
1516
fd = os.open(self._filename, os.O_RDWR | os.O_CREAT, 0o600)
1793
ensure_config_dir_exists(conf_dir)
1794
fd = os.open(self._filename, os.O_RDWR|os.O_CREAT, 0o600)
1518
1796
f = os.fdopen(fd, 'wb')
1519
1797
self._get_config().write(f)
2507
2770
option_registry.register(
2508
2771
ListOption('debug_flags', default=[],
2509
help='Debug flags to activate.'))
2772
help='Debug flags to activate.'))
2510
2773
option_registry.register(
2511
2774
Option('default_format', default='2a',
2512
2775
help='Format used when creating branches.'))
2513
2776
option_registry.register(
2777
Option('dpush_strict', default=None,
2778
from_unicode=bool_from_store,
2780
The default value for ``dpush --strict``.
2782
If present, defines the ``--strict`` option default value for checking
2783
uncommitted changes before pushing into a different VCS without any
2784
custom bzr metadata.
2786
option_registry.register(
2514
2787
Option('editor',
2515
2788
help='The command called to launch an editor to enter a message.'))
2516
2789
option_registry.register(
2517
Option('email', override_from_env=['BRZ_EMAIL', 'BZR_EMAIL'],
2518
default=bedding.default_email, help='The users identity'))
2790
Option('email', override_from_env=['BRZ_EMAIL'], default=default_email,
2791
help='The users identity'))
2519
2792
option_registry.register(
2520
2793
Option('gpg_signing_key',