Example #1
0
def _build_in_isolated_env(
    build_env: Mapping[str, str],
    builder: ProjectBuilder,
    outdir: str,
    distribution: str,
) -> str:
    # For debugging: The following line disables removal of the isolated venv.
    # It will be left in the /tmp folder and can be inspected or entered as
    # needed.
    # _IsolatedEnvBuilder.__exit__ = lambda *args: None
    with _IsolatedEnvBuilder() as env:
        builder.python_executable = env.executable
        builder.scripts_dir = env.scripts_dir
        # first install the build dependencies
        symlink_unisolated_packages(env)
        install_reqs(env, builder.build_system_requires)
        installed_requires_for_build = False
        try:
            build_reqs = builder.get_requires_for_build(distribution)
        except BuildBackendException:
            pass
        else:
            install_reqs(env, build_reqs)
            installed_requires_for_build = True

        with replace_env(build_env):
            if not installed_requires_for_build:
                install_reqs(env, builder.get_requires_for_build(distribution))
            return builder.build(distribution, outdir, {})
Example #2
0
def build_package_via_sdist(srcdir, outdir, distributions, config_settings=None, isolation=True, skip_dependency_check=False):
    # type: (str, str, List[str], Optional[ConfigSettingsType], bool, bool) -> None
    """
    Build a sdist and then the specified distributions from it.

    :param srcdir: Source directory
    :param outdir: Output directory
    :param distribution: Distribution to build (only wheel)
    :param config_settings: Configuration settings to be passed to the backend
    :param isolation: Isolate the build in a separate environment
    :param skip_dependency_check: Do not perform the dependency check
    """
    if 'sdist' in distributions:
        raise ValueError('Only binary distributions are allowed but sdist was specified')

    builder = ProjectBuilder(srcdir)
    sdist = _build(isolation, builder, outdir, 'sdist', config_settings, skip_dependency_check)

    sdist_name = os.path.basename(sdist)
    sdist_out = tempfile.mkdtemp(prefix='build-via-sdist-')
    # extract sdist
    with tarfile.open(sdist) as t:
        t.extractall(sdist_out)
        try:
            builder = ProjectBuilder(os.path.join(sdist_out, sdist_name[: -len('.tar.gz')]))
            for distribution in distributions:
                _build(isolation, builder, outdir, distribution, config_settings, skip_dependency_check)
        finally:
            shutil.rmtree(sdist_out, ignore_errors=True)
Example #3
0
def run_python_in_env(srcdir, args, **kwargs):
    """
    Execute ``python <args>`` in path in the build environment.

    The build environment will be read from the ``srcdir/pyproject.toml`` file.

    Notes
    -----

    The ``cwd`` keyword argument to `subprocess.call` will default to
    ``srcdir`` unless passed in ``kwargs``.

    The output from the pip command installing the build dependencies is
    redirected to stderr.

    """
    srcdir = Path(srcdir).expanduser().absolute()
    builder = ProjectBuilder(srcdir)

    cwd = kwargs.pop("cwd", srcdir)

    with IsolatedEnvBuilder() as env:
        builder.python_executable = env.executable
        silent_install(env, builder.build_system_requires)

        requirements = builder.get_requires_for_build('sdist')

        silent_install(env, requirements)

        sub_args = [builder.python_executable] + list(args)
        return subprocess.call(sub_args, cwd=cwd, **kwargs)
Example #4
0
def _build_in_isolated_env(
    build_env: Mapping[str, str],
    builder: ProjectBuilder,
    outdir: str,
    distribution: str,
) -> str:
    with _IsolatedEnvBuilder() as env:
        builder.python_executable = env.executable
        builder.scripts_dir = env.scripts_dir
        # first install the build dependencies
        symlink_unisolated_packages(env)
        install_reqs(env, builder.build_system_requires)
        installed_requires_for_build = False
        try:
            build_reqs = builder.get_requires_for_build(distribution)
        except BuildBackendException:
            pass
        else:
            install_reqs(env, build_reqs)
            installed_requires_for_build = True

        with replace_env(build_env):
            if not installed_requires_for_build:
                install_reqs(env, builder.get_requires_for_build(distribution))
            return builder.build(distribution, outdir, {})
Example #5
0
def _build_in_isolated_env(
    builder: ProjectBuilder, outdir: PathType, distribution: str, config_settings: Optional[ConfigSettingsType]
) -> str:
    with _IsolatedEnvBuilder() as env:
        builder.python_executable = env.executable
        builder.scripts_dir = env.scripts_dir
        # first install the build dependencies
        env.install(builder.build_system_requires)
        # then get the extra required dependencies from the backend (which was installed in the call above :P)
        env.install(builder.get_requires_for_build(distribution))
        return builder.build(distribution, outdir, config_settings or {})
Example #6
0
def _build_in_current_env(
    builder: ProjectBuilder,
    outdir: PathType,
    distribution: str,
    config_settings: Optional[ConfigSettingsType],
    skip_dependency_check: bool = False,
) -> str:
    if not skip_dependency_check:
        missing = builder.check_dependencies(distribution)
        if missing:
            dependencies = ''.join('\n\t' + dep for deps in missing for dep in (deps[0], _format_dep_chain(deps[1:])) if dep)
            print()
            _error(f'Missing dependencies:{dependencies}')

    return builder.build(distribution, outdir, config_settings or {})
Example #7
0
def _project_wheel_metadata(
        builder: build.ProjectBuilder) -> 'importlib_metadata.PackageMetadata':
    with tempfile.TemporaryDirectory() as tmpdir:
        path = pathlib.Path(builder.metadata_path(tmpdir))
        # https://github.com/python/importlib_metadata/pull/343
        return importlib_metadata.PathDistribution(
            path).metadata  # type: ignore
Example #8
0
def build_package(srcdir,
                  outdir,
                  distributions,
                  config_settings=None,
                  isolation=True,
                  skip_dependencies=False):
    # type: (str, str, List[str], Optional[ConfigSettings], bool, bool) -> None
    """
    Runs the build process

    :param srcdir: Source directory
    :param outdir: Output directory
    :param distributions: Distributions to build (sdist and/or wheel)
    :param config_settings: Configuration settings to be passed to the backend
    :param isolation: Isolate the build in a separate environment
    :param skip_dependencies: Do not perform the dependency check
    """
    if not config_settings:
        config_settings = {}

    try:
        builder = ProjectBuilder(srcdir, config_settings)
        if isolation:
            _build_in_isolated_env(builder, outdir, distributions)
        else:
            _build_in_current_env(builder, outdir, distributions,
                                  skip_dependencies)
    except BuildException as e:
        _error(str(e))
    except BuildBackendException as e:
        if sys.version_info >= (3, 5):
            print(traceback.format_exc(-1))
        else:
            print(traceback.format_exc())
        _error(str(e))
Example #9
0
def build_package(srcdir, outdir, distributions, config_settings=None, isolation=True, skip_dependency_check=False):
    # type: (str, str, List[str], Optional[ConfigSettingsType], bool, bool) -> None
    """
    Run the build process.

    :param srcdir: Source directory
    :param outdir: Output directory
    :param distribution: Distribution to build (sdist or wheel)
    :param config_settings: Configuration settings to be passed to the backend
    :param isolation: Isolate the build in a separate environment
    :param skip_dependency_check: Do not perform the dependency check
    """
    builder = ProjectBuilder(srcdir)
    for distribution in distributions:
        _build(isolation, builder, outdir, distribution, config_settings, skip_dependency_check)