Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
3.0 kB · 105 lines
Python
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106#!/usr/bin/env python3"""The runtimeDependenciesHook validates, that all dependencies specifiedin wheel metadata are available in the local environment.
In case that does not hold, it will print missing dependencies andviolated version constraints."""
import importlib.metadataimport reimport sysimport tempfilefrom argparse import ArgumentParserfrom zipfile import ZipFile
from packaging.metadata import Metadata, parse_emailfrom packaging.requirements import Requirement
argparser = ArgumentParser()argparser.add_argument("wheel", help="Path to the .whl file to test")
def error(msg: str) -> None: print(f" - {msg}", file=sys.stderr)
def normalize_name(name: str) -> str: """ Normalize package names according to PEP503 """ return re.sub(r"[-_.]+", "-", name).lower()
def get_manifest_text_from_wheel(wheel: str) -> str: """ Given a path to a wheel, this function will try to extract the METADATA file in the wheels .dist-info directory. """ with ZipFile(wheel) as zipfile: for zipinfo in zipfile.infolist(): if zipinfo.filename.endswith(".dist-info/METADATA"): with tempfile.TemporaryDirectory() as tmp: path = zipfile.extract(zipinfo, path=tmp) with open(path, encoding="utf-8") as fd: return fd.read()
raise RuntimeError("No METADATA file found in wheel")
def get_metadata(wheel: str) -> Metadata: """ Given a path to a wheel, returns a parsed Metadata object. """ text = get_manifest_text_from_wheel(wheel) raw, _ = parse_email(text) metadata = Metadata.from_raw(raw, validate=False)
return metadata
def test_requirement(requirement: Requirement) -> bool: """ Given a requirement specification, tests whether the dependency can be resolved in the local environment, and whether it satisfies the specified version constraints. """ if requirement.marker and not requirement.marker.evaluate(): # ignore requirements with incompatible markers return True
package_name = normalize_name(requirement.name)
try: package = importlib.metadata.distribution(requirement.name) except importlib.metadata.PackageNotFoundError: error(f"{package_name} not installed") return False
# Allow prereleases, to give to give us some wiggle-room requirement.specifier.prereleases = True
if requirement.specifier and package.version not in requirement.specifier: error( f"{package_name}{requirement.specifier} not satisfied by version {package.version}" ) return False
return True
if __name__ == "__main__": args = argparser.parse_args()
metadata = get_metadata(args.wheel) requirements = metadata.requires_dist
if not requirements: sys.exit(0)
tests = [test_requirement(requirement) for requirement in requirements]
if not all(tests): sys.exit(1)