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, {})
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)
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)
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, {})
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 {})
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 {})
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
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))
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)