diff --git a/openstack_requirements/cmds/update.py b/openstack_requirements/cmds/update.py deleted file mode 100644 index 5602c207d8..0000000000 --- a/openstack_requirements/cmds/update.py +++ /dev/null @@ -1,298 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# Copyright 2013 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -A simple script to update the requirements files from a global set of -allowable requirements. - -The script can be called like this: - - $> python update.py ../myproj - -Any requirements listed in the target files will have their versions -updated to match the global requirements. Requirements not in the global -files will be dropped. -""" - -import itertools -import optparse -import os -import os.path -import sys - -from openstack_requirements import project -from openstack_requirements import requirement - -_setup_py_text = """\ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT -import setuptools - -setuptools.setup( - setup_requires=['pbr>=2.0.0'], - pbr=True) -""" - - -# Pure -- - -class Change(object): - def __init__(self, name, old, new): - self.name = name - self.old = old.strip() - self.new = new.strip() - - def __repr__(self): - return "%-30.30s -> %s" % (self.old, self.new) - - -def _check_setup_py(proj): - actions = [] - # If it doesn't have a setup.py, then we don't want to update it - if 'setup.py' not in proj: - return actions - # If it doesn't use pbr, we don't want to update it. - elif 'pbr' not in proj['setup.py']: - return actions - # We don't update pbr's setup.py because it can't use itself. - if 'setup.cfg' in proj and 'name = pbr' in proj['setup.cfg']: - return actions - actions.append(project.Verbose("Syncing setup.py")) - actions.append(project.File('setup.py', _setup_py_text)) - return actions - - -def _sync_requirements_file( - source_reqs, dest_sequence, dest_label, softupdate, hacking, - non_std_reqs, blacklist={}): - actions = [] - dest_reqs = requirement.to_dict(dest_sequence) - changes = [] - output_requirements = [] - processed_packages = set() - - for req, req_line in dest_sequence: - # Skip the instructions header - if req_line in requirement._REQS_HEADER: - continue - elif req is None: - # Unparsable lines. - output_requirements.append( - requirement.Requirement('', '', '', '', req_line.rstrip())) - continue - elif not req.package: - # Comment-only lines - output_requirements.append(req) - continue - elif req.package.lower() in processed_packages: - continue - - processed_packages.add(req.package.lower()) - # Special cases: - # projects need to align hacking version on their own time - if req.package == "hacking" and not hacking: - output_requirements.append(req) - continue - # the overall blacklist is similarly synced by projects as - # needed - if req.package in blacklist: - output_requirements.append(req) - continue - - reference = source_reqs.get(req.package.lower()) - if reference: - actual = dest_reqs.get(req.package.lower()) - for req, ref in itertools.zip_longest(actual, reference): - if not req: - # More in globals - changes.append(Change(ref[0].package, '', ref[1])) - elif not ref: - # less in globals - changes.append(Change(req[0].package, req[1], '')) - elif req[0] != ref[0]: - # NOTE(jamielennox): extras are allowed to be specified in - # a project's requirements and the version be updated and - # extras maintained. Create a new ref object the same as - # the original but with the req's extras. - - merged_ref = requirement.Requirement(ref[0].package, - ref[0].location, - ref[0].specifiers, - ref[0].markers, - ref[0].comment, - req[0].extras) - - ref = (merged_ref, merged_ref.to_line()) - - if req[0] != ref[0]: - # A change on this entry - changes.append(Change(req[0].package, req[1], ref[1])) - - if ref: - output_requirements.append(ref[0]) - elif softupdate: - # under softupdate we pass through anything unknown packages, - # this is intended for ecosystem projects that want to stay in - # sync with existing requirements, but also add their own above - # and beyond. - output_requirements.append(req) - else: - # What do we do if we find something unexpected? - # - # In the default cause we should die horribly, because - # the point of global requirements was a single lever - # to control all the pip installs in the gate. - # - # However, we do have other projects using - # devstack jobs that might have legitimate reasons to - # override. For those we support NON_STANDARD_REQS=1 - # environment variable to turn this into a warning only. - # However this drops the unknown requirement. - actions.append(project.Error( - "'%s' is not in global-requirements.txt or blacklist.txt" - % req.package)) - # always print out what we did if we did a thing - if changes: - actions.append(project.StdOut( - "Version change for: %s\n" - % ", ".join([x.name for x in changes]))) - actions.append(project.StdOut("Updated %s:\n" % dest_label)) - for change in changes: - actions.append(project.StdOut(" %s\n" % change)) - return actions, requirement.Requirements(output_requirements) - - -def _copy_requires( - suffix, softupdate, hacking, proj, global_reqs, non_std_reqs, - blacklist={}): - """Copy requirements files.""" - actions = [] - for source, content in sorted(proj['requirements'].items()): - dest_path = os.path.join(proj['root'], source) - # this is specifically for global-requirements gate jobs so we don't - # modify the git tree - if suffix: - dest_path = "%s.%s" % (dest_path, suffix) - dest_name = "%s.%s" % (source, suffix) - else: - dest_name = source - dest_sequence = list(requirement.to_reqs(content)) - actions.append(project.Verbose("Syncing %s" % dest_path)) - _actions, reqs = _sync_requirements_file( - global_reqs, dest_sequence, dest_path, softupdate, hacking, - non_std_reqs, blacklist) - actions.extend(_actions) - actions.append(project.File(dest_name, requirement.to_content(reqs))) - extras = project.extras(proj) - output_extras = {} - for extra, content in sorted(extras.items()): - dest_name = 'extra-%s' % extra - dest_path = "%s[%s]" % (proj['root'], extra) - dest_sequence = list(requirement.to_reqs(content)) - actions.append(project.Verbose("Syncing extra [%s]" % extra)) - _actions, reqs = _sync_requirements_file( - global_reqs, dest_sequence, dest_path, softupdate, hacking, - non_std_reqs, blacklist) - actions.extend(_actions) - output_extras[extra] = reqs - dest_path = 'setup.cfg' - if suffix: - dest_path = "%s.%s" % (dest_path, suffix) - actions.append(project.File( - dest_path, project.merge_setup_cfg(proj['setup.cfg'], output_extras))) - return actions - - -def _process_project( - project, global_reqs, suffix, softupdate, hacking, non_std_reqs, - blacklist={}): - """Project a project. - - :return: The actions to take as a result. - """ - actions = _copy_requires( - suffix, softupdate, hacking, project, global_reqs, non_std_reqs, - blacklist) - actions.extend(_check_setup_py(project)) - return actions - - -# IO -- - -def main(argv=None, stdout=None, _worker=None): - parser = optparse.OptionParser() - parser.add_option("-o", "--output-suffix", dest="suffix", default="", - help="output suffix for updated files (i.e. .global)") - parser.add_option("-s", "--soft-update", dest="softupdate", - action="store_true", - help="Pass through extra requirements without warning.") - parser.add_option("-H", "--hacking", dest="hacking", - action="store_true", - help="Include the hacking project.") - parser.add_option("-v", "--verbose", dest="verbose", - action="store_true", - help="Add further verbosity to output") - parser.add_option("--source", dest="source", default=".", - help="Dir where global-requirements.txt is located.") - options, args = parser.parse_args(argv) - if len(args) != 1: - print("Must specify directory to update") - raise Exception("Must specify one and only one directory to update.") - if not os.path.isdir(args[0]): - print("%s is not a directory." % (args[0])) - raise Exception("%s is not a directory." % (args[0])) - if stdout is None: - stdout = sys.stdout - if _worker is None: - _worker = _do_main - non_std_reqs = os.getenv('NON_STANDARD_REQS', '0') == '1' - _worker( - args[0], options.source, options.suffix, options.softupdate, - options.hacking, stdout, options.verbose, non_std_reqs) - - -def _do_main( - root, source, suffix, softupdate, hacking, stdout, verbose, - non_std_reqs): - """No options or environment variable access from here on in.""" - proj = project.read(root) - global_req_content = open( - os.path.join(source, 'global-requirements.txt'), 'rt').read() - global_reqs = requirement.parse(global_req_content) - blacklist_content = open( - os.path.join(source, 'blacklist.txt'), 'rt').read() - blacklist = requirement.parse(blacklist_content) - actions = _process_project( - proj, global_reqs, suffix, softupdate, hacking, non_std_reqs, - blacklist) - project.write(proj, actions, stdout=stdout, verbose=verbose) - - -if __name__ == "__main__": - main() diff --git a/openstack_requirements/tests/common.py b/openstack_requirements/tests/common.py index 6f241dea30..930f15abab 100644 --- a/openstack_requirements/tests/common.py +++ b/openstack_requirements/tests/common.py @@ -15,7 +15,6 @@ import shutil import fixtures -from openstack_requirements.cmds import update from openstack_requirements import project from openstack_requirements import requirement @@ -102,16 +101,3 @@ pbr_project = make_project(pbr_fixture) project_project = make_project(project_fixture) bad_project = make_project(bad_project_fixture) oslo_project = make_project(oslo_fixture) - - -def project_file( - fail, proj, action_filename, suffix=None, softupdate=None, - non_std_reqs=False, blacklist={}): - actions = update._process_project( - proj, global_reqs, suffix, softupdate, None, - non_std_reqs, blacklist) - for action in actions: - if type(action) is project.File: - if action.filename == action_filename: - return action.content.splitlines() - fail('File %r not found in %r' % (action_filename, actions)) diff --git a/openstack_requirements/tests/test_update.py b/openstack_requirements/tests/test_update.py deleted file mode 100644 index d9dc075437..0000000000 --- a/openstack_requirements/tests/test_update.py +++ /dev/null @@ -1,456 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import io -import sys -import textwrap -from unittest import mock - -import fixtures -import testscenarios -import testtools -from testtools import matchers - -from openstack_requirements.cmds import update -from openstack_requirements import project -from openstack_requirements import requirement -from openstack_requirements.tests import common - - -load_tests = testscenarios.load_tests_apply_scenarios - - -class SmokeTest(testtools.TestCase): - - def test_project(self): - global_env = self.useFixture(common.GlobalRequirements()) - global_reqs = common._file_to_list(global_env.req_file) - # This is testing our test input data. Perhaps remove? (lifeless) - self.assertIn("jsonschema!=1.4.0,<2,>=1.0.0", global_reqs) - # And test the end to end call of update.py, UI and all. - self.project = self.useFixture(common.project_fixture) - capture = io.StringIO() - update.main(['--source', global_env.root, self.project.root], capture) - reqs = common._file_to_list(self.project.req_file) - # ensure various updates take - self.assertIn("jsonschema!=1.4.0,<2,>=1.0.0", reqs) - self.assertIn("python-keystoneclient>=0.4.1", reqs) - self.assertIn("SQLAlchemy<=0.7.99,>=0.7", reqs) - expected = ('Version change for: greenlet, SQLAlchemy, eventlet, PasteDeploy, routes, WebOb, wsgiref, boto, kombu, python-swiftclient, lxml, jsonschema, python-keystoneclient\n' # noqa - """Updated %(project)s/requirements.txt: - greenlet>=0.3.1 -> greenlet>=0.3.2 - SQLAlchemy>=0.7.8,<=1.0.17 -> SQLAlchemy<=0.7.99,>=0.7 - eventlet>=0.9.12 -> eventlet>=0.12.0 - PasteDeploy -> PasteDeploy>=1.5.0 - routes -> Routes>=1.12.3 - WebOb>=1.2 -> WebOb<1.3,>=1.2.3 - wsgiref -> wsgiref>=0.1.2 - boto -> boto>=2.4.0 - kombu>2.4.7 -> kombu>=2.4.8 - python-swiftclient>=1.2,<4 -> python-swiftclient>=1.2 - lxml -> lxml>=2.3 - jsonschema -> jsonschema!=1.4.0,<2,>=1.0.0 - python-keystoneclient>=0.2.0 -> python-keystoneclient>=0.4.1 -Version change for: mox, mox3, testrepository, testtools -Updated %(project)s/test-requirements.txt: - mox==0.5.3 -> mox>=0.5.3 - mox3==0.21.0 -> mox3>=0.7.0 - testrepository>=0.0.13 -> testrepository>=0.0.17 - testtools>=0.9.27 -> testtools>=0.9.32 -""") % dict(project=self.project.root) - self.assertEqual(expected, capture.getvalue()) - - -class UpdateTest(testtools.TestCase): - - def test_project(self): - reqs = common.project_file( - self.fail, common.project_project, 'requirements.txt') - # ensure various updates take - self.assertIn("jsonschema!=1.4.0,<2,>=1.0.0", reqs) - self.assertIn("python-keystoneclient>=0.4.1", reqs) - self.assertIn("SQLAlchemy<=0.7.99,>=0.7", reqs) - - def test_requirements_header(self): - _REQS_HEADER = [ - '# The order of packages is significant, because pip processes ' - 'them in the order', - '# of appearance. Changing the order has an impact on the overall ' - 'integration', - '# process, which may cause wedges in the gate later.', - ] - reqs = common.project_file( - self.fail, common.project_project, 'requirements.txt') - self.assertEqual(_REQS_HEADER, reqs[:3]) - - def test_project_with_oslo(self): - reqs = common.project_file( - self.fail, common.oslo_project, 'requirements.txt') - oslo_tar = ("-f http://tarballs.openstack.org/oslo.config/" - "oslo.config-1.2.0a3.tar.gz#egg=oslo.config-1.2.0a3") - self.assertIn(oslo_tar, reqs) - - def test_test_project(self): - reqs = common.project_file( - self.fail, common.project_project, 'test-requirements.txt') - self.assertIn("testtools>=0.9.32", reqs) - self.assertIn("testrepository>=0.0.17", reqs) - # make sure we didn't add something we shouldn't - self.assertNotIn("sphinxcontrib-pecanwsme>=0.2", reqs) - - def test_install_setup(self): - setup_contents = common.project_file( - self.fail, common.project_project, 'setup.py', suffix='global') - self.assertIn("# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO" - " - DO NOT EDIT", setup_contents) - - def test_no_install_setup(self): - actions = update._process_project( - common.oslo_project, common.global_reqs, None, None, None, - False) - for action in actions: - if type(action) is project.File: - self.assertNotEqual(action.filename, 'setup.py') - - # These are tests which don't need to run the project update in advance - def test_requirement_not_in_global(self): - actions = update._process_project( - common.bad_project, common.global_reqs, None, None, None, False) - errors = [a for a in actions if type(a) is project.Error] - msg = u"'thisisnotarealdependency' is not in global-requirements.txt" - self.assertIn(msg, errors[0].message) - - def test_requirement_in_blacklist(self): - actions = update._process_project( - common.bad_project, common.global_reqs, None, None, None, False, - blacklist={'thisisnotarealdependency': None}) - errors = [a for a in actions if type(a) is project.Error] - self.assertEqual([], errors) - - def test_requirement_not_in_global_non_fatal(self): - reqs = common.project_file( - self.fail, common.bad_project, 'requirements.txt', - non_std_reqs=True) - self.assertNotIn("thisisnotarealdependency", reqs) - - def test_requirement_soft_update(self): - reqs = common.project_file( - self.fail, common.bad_project, 'requirements.txt', - softupdate=True) - self.assertIn("thisisnotarealdependency", reqs) - - # testing output - def test_non_verbose_output(self): - actions = update._process_project( - common.project_project, common.global_reqs, None, None, None, - False) - capture = io.StringIO() - project.write( - common.project_project, actions, capture, False, True) - expected = ('Version change for: greenlet, SQLAlchemy, eventlet, PasteDeploy, routes, WebOb, wsgiref, boto, kombu, python-swiftclient, lxml, jsonschema, python-keystoneclient\n' # noqa - """Updated %(project)s/requirements.txt: - greenlet>=0.3.1 -> greenlet>=0.3.2 - SQLAlchemy>=0.7.8,<=1.0.17 -> SQLAlchemy<=0.7.99,>=0.7 - eventlet>=0.9.12 -> eventlet>=0.12.0 - PasteDeploy -> PasteDeploy>=1.5.0 - routes -> Routes>=1.12.3 - WebOb>=1.2 -> WebOb<1.3,>=1.2.3 - wsgiref -> wsgiref>=0.1.2 - boto -> boto>=2.4.0 - kombu>2.4.7 -> kombu>=2.4.8 - python-swiftclient>=1.2,<4 -> python-swiftclient>=1.2 - lxml -> lxml>=2.3 - jsonschema -> jsonschema!=1.4.0,<2,>=1.0.0 - python-keystoneclient>=0.2.0 -> python-keystoneclient>=0.4.1 -Version change for: mox, mox3, testrepository, testtools -Updated %(project)s/test-requirements.txt: - mox==0.5.3 -> mox>=0.5.3 - mox3==0.21.0 -> mox3>=0.7.0 - testrepository>=0.0.13 -> testrepository>=0.0.17 - testtools>=0.9.27 -> testtools>=0.9.32 -""") % dict(project=common.project_project['root']) - self.assertEqual(expected, capture.getvalue()) - - def test_verbose_output(self): - actions = update._process_project( - common.project_project, common.global_reqs, None, None, None, - False) - capture = io.StringIO() - project.write( - common.project_project, actions, capture, True, True) - expected = ("""Syncing %(project)s/requirements.txt -Version change for: greenlet, SQLAlchemy, eventlet, PasteDeploy, routes, WebOb, wsgiref, boto, kombu, python-swiftclient, lxml, jsonschema, python-keystoneclient\n""" # noqa - """Updated %(project)s/requirements.txt: - greenlet>=0.3.1 -> greenlet>=0.3.2 - SQLAlchemy>=0.7.8,<=1.0.17 -> SQLAlchemy<=0.7.99,>=0.7 - eventlet>=0.9.12 -> eventlet>=0.12.0 - PasteDeploy -> PasteDeploy>=1.5.0 - routes -> Routes>=1.12.3 - WebOb>=1.2 -> WebOb<1.3,>=1.2.3 - wsgiref -> wsgiref>=0.1.2 - boto -> boto>=2.4.0 - kombu>2.4.7 -> kombu>=2.4.8 - python-swiftclient>=1.2,<4 -> python-swiftclient>=1.2 - lxml -> lxml>=2.3 - jsonschema -> jsonschema!=1.4.0,<2,>=1.0.0 - python-keystoneclient>=0.2.0 -> python-keystoneclient>=0.4.1 -Syncing %(project)s/test-requirements.txt -Version change for: mox, mox3, testrepository, testtools -Updated %(project)s/test-requirements.txt: - mox==0.5.3 -> mox>=0.5.3 - mox3==0.21.0 -> mox3>=0.7.0 - testrepository>=0.0.13 -> testrepository>=0.0.17 - testtools>=0.9.27 -> testtools>=0.9.32 -Syncing setup.py -""") % dict(project=common.project_project['root']) - self.assertEqual(expected, capture.getvalue()) - - -class TestMain(testtools.TestCase): - - @mock.patch('os.path.isdir', return_value=True) - def test_smoke(self, mock_isdir): - def check_params( - root, source, suffix, softupdate, hacking, stdout, verbose, - non_std_reqs): - self.expectThat(root, matchers.Equals('/dev/zero')) - self.expectThat(source, matchers.Equals('/dev/null')) - self.expectThat(suffix, matchers.Equals('')) - self.expectThat(softupdate, matchers.Equals(None)) - self.expectThat(hacking, matchers.Equals(None)) - self.expectThat(stdout, matchers.Equals(sys.stdout)) - self.expectThat(verbose, matchers.Equals(None)) - self.expectThat(non_std_reqs, matchers.Equals(True)) - - with fixtures.EnvironmentVariable('NON_STANDARD_REQS', '1'): - update.main( - ['--source', '/dev/null', '/dev/zero'], _worker=check_params) - self.expectThat(mock_isdir.called, matchers.Equals(True)) - - @mock.patch('os.path.isdir', return_value=True) - def test_suffix(self, mock_isdir): - def check_params( - root, source, suffix, softupdate, hacking, stdout, verbose, - non_std_reqs): - self.expectThat(suffix, matchers.Equals('global')) - - update.main(['-o', 'global', '/dev/zero'], _worker=check_params) - self.expectThat(mock_isdir.called, matchers.Equals(True)) - - def test_isdirectory(self): - def never_called( - root, source, suffix, softupdate, hacking, stdout, verbose, - non_std_reqs): - self.expectThat(False, matchers.Equals(True), - message=("update.main() should riase an " - "exception before getting here")) - - with testtools.ExpectedException(Exception, - "/dev/zero is not a directory"): - update.main(['/dev/zero'], _worker=never_called) - - -class TestSyncRequirementsFile(testtools.TestCase): - - def test_multiple_lines_in_global_one_in_project(self): - global_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - foo>1;python_version!='2.7' - """) - project_content = textwrap.dedent("""\ - foo - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - self.assertEqual(requirement.Requirements([ - requirement.Requirement( - 'foo', '', '<2', "python_version=='2.7'", ''), - requirement.Requirement( - 'foo', '', '>1', "python_version!='2.7'", '')]), - reqs) - self.assertEqual(project.StdOut( - " foo " - "-> foo<2;python_version=='2.7'\n"), actions[2]) - self.assertEqual(project.StdOut( - " " - "-> foo>1;python_version!='2.7'\n"), actions[3]) - self.assertThat(actions, matchers.HasLength(4)) - - def test_multiple_lines_separated_in_project_nochange(self): - global_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - foo>1;python_version!='2.7' - """) - project_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - # mumbo gumbo - foo>1;python_version!='2.7' - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - self.assertEqual(requirement.Requirements([ - requirement.Requirement( - 'foo', '', '<2', "python_version=='2.7'", ''), - requirement.Requirement( - 'foo', '', '>1', "python_version!='2.7'", ''), - requirement.Requirement( - '', '', '', '', "# mumbo gumbo")]), - reqs) - self.assertThat(actions, matchers.HasLength(0)) - - def test_multiple_lines_separated_in_project(self): - global_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - foo>1;python_version!='2.7' - """) - project_content = textwrap.dedent("""\ - foo<1.8;python_version=='2.7' - # mumbo gumbo - foo>0.9;python_version!='2.7' - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - self.assertEqual(requirement.Requirements([ - requirement.Requirement( - 'foo', '', '<2', "python_version=='2.7'", ''), - requirement.Requirement( - 'foo', '', '>1', "python_version!='2.7'", ''), - requirement.Requirement( - '', '', '', '', "# mumbo gumbo")]), - reqs) - self.assertEqual(project.StdOut( - " foo<1.8;python_version=='2.7' -> " - "foo<2;python_version=='2.7'\n"), actions[2]) - self.assertEqual(project.StdOut( - " foo>0.9;python_version!='2.7' -> " - "foo>1;python_version!='2.7'\n"), actions[3]) - self.assertThat(actions, matchers.HasLength(4)) - - def test_multiple_lines_nochange(self): - global_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - foo>1;python_version!='2.7' - """) - project_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - foo>1;python_version!='2.7' - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - self.assertEqual(requirement.Requirements([ - requirement.Requirement( - 'foo', '', '<2', "python_version=='2.7'", ''), - requirement.Requirement( - 'foo', '', '>1', "python_version!='2.7'", '')]), - reqs) - self.assertThat(actions, matchers.HasLength(0)) - - def test_single_global_multiple_in_project(self): - global_content = textwrap.dedent("""\ - foo>1 - """) - project_content = textwrap.dedent("""\ - foo<2;python_version=='2.7' - foo>1;python_version!='2.7' - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - self.assertEqual(requirement.Requirements([ - requirement.Requirement('foo', '', '>1', "", '')]), - reqs) - self.assertEqual(project.StdOut( - " foo<2;python_version=='2.7' -> foo>1\n"), actions[2]) - self.assertEqual(project.StdOut( - " foo>1;python_version!='2.7' -> \n"), actions[3]) - self.assertThat(actions, matchers.HasLength(4)) - - def test_unparseable_line(self): - global_content = textwrap.dedent("""\ - foo - """) - project_content = textwrap.dedent("""\ - foo - -e https://git.openstack.org/openstack/neutron.git#egg=neutron - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - n = '-e https://git.openstack.org/openstack/neutron.git#egg=neutron' - self.assertEqual(requirement.Requirements([ - requirement.Requirement('foo', '', '', '', ''), - requirement.Requirement('', '', '', '', n)]), - reqs) - - def test_extras_kept(self): - global_content = textwrap.dedent("""\ - oslo.db>1.4.1 - """) - project_content = textwrap.dedent("""\ - oslo.db[fixture,mysql]>1.3 - """) - global_reqs = requirement.parse(global_content) - project_reqs = list(requirement.to_reqs(project_content)) - actions, reqs = update._sync_requirements_file( - global_reqs, project_reqs, 'f', False, False, False) - self.assertEqual(requirement.Requirements([ - requirement.Requirement( - 'oslo.db', '', '>1.4.1', '', '', ['fixture', 'mysql'])]), - reqs) - self.assertThat(actions, matchers.HasLength(3)) - self.assertEqual(project.StdOut( - " oslo.db[fixture,mysql]>1.3 -> " - "oslo.db[fixture,mysql]>1.4.1\n"), actions[2]) - - -class TestCopyRequires(testtools.TestCase): - - def test_extras_no_change(self): - global_content = textwrap.dedent(u"""\ - foo<2;python_version=='2.7' # BSD - foo>1;python_version!='2.7' - freddy - """) - setup_cfg = textwrap.dedent(u"""\ - [metadata] - name = openstack.requirements - - [extras] - test = - foo<2:python_version=='2.7' # BSD - foo>1:python_version!='2.7' - opt = - freddy - """) - proj = {} - proj['root'] = '/dev/null' - proj['requirements'] = {} - proj['setup.cfg'] = setup_cfg - global_reqs = requirement.parse(global_content) - actions = update._copy_requires( - u'', False, False, proj, global_reqs, False) - self.assertEqual([ - project.Verbose('Syncing extra [opt]'), - project.Verbose('Syncing extra [test]'), - project.File('setup.cfg', setup_cfg)], actions) diff --git a/openstack_requirements/tests/test_update_pbr.py b/openstack_requirements/tests/test_update_pbr.py deleted file mode 100644 index 81d5a65d41..0000000000 --- a/openstack_requirements/tests/test_update_pbr.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2013 IBM Corp. -# Copyright (c) 2013 Mirantis Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Based on test_update.py - -import testtools - -from openstack_requirements.cmds import update -from openstack_requirements import project -from openstack_requirements.tests import common - - -class UpdateTestPbr(testtools.TestCase): - - def test_project(self): - reqs = common.project_file( - self.fail, common.pbr_project, 'requirements.txt') - # ensure various updates take - self.assertIn("jsonschema!=1.4.0,<2,>=1.0.0", reqs) - self.assertIn("python-keystoneclient>=0.4.1", reqs) - self.assertIn("SQLAlchemy<=0.7.99,>=0.7", reqs) - - def test_test_project(self): - reqs = common.project_file( - self.fail, common.pbr_project, 'test-requirements.txt') - self.assertIn("testtools>=0.9.32", reqs) - self.assertIn("testrepository>=0.0.17", reqs) - # make sure we didn't add something we shouldn't - self.assertNotIn("sphinxcontrib-pecanwsme>=0.2", reqs) - - def test_no_install_setup(self): - actions = update._process_project( - common.pbr_project, common.global_reqs, None, None, None, - False) - for action in actions: - if type(action) is project.File: - self.assertNotEqual(action.filename, 'setup.py') diff --git a/openstack_requirements/tests/test_update_suffix.py b/openstack_requirements/tests/test_update_suffix.py deleted file mode 100644 index b360d84b26..0000000000 --- a/openstack_requirements/tests/test_update_suffix.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import testtools - -from openstack_requirements.cmds import update -from openstack_requirements import project -from openstack_requirements.tests import common - - -class UpdateTestWithSuffix(testtools.TestCase): - - def test_project(self): - reqs = common.project_file( - self.fail, common.project_project, 'requirements.txt.global', - suffix='global') - # ensure various updates take - self.assertIn("jsonschema!=1.4.0,<2,>=1.0.0", reqs) - self.assertIn("python-keystoneclient>=0.4.1", reqs) - self.assertIn("SQLAlchemy<=0.7.99,>=0.7", reqs) - - def test_project_with_oslo(self): - reqs = common.project_file( - self.fail, common.oslo_project, 'requirements.txt.global', - suffix='global') - oslo_tar = ("-f http://tarballs.openstack.org/oslo.config/" - "oslo.config-1.2.0a3.tar.gz#egg=oslo.config-1.2.0a3") - self.assertIn(oslo_tar, reqs) - - def test_test_project(self): - reqs = common.project_file( - self.fail, common.project_project, 'test-requirements.txt.global', - suffix='global') - self.assertIn("testtools>=0.9.32", reqs) - self.assertIn("testrepository>=0.0.17", reqs) - # make sure we didn't add something we shouldn't - self.assertNotIn("sphinxcontrib-pecanwsme>=0.2", reqs) - - def test_install_setup(self): - setup_contents = common.project_file( - self.fail, common.project_project, 'setup.py', suffix='global') - self.assertIn("# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO" - " - DO NOT EDIT", setup_contents) - - def test_no_install_setup(self): - actions = update._process_project( - common.oslo_project, common.global_reqs, 'global', None, None, - False) - for action in actions: - if type(action) is project.File: - self.assertNotEqual(action.filename, 'setup.py') diff --git a/setup.cfg b/setup.cfg index faac7c9b16..6c17f7c47b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,7 +31,6 @@ console_scripts = edit-constraints = openstack_requirements.cmds.edit_constraint:main generate-constraints = openstack_requirements.cmds.generate:main check-conflicts = openstack_requirements.cmds.check_conflicts:main - update-requirements = openstack_requirements.cmds.update:main validate-constraints = openstack_requirements.cmds.validate:main validate-projects = openstack_requirements.cmds.validate_projects:main normalize-requirements = openstack_requirements.cmds.normalize_requirements:main diff --git a/update.py b/update.py deleted file mode 120000 index d715f12ed5..0000000000 --- a/update.py +++ /dev/null @@ -1 +0,0 @@ -openstack_requirements/cmds/update.py \ No newline at end of file