示例#1
0
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)
示例#2
0
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()
示例#3
0
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])
示例#4
0
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)
示例#5
0
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])
示例#6
0
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)
示例#7
0
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()))
示例#8
0
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])
示例#9
0
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,
    )
示例#10
0
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
示例#11
0
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
示例#12
0
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()
示例#13
0
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)
示例#14
0
def test_freeze_on_empty_environment_yields_empty_file(pip: Pip):
    frozen_requirements = pip.freeze([])
    assert not frozen_requirements.strip()
示例#15
0
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()
示例#16
0
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("")
示例#17
0
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)