blob: ebe6a19b4061df8d62333fc9520c1b153d57adae [file] [log] [blame]
# -*- coding: utf-8 -*-
# repoman: Herd database analysis
# Copyright 2010-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2 or later
from __future__ import print_function, unicode_literals
import errno
import xml.etree.ElementTree
try:
from xml.parsers.expat import ExpatError
except (SystemExit, KeyboardInterrupt):
raise
except (ImportError, SystemError, RuntimeError, Exception):
# broken or missing xml support
# https://bugs.python.org/issue14988
# This means that python is built without xml support.
# We tolerate global scope import failures for optional
# modules, so that ImportModulesTestCase can succeed (or
# possibly alert us about unexpected import failures).
pass
from portage import _encodings, _unicode_encode
from portage.exception import FileNotFound, ParseError, PermissionDenied
from portage import os
from repoman.errors import err
__all__ = [
"make_herd_base", "get_herd_base"
]
def _make_email(nick_name):
if not nick_name.endswith('@gentoo.org'):
nick_name = nick_name + '@gentoo.org'
return nick_name
class HerdBase(object):
def __init__(self, herd_to_emails, all_emails):
self.herd_to_emails = herd_to_emails
self.all_emails = all_emails
def known_herd(self, herd_name):
return herd_name in self.herd_to_emails
def known_maintainer(self, nick_name):
return _make_email(nick_name) in self.all_emails
def maintainer_in_herd(self, nick_name, herd_name):
return _make_email(nick_name) in self.herd_to_emails[herd_name]
class _HerdsTreeBuilder(xml.etree.ElementTree.TreeBuilder):
"""
Implements doctype() as required to avoid deprecation warnings with
>=python-2.7.
"""
def doctype(self, name, pubid, system):
pass
def make_herd_base(filename):
herd_to_emails = dict()
all_emails = set()
try:
xml_tree = xml.etree.ElementTree.parse(
_unicode_encode(
filename, encoding=_encodings['fs'], errors='strict'),
parser=xml.etree.ElementTree.XMLParser(
target=_HerdsTreeBuilder()))
except ExpatError as e:
raise ParseError("metadata.xml: %s" % (e,))
except EnvironmentError as e:
func_call = "open('%s')" % filename
if e.errno == errno.EACCES:
raise PermissionDenied(func_call)
elif e.errno == errno.ENOENT:
raise FileNotFound(filename)
raise
herds = xml_tree.findall('herd')
for h in herds:
_herd_name = h.find('name')
if _herd_name is None:
continue
herd_name = _herd_name.text.strip()
del _herd_name
maintainers = h.findall('maintainer')
herd_emails = set()
for m in maintainers:
_m_email = m.find('email')
if _m_email is None:
continue
m_email = _m_email.text.strip()
herd_emails.add(m_email)
all_emails.add(m_email)
herd_to_emails[herd_name] = herd_emails
return HerdBase(herd_to_emails, all_emails)
def get_herd_base(repoman_settings):
try:
herd_base = make_herd_base(
os.path.join(repoman_settings["PORTDIR"], "metadata/herds.xml"))
except (EnvironmentError, ParseError, PermissionDenied) as e:
err(str(e))
except FileNotFound:
# TODO: Download as we do for metadata.dtd, but add a way to
# disable for non-gentoo repoman users who may not have herds.
herd_base = None
return herd_base
if __name__ == '__main__':
h = make_herd_base('/usr/portage/metadata/herds.xml')
assert(h.known_herd('sound'))
assert(not h.known_herd('media-sound'))
assert(h.known_maintainer('sping'))
assert(h.known_maintainer('sping@gentoo.org'))
assert(not h.known_maintainer('portage'))
assert(h.maintainer_in_herd('zmedico@gentoo.org', 'tools-portage'))
assert(not h.maintainer_in_herd('pva@gentoo.org', 'tools-portage'))
import pprint
pprint.pprint(h.herd_to_emails)