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"'thisisnotarealdepedency' is not in global-requirements.txt" self.assertEqual([project.Error(message=msg)], errors)
def test_errors(self): stdout = io.StringIO() root = self.useFixture(fixtures.TempDir()).path proj = {'root': root} actions = [project.Error(u'fred')] with testtools.ExpectedException(Exception): project.write(proj, actions, stdout, True) self.expectThat(stdout.getvalue(), matchers.Equals('fred\n'))
def _sync_requirements_file(source_reqs, dest_sequence, dest_label, softupdate, hacking, non_std_reqs): 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 reference = source_reqs.get(req.package.lower()) if reference: actual = dest_reqs.get(req.package.lower()) for req, ref in six.moves.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" % 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)