def get_release_info(package_info, specified_version): releases_info = package_info["releases"] release_info = releases_info.get(specified_version) parsed_version = packaging_parse(specified_version) if parsed_version.is_prerelease or parsed_version.is_postrelease or parsed_version.is_devrelease: pypi_version = _get_pypi_version(specified_version, releases_info) if pypi_version: release_info = releases_info[pypi_version] else: # Unable to find a matching normalized version string, throw exception raise ValueError( "Could not find a matching normalized version string", package_info['name'], specified_version) return release_info
def read_bom(fd): """Read BOM data from file handle.""" print("Generating CycloneDX BOM") component_elements = [] for req in requirements.parse(fd): name = req.name if not req.specs: print("WARNING: " + name + " does not have a version specified. Skipping.") break if len(req.specs[0]) >= 2: version = req.specs[0][1] if req.specs[0][0] != "==": print("WARNING: " + name + " is not pinned to a specific version. Using: " + version) response = BomGenerator.get_package_info(name, version) if response: json = response.json() info = json["info"] author = info["author"] description = info["summary"] license = info[ "license"] # TODO: Attempt to perform SPDX license ID resolution # This should be optimized a bit - kinda ugly hashes = {} releases = json["releases"] version_release = releases.get(version, version) if type(version_release) == str: # version was not found in release_dict print("WARNING: " + name + "==" + version + " could not be found in PyPi") purl = BomGenerator.generate_purl(name, version) component = BomGenerator.build_component_element( "", name, version, "", {}, "", purl, "false") component_elements.append(component) continue # move on to the next component else: parsed_version = packaging_parse(version) if parsed_version.is_prerelease or parsed_version.is_postrelease or parsed_version.is_devrelease: pypi_version = _get_pypi_version(version, releases) if pypi_version: version_release = releases[pypi_version] else: # Unable to find a matching normalized version string, throw exception raise ValueError( "Could not find a matching normalized version string", name, version) has_wheel = False for release in version_release: if release["packagetype"] == "bdist_wheel": has_wheel = True # pip will always prefer bdist_wheel over sdist - therefore hashes from bdist_wheel take precedence for release in version_release: if has_wheel is True and release[ "packagetype"] == "bdist_wheel": populate_digests(hashes, release["digests"]) elif has_wheel is False and release[ "packagetype"] == "sdist": populate_digests(hashes, release["digests"]) purl = BomGenerator.generate_purl(name, version) component = BomGenerator.build_component_element( author, name, version, description, hashes, license, purl, "false") component_elements.append(component) else: # nothing to parse, simply add the name, version, and purl to bom purl = BomGenerator.generate_purl(name, version) component = BomGenerator.build_component_element( "", name, version, "", {}, "", purl, "false") component_elements.append(component) return component_elements