|
3 | 3 | from pathlib import Path
|
4 | 4 | from typing import TYPE_CHECKING
|
5 | 5 | from typing import ClassVar
|
| 6 | +from typing import Literal |
6 | 7 |
|
7 | 8 | from cleo.helpers import option
|
8 | 9 |
|
9 | 10 | from poetry.console.commands.env_command import EnvCommand
|
10 |
| -from poetry.utils.env import build_environment |
11 | 11 | from poetry.utils.helpers import remove_directory
|
| 12 | +from poetry.utils.isolated_build import isolated_builder |
12 | 13 |
|
13 | 14 |
|
14 | 15 | if TYPE_CHECKING:
|
15 | 16 | from cleo.io.inputs.option import Option
|
16 | 17 |
|
| 18 | +BUILD_FORMATS = ["sdist", "wheel"] |
| 19 | + |
17 | 20 |
|
18 | 21 | class BuildCommand(EnvCommand):
|
19 | 22 | name = "build"
|
@@ -47,49 +50,52 @@ class BuildCommand(EnvCommand):
|
47 | 50 | "poetry.core.masonry.builders.wheel",
|
48 | 51 | ]
|
49 | 52 |
|
50 |
| - def _build( |
51 |
| - self, |
52 |
| - fmt: str, |
53 |
| - executable: str | Path | None = None, |
54 |
| - *, |
55 |
| - target_dir: Path | None = None, |
56 |
| - ) -> None: |
57 |
| - from poetry.masonry.builders import BUILD_FORMATS |
| 53 | + def _requested_formats(self) -> list[Literal["sdist", "wheel"]]: |
| 54 | + fmt = self.option("format") or "all" |
58 | 55 |
|
59 | 56 | if fmt in BUILD_FORMATS:
|
60 |
| - builders = [BUILD_FORMATS[fmt]] |
| 57 | + formats = [fmt] |
61 | 58 | elif fmt == "all":
|
62 |
| - builders = list(BUILD_FORMATS.values()) |
| 59 | + formats = BUILD_FORMATS |
63 | 60 | else:
|
64 | 61 | raise ValueError(f"Invalid format: {fmt}")
|
65 | 62 |
|
| 63 | + return formats # type: ignore[return-value] # TODO |
| 64 | + |
| 65 | + def _build( |
| 66 | + self, fmt: Literal["wheel", "sdist"], executable: Path, target_dir: Path |
| 67 | + ) -> None: |
| 68 | + config_settings = {} |
| 69 | + |
66 | 70 | if local_version_label := self.option("local-version"):
|
67 |
| - self.poetry.package.version = self.poetry.package.version.replace( |
68 |
| - local=local_version_label |
69 |
| - ) |
| 71 | + config_settings["local-version"] = local_version_label |
70 | 72 |
|
71 |
| - for builder in builders: |
72 |
| - builder(self.poetry, executable=executable).build(target_dir) |
| 73 | + with isolated_builder( |
| 74 | + source=self.poetry.file.path.parent, |
| 75 | + distribution=fmt, |
| 76 | + python_executable=executable, |
| 77 | + ) as builder: |
| 78 | + self.line(f"Building <info>{fmt}</info>") |
| 79 | + builder.build(fmt, target_dir, config_settings=config_settings) |
73 | 80 |
|
74 | 81 | def handle(self) -> int:
|
75 | 82 | if not self.poetry.is_package_mode:
|
76 | 83 | self.line_error("Building a package is not possible in non-package mode.")
|
77 | 84 | return 1
|
78 | 85 |
|
79 |
| - with build_environment(poetry=self.poetry, env=self.env, io=self.io) as env: |
80 |
| - fmt = self.option("format") or "all" |
81 |
| - dist_dir = Path(self.option("output")) |
82 |
| - package = self.poetry.package |
83 |
| - self.line( |
84 |
| - f"Building <c1>{package.pretty_name}</c1> (<c2>{package.version}</c2>)" |
85 |
| - ) |
| 86 | + dist_dir = Path(self.option("output")) |
| 87 | + package = self.poetry.package |
| 88 | + self.line( |
| 89 | + f"Building <c1>{package.pretty_name}</c1> (<c2>{package.version}</c2>)" |
| 90 | + ) |
86 | 91 |
|
87 |
| - if not dist_dir.is_absolute(): |
88 |
| - dist_dir = self.poetry.pyproject_path.parent / dist_dir |
| 92 | + if not dist_dir.is_absolute(): |
| 93 | + dist_dir = self.poetry.pyproject_path.parent / dist_dir |
89 | 94 |
|
90 |
| - if self.option("clean"): |
91 |
| - remove_directory(path=dist_dir, force=True) |
| 95 | + if self.option("clean"): |
| 96 | + remove_directory(path=dist_dir, force=True) |
92 | 97 |
|
93 |
| - self._build(fmt, executable=env.python, target_dir=dist_dir) |
| 98 | + for fmt in self._requested_formats(): |
| 99 | + self._build(fmt, executable=self.env.python, target_dir=dist_dir) |
94 | 100 |
|
95 | 101 | return 0
|
0 commit comments