Merge "Handle : as well as ; for markers."

This commit is contained in:
Jenkins 2015-06-20 04:36:04 +00:00 committed by Gerrit Code Review
commit 00356aaf1e
2 changed files with 57 additions and 32 deletions

View File

@ -310,28 +310,32 @@ class TestParseRequirement(testtools.TestCase):
scenarios = [
('package', dict(
line='swift',
req=update.Requirement('swift', '', ''))),
req=update.Requirement('swift', '', '', ''))),
('specifier', dict(
line='alembic>=0.4.1',
req=update.Requirement('alembic', '>=0.4.1', ''))),
req=update.Requirement('alembic', '>=0.4.1', '', ''))),
('specifiers', dict(
line='alembic>=0.4.1,!=1.1.8',
req=update.Requirement('alembic', '!=1.1.8,>=0.4.1', ''))),
req=update.Requirement('alembic', '!=1.1.8,>=0.4.1', '', ''))),
('comment-only', dict(
line='# foo',
req=update.Requirement('', '', '# foo'))),
req=update.Requirement('', '', '', '# foo'))),
('comment', dict(
line='Pint>=0.5 # BSD',
req=update.Requirement('Pint', '>=0.5', '# BSD'))),
req=update.Requirement('Pint', '>=0.5', '', '# BSD'))),
('comment-with-semicolon', dict(
line='Pint>=0.5 # BSD;fred',
req=update.Requirement('Pint', '>=0.5', '# BSD;fred'))),
req=update.Requirement('Pint', '>=0.5', '', '# BSD;fred'))),
('case', dict(
line='Babel>=1.3',
req=update.Requirement('Babel', '>=1.3', ''))),
req=update.Requirement('Babel', '>=1.3', '', ''))),
('markers', dict(
line="pywin32;sys_platform=='win32'",
req=update.Requirement('pywin32', '', ";sys_platform=='win32'")))]
req=update.Requirement('pywin32', '', "sys_platform=='win32'", ''))),
('markers-with-comment', dict(
line="Sphinx<=1.2; python_version=='2.7'# Sadface",
req=update.Requirement('Sphinx', '<=1.2', "python_version=='2.7'",
'# Sadface')))]
def test_parse(self):
parsed = update._parse_requirement(self.line)
@ -366,8 +370,8 @@ class TestSyncRequirementsFile(testtools.TestCase):
actions, reqs = update._sync_requirements_file(
global_reqs, project_reqs, 'f', False, False, False)
self.assertEqual(update.Requirements([
update.Requirement('foo', '<2', ";python_version=='2.7'"),
update.Requirement('foo', '>1', ";python_version!='2.7'")]),
update.Requirement('foo', '<2', "python_version=='2.7'", ''),
update.Requirement('foo', '>1', "python_version!='2.7'", '')]),
reqs)
self.assertEqual(update.StdOut(
" foo "
@ -392,9 +396,9 @@ class TestSyncRequirementsFile(testtools.TestCase):
actions, reqs = update._sync_requirements_file(
global_reqs, project_reqs, 'f', False, False, False)
self.assertEqual(update.Requirements([
update.Requirement('foo', '<2', ";python_version=='2.7'"),
update.Requirement('foo', '>1', ";python_version!='2.7'"),
update.Requirement('', '', "# mumbo gumbo")]),
update.Requirement('foo', '<2', "python_version=='2.7'", ''),
update.Requirement('foo', '>1', "python_version!='2.7'", ''),
update.Requirement('', '', '', "# mumbo gumbo")]),
reqs)
self.assertThat(actions, matchers.HasLength(0))
@ -413,9 +417,9 @@ class TestSyncRequirementsFile(testtools.TestCase):
actions, reqs = update._sync_requirements_file(
global_reqs, project_reqs, 'f', False, False, False)
self.assertEqual(update.Requirements([
update.Requirement('foo', '<2', ";python_version=='2.7'"),
update.Requirement('foo', '>1', ";python_version!='2.7'"),
update.Requirement('', '', "# mumbo gumbo")]),
update.Requirement('foo', '<2', "python_version=='2.7'", ''),
update.Requirement('foo', '>1', "python_version!='2.7'", ''),
update.Requirement('', '', '', "# mumbo gumbo")]),
reqs)
self.assertEqual(update.StdOut(
" foo<1.8;python_version=='2.7' -> "
@ -439,8 +443,8 @@ class TestSyncRequirementsFile(testtools.TestCase):
actions, reqs = update._sync_requirements_file(
global_reqs, project_reqs, 'f', False, False, False)
self.assertEqual(update.Requirements([
update.Requirement('foo', '<2', ";python_version=='2.7'"),
update.Requirement('foo', '>1', ";python_version!='2.7'")]),
update.Requirement('foo', '<2', "python_version=='2.7'", ''),
update.Requirement('foo', '>1', "python_version!='2.7'", '')]),
reqs)
self.assertThat(actions, matchers.HasLength(0))
@ -457,10 +461,23 @@ class TestSyncRequirementsFile(testtools.TestCase):
actions, reqs = update._sync_requirements_file(
global_reqs, project_reqs, 'f', False, False, False)
self.assertEqual(update.Requirements([
update.Requirement('foo', '>1', "")]),
update.Requirement('foo', '>1', "", '')]),
reqs)
self.assertEqual(update.StdOut(
" foo<2;python_version=='2.7' -> foo>1\n"), actions[2])
self.assertEqual(update.StdOut(
" foo>1;python_version!='2.7' -> \n"), actions[3])
self.assertThat(actions, matchers.HasLength(4))
class TestReqsToContent(testtools.TestCase):
def test_smoke(self):
reqs = update._reqs_to_content(update.Requirements(
[update.Requirement(
'foo', '<=1', "python_version=='2.7'", '# BSD')]),
marker_sep='!')
self.assertEqual(
''.join(update._REQS_HEADER
+ ["foo<=1!python_version=='2.7' # BSD\n"]),
reqs)

