diff --git a/pkgs/development/interpreters/python/check-requirements/check-requirements.py b/pkgs/development/interpreters/python/check-requirements/check-requirements.py new file mode 100644 index 0000000000000..8ca597b8cb453 --- /dev/null +++ b/pkgs/development/interpreters/python/check-requirements/check-requirements.py @@ -0,0 +1,55 @@ +# Check whether dependencies listed in a requiremens.txt are found +# in the current environment. +# +# Based on https://github.com/pypa/pip/issues/2733#issuecomment-257340871 +import argparse +import pip +from pip.req import parse_requirements +import pkg_resources +from pkg_resources import DistributionNotFound, VersionConflict + + +def get_dependencies(requirement_file_name): + dependencies = [] + session = pip.download.PipSession() + for req in parse_requirements(requirement_file_name, session=session): + if req.req is not None: + dependencies.append(str(req.req)) + else: + # The req probably refers to a url. Depending on the + # format req.link.url may be able to be parsed to find the + # required package. + pass + return dependencies + + +def check_dependencies(dependencies): + """Checks to see if the python dependencies are fullfilled. + If check passes return 0. Otherwise print error and return 1 + """ + try: + pkg_resources.working_set.require(dependencies) + except VersionConflict as exc: + try: + print("{} was found on your system, " + "but {} is required.\n".format(e.dist, e.req)) + return(0) + except AttributeError: + print(e) + return 1 + except DistributionNotFound as e: + print(e) + return 1 + return 0 + + +def parse_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument("file") + return parser.parse_args() + + +if __name__ == "__main__": + args = parse_arguments() + dependencies = get_dependencies(args.file) + exit(check_dependencies(dependencies)) diff --git a/pkgs/development/interpreters/python/hooks/default.nix b/pkgs/development/interpreters/python/hooks/default.nix index 861cb38c06079..77017e5254e0d 100644 --- a/pkgs/development/interpreters/python/hooks/default.nix +++ b/pkgs/development/interpreters/python/hooks/default.nix @@ -70,6 +70,16 @@ in rec { name = "python-remove-bin-bytecode-hook"; } ./python-remove-bin-bytecode-hook.sh) {}; + requirementsCheckHook = callPackage ({ pip, setuptools }: + makeSetupHook { + name = "check-requirements-hook"; + deps = [ pip setuptools ]; + substitutions = { + inherit pythonCheckInterpreter; + requirementsCheckScript = ../check-requirements/check-requirements.py; + }; + } ./requirements-check-hook.sh) {}; + setuptoolsBuildHook = callPackage ({ setuptools, wheel }: makeSetupHook { name = "setuptools-setup-hook"; diff --git a/pkgs/development/interpreters/python/hooks/requirements-check-hook.sh b/pkgs/development/interpreters/python/hooks/requirements-check-hook.sh new file mode 100644 index 0000000000000..fcf0943ad7c61 --- /dev/null +++ b/pkgs/development/interpreters/python/hooks/requirements-check-hook.sh @@ -0,0 +1,15 @@ +# Setup hook for requirements. +echo "Sourcing requirements-check-hook" + +requirementsCheckPhase() { + if [ -z "$requirementsCheckFile" ]; then + echo "Error: no $requirementsCheckFile was given." + exit 1 + + @pythonCheckInterpreter@ @requirementsCheckScript@ $requirementsCheckFile +} + +if [ -z "$dontUseRequirementsCheck" ]; then + echo "Using requirementsCheckPhase" + preDistPhases+=" requirementsCheckPhase" +fi diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 77c8c59373a3d..df0565b58ffab 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -108,7 +108,7 @@ in { inherit buildSetupcfg; inherit (callPackage ../development/interpreters/python/hooks { }) - flitBuildHook pipBuildHook pipInstallHook pytestCheckHook pythonCatchConflictsHook pythonImportsCheckHook pythonRemoveBinBytecodeHook setuptoolsBuildHook setuptoolsCheckHook wheelUnpackHook; + flitBuildHook pipBuildHook pipInstallHook pytestCheckHook pythonCatchConflictsHook pythonImportsCheckHook pythonRemoveBinBytecodeHook requirementsCheckHook setuptoolsBuildHook setuptoolsCheckHook wheelUnpackHook; # helpers