Пример #1
0
def do_build(
    project: Project,
    sdist: bool = True,
    wheel: bool = True,
    dest: str = "dist",
    clean: bool = True,
):
    """Build artifacts for distribution."""
    if project.is_global:
        raise ProjectError("Not allowed to build based on the global project.")
    check_project_file(project)
    if not wheel and not sdist:
        stream.echo("All artifacts are disabled, nothing to do.", err=True)
        return
    if not os.path.isabs(dest):
        dest = project.root.joinpath(dest).as_posix()
    if clean:
        shutil.rmtree(dest, ignore_errors=True)
    with stream.logging("build"), EnvBuilder(project.root,
                                             project.environment) as builder:
        if sdist:
            stream.echo("Building sdist...")
            loc = builder.build_sdist(dest)
            stream.echo(f"Built sdist at {loc}")
        if wheel:
            stream.echo("Building wheel...")
            loc = builder.build_wheel(dest)
            stream.echo(f"Built wheel at {loc}")
Пример #2
0
 def update_project_egg_info(self):
     if not self.environment.project.meta.name:
         return
     canonical_name = self.environment.project.meta.project_name.lower(
     ).replace("-", "_")
     egg_info_dir = self.environment.project.root / f"{canonical_name}.egg-info"
     if egg_info_dir.exists():
         stream.echo("Updating the project's egg info...")
         with EnvBuilder(self.environment.project.root,
                         self.environment) as builder:
             builder.build_egg_info(str(builder.src_dir))
Пример #3
0
 def install_editable(self, ireq: pip_shims.InstallRequirement) -> None:
     setup_path = ireq.setup_py_path
     paths = self.environment.get_paths()
     install_script = importlib.import_module(
         "pdm.installers._editable_install"
     ).__file__.rstrip("co")
     install_args = [
         self.environment.python_executable,
         "-u",
         install_script,
         setup_path,
         paths["prefix"],
         paths["purelib"],
         paths["scripts"],
     ]
     with EnvBuilder(ireq.unpacked_source_directory, self.environment) as builder:
         builder.install(["setuptools"])
         extra_env = {"INJECT_SITE": "1"} if not self.environment.is_global else None
         builder.subprocess_runner(
             install_args, ireq.unpacked_source_directory, extra_env
         )
Пример #4
0
    def build(
        self,
        ireq: pip_shims.InstallRequirement,
        hashes: Optional[Dict[str, str]] = None,
        allow_all: bool = True,
    ) -> str:
        """Build egg_info directory for editable candidates and a wheel for others.

        :param ireq: the InstallRequirment of the candidate.
        :param hashes: a dictionary of filename: hash_value to check against downloaded
        artifacts.
        :param allow_all: Allow building incompatible wheels.
        :returns: The full path of the built artifact.
        """
        kwargs = self._make_building_args(ireq)
        wheel_cache = self.project.make_wheel_cache()
        with self.get_finder() as finder:
            with allow_all_wheels(allow_all):
                # temporarily allow all wheels to get a link.
                populate_link(finder, ireq, False)
                if hashes is None:
                    cache_entry = wheel_cache.get_cache_entry(
                        ireq.link,
                        ireq.req.project_name,
                        pip_shims.get_supported(
                            version="".join(
                                map(
                                    str,
                                    get_python_version(self.python_executable)[0][:2],
                                )
                            )
                        ),
                    )
                    if cache_entry is not None:
                        stream.logger.debug(
                            "Using cached wheel link: %s", cache_entry.link
                        )
                        ireq.link = cache_entry.link
            if not ireq.editable and not ireq.req.name:
                ireq.source_dir = kwargs["build_dir"]
            else:
                ireq.ensure_has_source_dir(kwargs["build_dir"])

            download_dir = kwargs["download_dir"]
            only_download = False
            if ireq.link.is_wheel:
                download_dir = kwargs["wheel_download_dir"]
                only_download = True
            if hashes:
                ireq.hash_options = convert_hashes(hashes)
            if not (ireq.editable and ireq.req.is_local_dir):
                downloader = pip_shims.Downloader(finder.session, "off")
                if ireq.link.is_vcs:
                    ireq.link = pip_shims.Link(expand_env_vars_in_auth(ireq.link.url))
                downloaded = pip_shims.unpack_url(
                    ireq.link,
                    ireq.source_dir,
                    downloader,
                    download_dir,
                    ireq.hashes(False),
                )
                # Preserve the downloaded file so that it won't be cleared.
                if downloaded and only_download:
                    try:
                        shutil.copy(downloaded.path, download_dir)
                    except shutil.SameFileError:
                        pass

            if ireq.link.is_wheel:
                # If the file is a wheel, should be already present under download dir.
                return (self.project.cache("wheels") / ireq.link.filename).as_posix()
            else:
                # Check the built wheel cache again after hashes are resolved.
                cache_entry = wheel_cache.get_cache_entry(
                    ireq.link,
                    ireq.req.project_name,
                    pip_shims.get_supported(
                        version="".join(
                            map(str, get_python_version(self.python_executable)[0][:2])
                        )
                    ),
                )
                if cache_entry is not None:
                    stream.logger.debug("Using cached wheel link: %s", cache_entry.link)
                    return cache_entry.link.file_path

            # Otherwise, now all source is prepared, build it.
            with EnvBuilder(ireq.unpacked_source_directory, self) as builder:
                if ireq.editable:
                    ret = builder.build_egg_info(kwargs["build_dir"])
                    ireq.metadata_directory = ret
                else:
                    should_cache = False
                    if ireq.link.is_vcs:
                        vcs = pip_shims.VcsSupport()
                        vcs_backend = vcs.get_backend_for_scheme(ireq.link.scheme)
                        if vcs_backend.is_immutable_rev_checkout(
                            ireq.link.url, ireq.source_dir
                        ):
                            should_cache = True
                    else:
                        base, _ = ireq.link.splitext()
                        if _egg_info_re.search(base) is not None:
                            # Determine whether the string looks like an egg_info.
                            should_cache = True
                    output_dir = (
                        wheel_cache.get_path_for_link(ireq.link)
                        if should_cache
                        else kwargs["build_dir"]
                    )
                    if not os.path.exists(output_dir):
                        os.makedirs(output_dir, exist_ok=True)
                    ret = builder.build_wheel(output_dir)
            return ret
