def test_canonicalises(self): req = requirement.Requirement('Foo_bar', '', '', '', '') self.assertEqual( {'foo-bar': [(req, '')]}, requirement.to_dict([(req, '')]))
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)
def test_canonicalises(self): req = requirement.Requirement('Foo_bar', '', '', '', '') self.assertEqual({'foo-bar': [(req, '')]}, requirement.to_dict([(req, '')]))
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)) 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 itertools.izip_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]: # 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)