diff --git a/openstack_requirements/cmds/update.py b/openstack_requirements/cmds/update.py index ee35018523..a441172ad3 100644 --- a/openstack_requirements/cmds/update.py +++ b/openstack_requirements/cmds/update.py @@ -98,7 +98,7 @@ def _check_setup_py(proj): def _sync_requirements_file( source_reqs, dest_sequence, dest_label, softupdate, hacking, - non_std_reqs): + non_std_reqs, blacklist={}): actions = [] dest_reqs = requirement.to_dict(dest_sequence) changes = [] @@ -127,6 +127,11 @@ def _sync_requirements_file( 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: @@ -178,7 +183,8 @@ def _sync_requirements_file( # 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" % req.package)) + "'%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( @@ -191,7 +197,8 @@ def _sync_requirements_file( def _copy_requires( - suffix, softupdate, hacking, proj, global_reqs, non_std_reqs): + suffix, softupdate, hacking, proj, global_reqs, non_std_reqs, + blacklist={}): """Copy requirements files.""" actions = [] for source, content in sorted(proj['requirements'].items()): @@ -207,7 +214,7 @@ def _copy_requires( actions.append(project.Verbose("Syncing %s" % dest_path)) _actions, reqs = _sync_requirements_file( global_reqs, dest_sequence, dest_path, softupdate, hacking, - non_std_reqs) + non_std_reqs, blacklist) actions.extend(_actions) actions.append(project.File(dest_name, requirement.to_content(reqs))) extras = project.extras(proj) @@ -219,7 +226,7 @@ def _copy_requires( actions.append(project.Verbose("Syncing extra [%s]" % extra)) _actions, reqs = _sync_requirements_file( global_reqs, dest_sequence, dest_path, softupdate, hacking, - non_std_reqs) + non_std_reqs, blacklist) actions.extend(_actions) output_extras[extra] = reqs dest_path = 'setup.cfg' @@ -231,13 +238,15 @@ def _copy_requires( def _process_project( - project, global_reqs, suffix, softupdate, hacking, non_std_reqs): + 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) + suffix, softupdate, hacking, project, global_reqs, non_std_reqs, + blacklist) actions.extend(_check_setup_py(project)) return actions @@ -284,8 +293,12 @@ def _do_main( 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) + proj, global_reqs, suffix, softupdate, hacking, non_std_reqs, + blacklist) project.write(proj, actions, stdout=stdout, verbose=verbose) diff --git a/openstack_requirements/tests/common.py b/openstack_requirements/tests/common.py index 69c72c8162..6f241dea30 100644 --- a/openstack_requirements/tests/common.py +++ b/openstack_requirements/tests/common.py @@ -79,6 +79,10 @@ class GlobalRequirements(fixtures.Fixture): self.req_file = os.path.join(self.root, "global-requirements.txt") shutil.copy( "openstack_requirements/tests/files/gr-base.txt", self.req_file) + self.blacklist_file = os.path.join(self.root, "blacklist.txt") + shutil.copy( + "openstack_requirements/tests/files/blacklist.txt", + self.blacklist_file) # Static data for unit testing. @@ -102,10 +106,10 @@ oslo_project = make_project(oslo_fixture) def project_file( fail, proj, action_filename, suffix=None, softupdate=None, - non_std_reqs=False): + non_std_reqs=False, blacklist={}): actions = update._process_project( proj, global_reqs, suffix, softupdate, None, - non_std_reqs) + non_std_reqs, blacklist) for action in actions: if type(action) is project.File: if action.filename == action_filename: diff --git a/openstack_requirements/tests/test_update.py b/openstack_requirements/tests/test_update.py index a1f4bc4036..7bfc838156 100644 --- a/openstack_requirements/tests/test_update.py +++ b/openstack_requirements/tests/test_update.py @@ -132,7 +132,14 @@ class UpdateTest(testtools.TestCase): 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.assertEqual([project.Error(message=msg)], errors) + 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(