Пример #5
0
    def build(
        self,
        ireq: pip_shims.InstallRequirement,
        hashes: Optional[Dict[str, str]] = None,
        allow_all: bool = True,
    ) -> str:
        """Build egg_info directory for editable candidates and a wheel for others.

        :param ireq: the InstallRequirment of the candidate.
        :param hashes: a dictionary of filename: hash_value to check against downloaded
        artifacts.
        :param allow_all: Allow building incompatible wheels.
        :returns: The full path of the built artifact.
        """
        build_dir = self._get_build_dir(ireq)
        wheel_cache = self.project.make_wheel_cache()
        supported_tags = pip_shims.get_supported("".join(
            map(str,
                get_python_version(self.python_executable, digits=2)[0])))
        with self.get_finder(ignore_requires_python=True) as finder:
            with allow_all_wheels(allow_all):
                # temporarily allow all wheels to get a link.
                populate_link(finder, ireq, False)
            ireq.link = pip_shims.Link(
                expand_env_vars_in_auth(
                    ireq.link.url.replace(
                        "${PROJECT_ROOT}",
                        self.project.root.as_posix().lstrip("/"))))
            if hashes is None and not ireq.editable:
                # If hashes are not given and cache is hit, replace the link with the
                # cached one. This can speed up by skipping the download and build.
                cache_entry = wheel_cache.get_cache_entry(
                    ireq.link,
                    ireq.req.project_name,
                    supported_tags,
                )
                if cache_entry is not None:
                    termui.logger.debug("Using cached wheel link: %s",
                                        cache_entry.link)
                    ireq.link = cache_entry.link
            if not ireq.editable and not ireq.req.name:
                ireq.source_dir = build_dir
            else:
                ireq.ensure_has_source_dir(build_dir)

            if hashes:
                ireq.hash_options = convert_hashes(hashes)
            if not (ireq.editable and ireq.req.is_local_dir):
                downloader = pip_shims.Downloader(finder.session, "off")
                downloaded = pip_shims.unpack_url(
                    ireq.link,
                    ireq.source_dir,
                    downloader,
                    hashes=ireq.hashes(False),
                )

                if ireq.link.is_wheel:
                    # If the file is a wheel, return the downloaded file directly.
                    return downloaded.path

        # Check the built wheel cache again after hashes are resolved.
        if not ireq.editable:
            cache_entry = wheel_cache.get_cache_entry(
                ireq.link,
                ireq.req.project_name,
                supported_tags,
            )
            if cache_entry is not None:
                termui.logger.debug("Using cached wheel link: %s",
                                    cache_entry.link)
                return cache_entry.link.file_path

        # Otherwise, as all source is already prepared, build it.
        with EnvBuilder(ireq.unpacked_source_directory, self) as builder:
            if ireq.editable:
                ret = builder.build_egg_info(build_dir)
                ireq.metadata_directory = ret
                return ret
            should_cache = False
            if ireq.link.is_vcs:
                vcs = pip_shims.VcsSupport()
                vcs_backend = vcs.get_backend_for_scheme(ireq.link.scheme)
                if vcs_backend.is_immutable_rev_checkout(
                        ireq.link.url, ireq.source_dir):
                    should_cache = True
            else:
                base, _ = ireq.link.splitext()
                if _egg_info_re.search(base) is not None:
                    # Determine whether the string looks like an egg_info.
                    should_cache = True
            output_dir = (wheel_cache.get_path_for_link(ireq.link)
                          if should_cache else build_dir)
            if not os.path.exists(output_dir):
                os.makedirs(output_dir, exist_ok=True)
            return builder.build_wheel(output_dir)