From 8f035b1ad5c31b483c0a439ad28f6a4b803e935b Mon Sep 17 00:00:00 2001 From: monchin Date: Thu, 31 Oct 2024 17:23:30 +0800 Subject: [PATCH] fix: build fails when use_uv is true (#3237) * fix: build fails when use_uv is true(#3231) * fix: delete uv build .gitignore so that publish could work * fix: make uv build compatible to --no-clean * feat: uv build enables --quiet * fix: resolve #3237 conversation * fix: build test failed --------- Co-authored-by: c.men --- news/3231.bug.md | 1 + src/pdm/cli/commands/build.py | 74 ++++++++++++++++++++++++----------- tests/cli/test_build.py | 1 + 3 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 news/3231.bug.md diff --git a/news/3231.bug.md b/news/3231.bug.md new file mode 100644 index 0000000000..ed9060d2b7 --- /dev/null +++ b/news/3231.bug.md @@ -0,0 +1 @@ +Fix the bug that `pdm build` would fail when `use_uv` is true. \ No newline at end of file diff --git a/src/pdm/cli/commands/build.py b/src/pdm/cli/commands/build.py index f4203c4c8f..6c3ad7fb2c 100644 --- a/src/pdm/cli/commands/build.py +++ b/src/pdm/cli/commands/build.py @@ -5,6 +5,7 @@ import shutil import tarfile import tempfile +from pathlib import Path from typing import Mapping from pdm.cli.commands.base import BaseCommand @@ -32,6 +33,7 @@ def do_build( wheel: bool = True, dest: str = "dist", clean: bool = True, + verbose: int = 0, config_settings: Mapping[str, str] | None = None, hooks: HookManager | None = None, ) -> None: @@ -57,29 +59,56 @@ def do_build( hooks.try_emit("pre_build", dest=dest, config_settings=config_settings) artifacts: list[str] = [] with project.core.ui.logging("build"): - if sdist: - project.core.ui.echo("[info]Building sdist...") - sdist_file = SdistBuilder(project.root, project.environment).build(dest) - project.core.ui.echo(f"[info]Built sdist at {sdist_file}") - artifacts.append(sdist_file) - if wheel: + if not project.config["use_uv"]: if sdist: - project.core.ui.echo("[info]Building wheel from sdist...") - sdist_out = tempfile.mkdtemp(prefix="pdm-build-via-sdist-") - try: - with tarfile.open(sdist_file, "r:gz") as tf: - tf.extractall(sdist_out) - sdist_name = os.path.basename(sdist_file)[: -len(".tar.gz")] - whl = WheelBuilder(os.path.join(sdist_out, sdist_name), project.environment).build(dest) - project.core.ui.echo(f"[info]Built wheel at {whl}") - artifacts.append(whl) - finally: - shutil.rmtree(sdist_out, ignore_errors=True) - else: - project.core.ui.echo("[info]Building wheel...") - whl = WheelBuilder(project.root, project.environment).build(dest) - project.core.ui.echo(f"[info]Built wheel at {whl}") - artifacts.append(whl) + project.core.ui.echo("[info]Building sdist...") + sdist_file = SdistBuilder(project.root, project.environment).build(dest) + project.core.ui.echo(f"[info]Built sdist at {sdist_file}") + artifacts.append(sdist_file) + if wheel: + if sdist: + project.core.ui.echo("[info]Building wheel from sdist...") + sdist_out = tempfile.mkdtemp(prefix="pdm-build-via-sdist-") + try: + with tarfile.open(sdist_file, "r:gz") as tf: + tf.extractall(sdist_out) + sdist_name = os.path.basename(sdist_file)[: -len(".tar.gz")] + whl = WheelBuilder(os.path.join(sdist_out, sdist_name), project.environment).build(dest) + project.core.ui.echo(f"[info]Built wheel at {whl}") + artifacts.append(whl) + finally: + shutil.rmtree(sdist_out, ignore_errors=True) + else: + project.core.ui.echo("[info]Building wheel...") + whl = WheelBuilder(project.root, project.environment).build(dest) + project.core.ui.echo(f"[info]Built wheel at {whl}") + artifacts.append(whl) + else: + import subprocess + + dest_dir = Path(dest).absolute() + + uv_build_cmd = [*project.core.uv_cmd, "build", "--out-dir", str(dest_dir)] + if verbose == -1: + uv_build_cmd.append("-q") + elif verbose > 0: + uv_build_cmd.append(f"-{'v'*verbose}") + subprocess.run(uv_build_cmd, check=True) + + # pdm build doesn't include .gitignore, and pdm publish would fail with .gitignore + (dest_dir / ".gitignore").unlink(missing_ok=True) + for sdist_fp in dest_dir.glob("*.tar.gz"): + if sdist is False: + sdist_fp.unlink(missing_ok=True) + else: + artifacts.append(str(sdist_fp)) + + for whl_file in dest_dir.glob("*.whl"): + if wheel is False: + whl_file.unlink(missing_ok=True) + else: + artifacts.append(str(whl_file)) + hooks.try_emit("post_build", artifacts=artifacts, config_settings=config_settings) def add_arguments(self, parser: argparse.ArgumentParser) -> None: @@ -113,5 +142,6 @@ def handle(self, project: Project, options: argparse.Namespace) -> None: wheel=options.wheel, dest=options.dest, clean=options.clean, + verbose=options.verbose, hooks=HookManager(project, options.skip), ) diff --git a/tests/cli/test_build.py b/tests/cli/test_build.py index cef49baa93..6c47c00295 100644 --- a/tests/cli/test_build.py +++ b/tests/cli/test_build.py @@ -30,6 +30,7 @@ def test_build_command(project, pdm, mocker): wheel=True, dest=mock.ANY, clean=True, + verbose=0, hooks=mock.ANY, ) assert project.core.state.config_settings == {"a": "1", "b": "2"}