279
279
# We need to iterate until no more refs appear ({{foo}} will need two
280
280
# iterations for example).
283
raw_chunks = self.option_ref_re.split(result)
285
import pdb; pdb.set_trace()
282
raw_chunks = self.option_ref_re.split(result)
286
283
if len(raw_chunks) == 1:
287
284
# Shorcut the trivial case: no refs
444
441
the concrete policy type is checked, and finally
445
442
$EMAIL is examined.
446
443
If no username can be found, errors.NoWhoami exception is raised.
448
TODO: Check it's reasonably well-formed.
450
445
v = os.environ.get('BZR_EMAIL')
452
447
return v.decode(osutils.get_user_encoding())
454
448
v = self._get_user_id()
458
451
v = os.environ.get('EMAIL')
460
453
return v.decode(osutils.get_user_encoding())
454
name, email = _auto_user_id()
456
return '%s <%s>' % (name, email)
462
459
raise errors.NoWhoami()
464
461
def ensure_username(self):
970
967
super(LockableConfig, self).remove_user_option(option_name,
970
def _iter_for_location_by_parts(sections, location):
971
"""Keep only the sessions matching the specified location.
973
:param sections: An iterable of section names.
975
:param location: An url or a local path to match against.
977
:returns: An iterator of (section, extra_path, nb_parts) where nb is the
978
number of path components in the section name, section is the section
979
name and extra_path is the difference between location and the section
982
location_parts = location.rstrip('/').split('/')
984
for section in sections:
985
# location is a local path if possible, so we need
986
# to convert 'file://' urls to local paths if necessary.
988
# FIXME: I don't think the above comment is still up to date,
989
# LocationConfig is always instantiated with an url -- vila 2011-04-07
991
# This also avoids having file:///path be a more exact
992
# match than '/path'.
994
# FIXME: Not sure about the above either, but since the path components
995
# are compared in sync, adding two empty components (//) is likely to
996
# trick the comparison and also trick the check on the number of
997
# components, so we *should* take only the relevant part of the url. On
998
# the other hand, this means 'file://' urls *can't* be used in sections
999
# so more work is probably needed -- vila 2011-04-07
1001
if section.startswith('file://'):
1002
section_path = urlutils.local_path_from_url(section)
1004
section_path = section
1005
section_parts = section_path.rstrip('/').split('/')
1008
if len(section_parts) > len(location_parts):
1009
# More path components in the section, they can't match
1012
# Rely on zip truncating in length to the length of the shortest
1013
# argument sequence.
1014
names = zip(location_parts, section_parts)
1016
if not fnmatch.fnmatch(name[0], name[1]):
1021
# build the path difference between the section and the location
1022
extra_path = '/'.join(location_parts[len(section_parts):])
1023
yield section, extra_path, len(section_parts)
974
1026
class LocationConfig(LockableConfig):
975
1027
"""A configuration object that gives the policy for a location."""
1005
1057
def _get_matching_sections(self):
1006
1058
"""Return an ordered list of section names matching this location."""
1007
sections = self._get_parser()
1008
location_names = self.location.split('/')
1009
if self.location.endswith('/'):
1010
del location_names[-1]
1012
for section in sections:
1013
# location is a local path if possible, so we need
1014
# to convert 'file://' urls to local paths if necessary.
1015
# This also avoids having file:///path be a more exact
1016
# match than '/path'.
1017
if section.startswith('file://'):
1018
section_path = urlutils.local_path_from_url(section)
1020
section_path = section
1021
section_names = section_path.split('/')
1022
if section.endswith('/'):
1023
del section_names[-1]
1024
names = zip(location_names, section_names)
1027
if not fnmatch.fnmatch(name[0], name[1]):
1032
# so, for the common prefix they matched.
1033
# if section is longer, no match.
1034
if len(section_names) > len(location_names):
1036
matches.append((len(section_names), section,
1037
'/'.join(location_names[len(section_names):])))
1059
matches = list(_iter_for_location_by_parts(self._get_parser(),
1038
1061
# put the longest (aka more specific) locations first
1039
matches.sort(reverse=True)
1041
for (length, section, extra_path) in matches:
1042
sections.append((section, extra_path))
1063
key=lambda (section, extra_path, length): (length, section),
1065
for (section, extra_path, length) in matches:
1066
yield section, extra_path
1043
1067
# should we stop looking for parent configs here?
1045
1069
if self._get_parser()[section].as_bool('ignore_parents'):
1047
1071
except KeyError:
1051
1074
def _get_sections(self, name=None):
1052
1075
"""See IniBasedConfig._get_sections()."""
1410
1433
return os.path.expanduser('~/.cache')
1436
def _get_default_mail_domain():
1437
"""If possible, return the assumed default email domain.
1439
:returns: string mail domain, or None.
1441
if sys.platform == 'win32':
1442
# No implementation yet; patches welcome
1445
f = open('/etc/mailname')
1446
except (IOError, OSError), e:
1449
domain = f.read().strip()
1455
def _auto_user_id():
1456
"""Calculate automatic user identification.
1458
:returns: (realname, email), either of which may be None if they can't be
1461
Only used when none is set in the environment or the id file.
1463
This only returns an email address if we can be fairly sure the
1464
address is reasonable, ie if /etc/mailname is set on unix.
1466
This doesn't use the FQDN as the default domain because that may be
1467
slow, and it doesn't use the hostname alone because that's not normally
1468
a reasonable address.
1470
if sys.platform == 'win32':
1471
# No implementation to reliably determine Windows default mail
1472
# address; please add one.
1475
default_mail_domain = _get_default_mail_domain()
1476
if not default_mail_domain:
1482
w = pwd.getpwuid(uid)
1484
mutter('no passwd entry for uid %d?' % uid)
1487
# we try utf-8 first, because on many variants (like Linux),
1488
# /etc/passwd "should" be in utf-8, and because it's unlikely to give
1489
# false positives. (many users will have their user encoding set to
1490
# latin-1, which cannot raise UnicodeError.)
1492
gecos = w.pw_gecos.decode('utf-8')
1494
except UnicodeError:
1496
encoding = osutils.get_user_encoding()
1497
gecos = w.pw_gecos.decode(encoding)
1498
except UnicodeError, e:
1499
mutter("cannot decode passwd entry %s" % w)
1502
username = w.pw_name.decode(encoding)
1503
except UnicodeError, e:
1504
mutter("cannot decode passwd entry %s" % w)
1507
comma = gecos.find(',')
1511
realname = gecos[:comma]
1513
return realname, (username + '@' + default_mail_domain)
1413
1516
def parse_username(username):
1414
1517
"""Parse e-mail username and return a (name, address) tuple."""
1415
1518
match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)