View File

@ -96,7 +96,7 @@ Verbose = collections.namedtuple('Verbose', ['message'])
Requirement = collections.namedtuple(
'Requirement', ['package', 'specifiers', 'comment'])
'Requirement', ['package', 'specifiers', 'markers', 'comment'])
Requirements = collections.namedtuple('Requirements', ['reqs'])
@ -112,18 +112,24 @@ def _parse_requirement(req_line):
They may of course be used by local test configurations, just not
committed into the OpenStack reference branches.
"""
end = len(req_line)
hash_pos = req_line.find('#')
semi_pos = req_line.find(';')
if hash_pos < 0:
hash_pos = semi_pos
if semi_pos < 0:
semi_pos = hash_pos
split_at = min(hash_pos, semi_pos)
if split_at >= 0:
comment = req_line[split_at:]
req_line = req_line[:split_at]
hash_pos = end
if '://' in req_line[:hash_pos]:
# Trigger an early failure before we look for ':'
pkg_resources.Requirement.parse(req_line)
semi_pos = req_line.find(';', 0, hash_pos)
colon_pos = req_line.find(':', 0, hash_pos)
marker_pos = max(semi_pos, colon_pos)
if marker_pos < 0:
marker_pos = hash_pos
markers = req_line[marker_pos + 1:hash_pos].strip()
if hash_pos != end:
comment = req_line[hash_pos:]
else:
comment = ''
req_line = req_line[:marker_pos]
if req_line:
parsed = pkg_resources.Requirement.parse(req_line)
@ -132,7 +138,7 @@ def _parse_requirement(req_line):
else:
name = ''
specifier = ''
return Requirement(name, specifier, comment)
return Requirement(name, specifier, markers, comment)
def _pass_through(req_line):
@ -173,7 +179,7 @@ def _sync_requirements_file(
continue
elif req is None:
# Unparsable lines.
output_requirements.append(Requirement('', '', req_line))
output_requirements.append(Requirement('', '', '', req_line))
continue
elif not req.package:
# Comment-only lines
@ -260,12 +266,14 @@ def _copy_requires(
return actions
def _reqs_to_content(reqs):
def _reqs_to_content(reqs, marker_sep=';'):
lines = list(_REQS_HEADER)
for req in reqs.reqs:
comment_p = ' ' if req.package else ''
comment = (comment_p + req.comment if req.comment else '')
lines.append('%s%s%s\n' % (req.package, req.specifiers, comment))
marker = marker_sep + req.markers if req.markers else ''
lines.append(
'%s%s%s%s\n' % (req.package, req.specifiers, marker, comment))
return u''.join(lines)