def test_install_does_not_install_anything_with_empty_requirements( pip: Pip, project_dir, current_platform ): target_directory = os.path.join(project_dir, "target_dir") os.makedirs(target_directory) pip.install(RequirementSet(current_platform), [], target_directory) assert not os.listdir(target_directory)
def test_pip_wheel_does_not_build_wheels_if_requirements_are_empty( pip: Pip, wheels_dir: Path, download_dir: Path, current_platform: TargetPlatform ): pip.build_wheels( requirements=RequirementSet(current_platform), target_directory=wheels_dir, source_directories=[download_dir], ) assert not wheels_dir.list_files()
def test_install_six_yields_non_empty_freeze_output( pip: Pip, project_dir, download_dir, current_platform, requirement_parser ): lib_dir = os.path.join(project_dir, "lib") requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("six")) pip.download_sources(requirements, download_dir) pip.install( requirements, source_directories=[download_dir], target_directory=lib_dir ) assert pip.freeze([lib_dir])
def test_pip_downloads_sources_to_target_directory( pip: Pip, project_dir: str, current_platform: TargetPlatform, requirement_parser: RequirementParser, ): download_path = os.path.join(project_dir, "download") requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("six")) pip.download_sources(requirements=requirements, target_directory=download_path) assert list_files(download_path)
def test_can_install_generated_packages( pip: Pip, current_platform: TargetPlatform, requirement_parser: RequirementParser, target_directory: Path, install_target: Path, package_generator: PackageGenerator, ): package_generator.generate_setuptools_package(name="testpackage") requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("testpackage")) pip.install( requirements, source_directories=[target_directory], target_directory=install_target, ) assert "testpackage" in pip.freeze(python_path=[install_target])
def test_install_to_target_directory_does_not_install_to_default_directory( pip: Pip, project_dir, download_dir, current_platform, requirement_parser ): requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("six")) target_directory = os.path.join(project_dir, "target-directory") os.makedirs(target_directory) pip.download_sources(requirements, download_dir) assert not os.listdir(target_directory) pip.install( requirements, source_directories=[download_dir], target_directory=target_directory, ) assert os.listdir(target_directory)
def test_pip_can_install_wheels_previously_downloaded( pip: Pip, project_dir: str, current_platform: TargetPlatform, requirement_parser: RequirementParser, download_dir: Path, wheels_dir: Path, ): requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("six")) pip.download_sources(requirements, download_dir) pip.build_wheels( requirements=requirements, source_directories=[download_dir], target_directory=wheels_dir, ) assert wheels_dir.list_files() assert any(map(lambda x: x.endswith(".whl"), wheels_dir.list_files()))
def test_can_generate_packages_with_requirements( package_generator: PackageGenerator, requirement_parser: RequirementParser, pip: Pip, target_directory: Path, install_target: Path, current_platform: TargetPlatform, ): package_generator.generate_setuptools_package( name="testpackage", install_requires=["other-package"]) package_generator.generate_setuptools_package(name="other-package") requirements = RequirementSet(target_platform=current_platform) requirements.add(requirement_parser.parse("testpackage")) pip.install( requirements, source_directories=[target_directory], target_directory=install_target, ) assert "other-package" in pip.freeze([install_target])
def pip(nix, project_dir, current_platform): return Pip( nix=nix, project_directory=project_dir, extra_build_inputs=[], extra_env="", verbose=3, wheels_cache=[], target_platform=current_platform, )
def test_can_generate_valid_packages_with_extras_require( package_generator: PackageGenerator, requirement_parser: RequirementParser, pip: Pip, target_directory: Path, install_target: Path, current_platform: TargetPlatform, ): package_generator.generate_setuptools_package( name="testpackage", extras_require={"extra": ["extrapackage"]}) package_generator.generate_setuptools_package(name="extrapackage") requirements = RequirementSet(target_platform=current_platform) requirements.add(requirement_parser.parse("testpackage[extra]")) pip.install( requirements, source_directories=[target_directory], target_directory=install_target, ) installed_packages = pip.freeze([install_target]) assert "extrapackage" in installed_packages
def test_can_generate_valid_packages_with_two_runtime_dependencies( package_generator: PackageGenerator, requirement_parser: RequirementParser, pip: Pip, target_directory: Path, install_target: Path, current_platform: TargetPlatform, ): package_generator.generate_setuptools_package( name="testpackage", install_requires=["dependency1", "dependency2"]) package_generator.generate_setuptools_package(name="dependency1") package_generator.generate_setuptools_package(name="dependency2") requirements = RequirementSet(target_platform=current_platform) requirements.add(requirement_parser.parse("testpackage")) pip.install( requirements, source_directories=[target_directory], target_directory=install_target, ) installed_packages = pip.freeze([install_target]) assert "dependency1" in installed_packages assert "dependency2" in installed_packages
def test_install_to_target_directory_does_not_install_to_default_directory( pip: Pip, project_dir: str, download_dir: Path, current_platform: TargetPlatform, requirement_parser: RequirementParser, ): requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("six")) target_directory = Path(project_dir) / "target-directory" target_directory.ensure_directory() pip.download_sources(requirements, download_dir) assert not target_directory.list_files() pip.install( requirements, source_directories=[download_dir], target_directory=target_directory, ) assert target_directory.list_files()
def test_freeze_respects_additional_python_path( pip: Pip, project_dir: str, current_platform: TargetPlatform, requirement_parser: RequirementParser, ): prefix = os.path.join(project_dir, "custom-prefix") download_dir = os.path.join(project_dir, "download") requirements = RequirementSet(current_platform) requirements.add(requirement_parser.parse("six")) pip.download_sources(requirements, download_dir) pip.install( requirements, target_directory=prefix, source_directories=[download_dir] ) freeze_without_six = pip.freeze([]) freeze_with_six = pip.freeze(python_path=[prefix]) assert len(freeze_without_six) < len(freeze_with_six)
def test_freeze_on_empty_environment_yields_empty_file(pip: Pip): frozen_requirements = pip.freeze([]) assert not frozen_requirements.strip()
def test_install_does_not_install_anything_with_empty_requirements( pip: Pip, project_dir: str, current_platform: TargetPlatform): target_directory = Path(project_dir) / "target_dir" target_directory.ensure_directory() pip.install(RequirementSet(current_platform), [], target_directory) assert not target_directory.list_files()
def main( version: str, verbose: int, nix_shell: str, nix_path: List[str], basename: str, cache_dir: str, extra_build_inputs: List[str], extra_env: str, enable_tests: bool, python_version: str, requirements: List[str], editable: List[str], setup_requires: List[str], overrides: List[AnyOverrides], default_overrides: bool, wheels_cache: List[str], ) -> None: """SPECIFICATION should be requirements.txt (output of pip freeze). """ logger = Logger(output=sys.stdout) nix_executable_directory: Optional[str] = (os.path.abspath( os.path.dirname(nix_shell)) if os.path.exists(nix_shell) else None) nix = Nix( nix_path=nix_path, executable_directory=nix_executable_directory, verbose=verbose != 0, ) platform_generator = PlatformGenerator(nix=nix) if default_overrides: overrides += tuple([ pypi2nix.overrides.OverridesGithub(owner="garbas", repo="nixpkgs-python", path="overrides.nix") ]) with open(os.path.join(os.path.dirname(__file__), "VERSION")) as f: pypi2nix_version = f.read() if version: click.echo(pypi2nix_version) return python_version_argument = python_version python_versions = pypi2nix.utils.PYTHON_VERSIONS.keys() if not python_version: raise click.exceptions.UsageError( 'Missing option "-V" / "--python-version". Choose from ' + (", ".join(python_versions))) python_version = pypi2nix.utils.PYTHON_VERSIONS[python_version] target_platform = platform_generator.from_python_version( python_version_argument) requirement_collector = RequirementsCollector(target_platform) setup_requirement_collector = RequirementsCollector(target_platform) extra_build_inputs = pypi2nix.utils.args_as_list(extra_build_inputs) setup_requires = pypi2nix.utils.args_as_list(setup_requires) for item in editable: requirement_collector.add_line(item) for build_input in setup_requires: setup_requirement_collector.add_line(build_input) # temporary pypi2nix folder and make sure it exists tmp_dir = os.path.join(tempfile.gettempdir(), "pypi2nix") if not os.path.exists(tmp_dir): os.makedirs(tmp_dir) current_dir = os.getcwd() requirements_name = os.path.join(current_dir, basename) if not cache_dir: cache_dir = os.path.join(tmp_dir, "cache") download_cache_dir = os.path.join(cache_dir, "download") wheel_cache_dir = os.path.join(cache_dir, "wheel") if not os.path.exists(download_cache_dir): os.makedirs(download_cache_dir) if not os.path.exists(wheel_cache_dir): os.makedirs(wheel_cache_dir) assert requirements is not None project_hash = md5_sum_of_files_with_file_names(requirements) project_dir = os.path.join(tmp_dir, project_hash) if os.path.exists(project_dir): shutil.rmtree(project_dir) os.makedirs(project_dir) for requirement_file_path in requirements: requirement_collector.add_file(requirement_file_path) requirement_set = requirement_collector.requirements() setup_requirements = setup_requirement_collector.requirements() sources = Sources() sources.update(requirement_set.sources()) sources.update(setup_requirements.sources()) click.echo("pypi2nix v{} running ...".format(pypi2nix_version)) click.echo("") click.echo("Stage1: Downloading wheels and creating wheelhouse ...") pip = Pip( nix=nix, project_directory=project_dir, extra_env=extra_env, extra_build_inputs=extra_build_inputs, verbose=verbose, wheels_cache=wheels_cache, target_platform=target_platform, ) wheel_builder = pypi2nix.stage1.WheelBuilder(pip=pip, project_directory=project_dir, logger=logger) wheels = wheel_builder.build(requirements=requirement_set, setup_requirements=setup_requirements) requirements_frozen = wheel_builder.get_frozen_requirements() default_environment = pip.default_environment() additional_dependency_graph = wheel_builder.additional_build_dependencies click.echo("Stage2: Extracting metadata from pypi.python.org ...") stage2 = pypi2nix.stage2.Stage2(sources=sources, verbose=verbose) packages_metadata = stage2.main( wheel_paths=wheels, default_environment=default_environment, wheel_cache_dir=wheel_cache_dir, additional_dependencies=additional_dependency_graph, ) click.echo("Stage3: Generating Nix expressions ...") pypi2nix.stage3.main( packages_metadata=packages_metadata, sources=sources, requirements_name=requirements_name, requirements_frozen=requirements_frozen, extra_build_inputs=extra_build_inputs, enable_tests=enable_tests, python_version=python_version, current_dir=current_dir, common_overrides=overrides, ) click.echo("") click.echo("Nix expressions generated successfully.") click.echo("") click.echo("To start development run:") click.echo(" nix-shell requirements.nix -A interpreter") click.echo("") click.echo("More information you can find at") click.echo(" https://github.com/garbas/pypi2nix") click.echo("")
def test_pip_downloads_nothing_when_no_requirements_are_given( pip: Pip, download_dir, current_platform): pip.download_sources(requirements=RequirementSet(current_platform), target_directory=download_dir) assert not list_files(download_dir)