From 3fce1f075c6ced40d6ebdad73622802a0935447c Mon Sep 17 00:00:00 2001 From: "c.men" Date: Tue, 29 Oct 2024 18:03:34 +0800 Subject: [PATCH 1/6] fix: build fails when use_uv is true(#3231) --- news/3231.bug.md | 1 + src/pdm/cli/commands/build.py | 71 ++++++++++++++++++++++++----------- 2 files changed, 50 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..738feed072 100644 --- a/src/pdm/cli/commands/build.py +++ b/src/pdm/cli/commands/build.py @@ -6,6 +6,7 @@ import tarfile import tempfile from typing import Mapping +from pathlib import Path from pdm.cli.commands.base import BaseCommand from pdm.cli.hooks import HookManager @@ -57,29 +58,55 @@ 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 + + dist_dir = project.root / "dist" + dest_dir = Path(dest).absolute() + if dest_dir.exists(): + shutil.rmtree(dest_dir, ignore_errors=True) + (dist_dir / ".gitignore").unlink(missing_ok=True) + + subprocess.call(["uv", "build"]) + + if dest != "dist": + shutil.move(dist_dir, dest_dir) + for sdist_file in dest_dir.glob("*.tar.gz"): + if sdist is False: + sdist_file.unlink(missing_ok=True) + else: + artifacts.append(str(sdist_file)) + + 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: From 0642350ff71c54563b881a3e39d79ad35d5aa844 Mon Sep 17 00:00:00 2001 From: "c.men" Date: Tue, 29 Oct 2024 19:18:58 +0800 Subject: [PATCH 2/6] fix: delete uv build .gitignore so that publish could work --- src/pdm/cli/commands/build.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pdm/cli/commands/build.py b/src/pdm/cli/commands/build.py index 738feed072..0d223e4441 100644 --- a/src/pdm/cli/commands/build.py +++ b/src/pdm/cli/commands/build.py @@ -5,8 +5,8 @@ import shutil import tarfile import tempfile -from typing import Mapping from pathlib import Path +from typing import Mapping from pdm.cli.commands.base import BaseCommand from pdm.cli.hooks import HookManager @@ -89,10 +89,10 @@ def do_build( dest_dir = Path(dest).absolute() if dest_dir.exists(): shutil.rmtree(dest_dir, ignore_errors=True) - (dist_dir / ".gitignore").unlink(missing_ok=True) subprocess.call(["uv", "build"]) + (dist_dir / ".gitignore").unlink(missing_ok=True) if dest != "dist": shutil.move(dist_dir, dest_dir) for sdist_file in dest_dir.glob("*.tar.gz"): @@ -100,7 +100,7 @@ def do_build( sdist_file.unlink(missing_ok=True) else: artifacts.append(str(sdist_file)) - + for whl_file in dest_dir.glob("*.whl"): if wheel is False: whl_file.unlink(missing_ok=True) From 6ac4844c1c29054407eabe1dce8e4478f04d890c Mon Sep 17 00:00:00 2001 From: "c.men" Date: Thu, 31 Oct 2024 15:51:03 +0800 Subject: [PATCH 3/6] fix: make uv build compatible to --no-clean --- src/pdm/cli/commands/build.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pdm/cli/commands/build.py b/src/pdm/cli/commands/build.py index 0d223e4441..4c55cef934 100644 --- a/src/pdm/cli/commands/build.py +++ b/src/pdm/cli/commands/build.py @@ -87,19 +87,18 @@ def do_build( dist_dir = project.root / "dist" dest_dir = Path(dest).absolute() - if dest_dir.exists(): - shutil.rmtree(dest_dir, ignore_errors=True) subprocess.call(["uv", "build"]) (dist_dir / ".gitignore").unlink(missing_ok=True) - if dest != "dist": - shutil.move(dist_dir, dest_dir) - for sdist_file in dest_dir.glob("*.tar.gz"): + if dest_dir != dist_dir: + shutil.copytree(dist_dir, dest_dir, dirs_exist_ok=True) + shutil.rmtree(dist_dir, ignore_errors=True) + for sdist_fp in dest_dir.glob("*.tar.gz"): if sdist is False: - sdist_file.unlink(missing_ok=True) + sdist_fp.unlink(missing_ok=True) else: - artifacts.append(str(sdist_file)) + artifacts.append(str(sdist_fp)) for whl_file in dest_dir.glob("*.whl"): if wheel is False: From 52492df89755fdd94dc1ab51b3efe56615db76c7 Mon Sep 17 00:00:00 2001 From: "c.men" Date: Thu, 31 Oct 2024 16:10:27 +0800 Subject: [PATCH 4/6] feat: uv build enables --quiet --- src/pdm/cli/commands/build.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pdm/cli/commands/build.py b/src/pdm/cli/commands/build.py index 4c55cef934..1af5d9e65b 100644 --- a/src/pdm/cli/commands/build.py +++ b/src/pdm/cli/commands/build.py @@ -33,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: @@ -88,7 +89,12 @@ def do_build( dist_dir = project.root / "dist" dest_dir = Path(dest).absolute() - subprocess.call(["uv", "build"]) + uv_build_cmd = ["uv", "build"] + if verbose == -1: + uv_build_cmd.append("-q") + elif verbose > 0: + uv_build_cmd.append(f"-{'v'*verbose}") + subprocess.call(uv_build_cmd) (dist_dir / ".gitignore").unlink(missing_ok=True) if dest_dir != dist_dir: @@ -139,5 +145,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), ) From 0dc01eb96660cc9e2d863b1ff3b8bcf6f5171512 Mon Sep 17 00:00:00 2001 From: mon Date: Thu, 31 Oct 2024 16:28:43 +0800 Subject: [PATCH 5/6] fix: resolve #3237 conversation --- src/pdm/cli/commands/build.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pdm/cli/commands/build.py b/src/pdm/cli/commands/build.py index 1af5d9e65b..6c3ad7fb2c 100644 --- a/src/pdm/cli/commands/build.py +++ b/src/pdm/cli/commands/build.py @@ -86,20 +86,17 @@ def do_build( else: import subprocess - dist_dir = project.root / "dist" dest_dir = Path(dest).absolute() - uv_build_cmd = ["uv", "build"] + 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.call(uv_build_cmd) + subprocess.run(uv_build_cmd, check=True) - (dist_dir / ".gitignore").unlink(missing_ok=True) - if dest_dir != dist_dir: - shutil.copytree(dist_dir, dest_dir, dirs_exist_ok=True) - shutil.rmtree(dist_dir, ignore_errors=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) From 7a4e3a35e5bc720c06225d56f9e24a1e4dbd6d4b Mon Sep 17 00:00:00 2001 From: mon Date: Thu, 31 Oct 2024 17:05:11 +0800 Subject: [PATCH 6/6] fix: build test failed --- tests/cli/test_build.py | 1 + 1 file changed, 1 insertion(+) 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"}