Expose extras information in requirements

Starting with oslo.db+Nova, we would like to specify say
oslo.db[fixtures] in Nova's test-requirements. If you see
the proposed review I4131e534d4cb12e4888d398fa4fb7c922e369210
the gate-nova-requirements fails because code in
project-config/jenkins/scripts/project-requirements-change.py
does not understand extras at all and treats both oslo.db
and oslo.db[fixtures] the same. Since that module
uses requirement.py, we should expose the information here
first and then fix project-config after that.

Change-Id: I146baa3ef94cc8bbf29af371786f3ea95a42cb9f
This commit is contained in:
Davanum Srinivas 2015-10-20 08:26:49 -04:00
parent 432b900a72
commit 33636c1d81
2 changed files with 32 additions and 3 deletions

View File

@ -31,8 +31,16 @@ _REQS_HEADER = [
]
Requirement = collections.namedtuple(
'Requirement', ['package', 'location', 'specifiers', 'markers', 'comment'])
class Requirement(collections.namedtuple('Requirement',
['package', 'location', 'specifiers',
'markers', 'comment', 'extras'])):
def __new__(cls, package, location, specifiers, markers, comment,
extras=None):
return super(Requirement, cls).__new__(
cls, package, location, specifiers, markers, comment,
frozenset(extras or ()))
Requirements = collections.namedtuple('Requirements', ['reqs'])
@ -105,6 +113,7 @@ def parse_line(req_line, permit_urls=False):
comment = ''
req_line = req_line[parse_start:marker_pos]
extras = ()
if parse_start:
# We parsed a url before
specifier = ''
@ -112,12 +121,13 @@ def parse_line(req_line, permit_urls=False):
# Pulled out a requirement
parsed = pkg_resources.Requirement.parse(req_line)
name = parsed.project_name
extras = parsed.extras
specifier = str(parsed.specifier)
else:
# Comments / blank lines etc.
name = ''
specifier = ''
return Requirement(name, location, specifier, markers, comment)
return Requirement(name, location, specifier, markers, comment, extras)
def to_content(reqs, marker_sep=';', line_prefix='', prefix=True):

View File

@ -149,6 +149,25 @@ class TestToReqs(testtools.TestCase):
set(reqs.keys()),
)
def test_extras(self):
content = textwrap.dedent("""\
oslo.config>=1.11.0 # Apache-2.0
oslo.concurrency[fixtures]>=1.11.0 # Apache-2.0
oslo.db[fixtures,mysql]>=1.11.0 # Apache-2.0
""")
reqs = requirement.parse(content)
self.assertEqual(
set(['oslo.config', 'oslo.concurrency', 'oslo.db']),
set(reqs.keys()),
)
self.assertEqual(reqs['oslo.config'][0][0].extras, frozenset(()))
self.assertEqual(reqs['oslo.concurrency'][0][0].extras,
frozenset(('fixtures',)))
self.assertEqual(reqs['oslo.db'][0][0].extras,
frozenset(('fixtures', 'mysql')))
self.assertItemsEqual(reqs,
['oslo.config', 'oslo.concurrency', 'oslo.db'])
class TestCanonicalName(testtools.TestCase):