Skip to content

Commit 34fea79

Browse files
committed
Add uv build
1 parent 6897001 commit 34fea79

File tree

16 files changed

+932
-168
lines changed

16 files changed

+932
-168
lines changed

Cargo.lock

Lines changed: 2 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/uv-build/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static DEFAULT_BACKEND: LazyLock<Pep517Backend> = LazyLock::new(|| Pep517Backend
8080
pub enum Error {
8181
#[error(transparent)]
8282
Io(#[from] io::Error),
83-
#[error("{} does not appear to be a Python project, as neither `pyproject.toml` nor `setup.py` is present in the directory", _0.simplified_display())]
83+
#[error("{} does not appear to be a Python project, as neither `pyproject.toml` nor `setup.py` are present in the directory", _0.simplified_display())]
8484
InvalidSourceDist(PathBuf),
8585
#[error("Invalid `pyproject.toml`")]
8686
InvalidPyprojectToml(#[from] toml::de::Error),

crates/uv-cli/src/lib.rs

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,21 @@ pub enum Commands {
335335
after_long_help = ""
336336
)]
337337
Venv(VenvArgs),
338+
/// Build Python packages into source distributions and wheels.
339+
///
340+
/// By default, `uv build` will build a source distribution ("sdist")
341+
/// from the source directory, and a binary distribution ("wheel") from
342+
/// the source distribution.
343+
///
344+
/// `uv build --sdist` can be used to build only the source distribution,
345+
/// `uv build --wheel` can be used to build only the binary distribution,
346+
/// and `uv build --sdist --wheel` can be used to build both distributions
347+
/// from source.
348+
#[command(
349+
after_help = "Use `uv help build` for more details.",
350+
after_long_help = ""
351+
)]
352+
Build(BuildArgs),
338353
/// Manage uv's cache.
339354
#[command(
340355
after_help = "Use `uv help cache` for more details.",
@@ -1125,7 +1140,7 @@ pub struct PipSyncArgs {
11251140

11261141
/// The Python interpreter into which packages should be installed.
11271142
///
1128-
/// By default, syncing requires a virtual environment. An path to an
1143+
/// By default, syncing requires a virtual environment. A path to an
11291144
/// alternative Python can be provided, but it is only recommended in
11301145
/// continuous integration (CI) environments and should be used with
11311146
/// caution, as it can modify the system Python installation.
@@ -1407,7 +1422,7 @@ pub struct PipInstallArgs {
14071422

14081423
/// The Python interpreter into which packages should be installed.
14091424
///
1410-
/// By default, installation requires a virtual environment. An path to an
1425+
/// By default, installation requires a virtual environment. A path to an
14111426
/// alternative Python can be provided, but it is only recommended in
14121427
/// continuous integration (CI) environments and should be used with
14131428
/// caution, as it can modify the system Python installation.
@@ -1572,7 +1587,7 @@ pub struct PipUninstallArgs {
15721587

15731588
/// The Python interpreter from which packages should be uninstalled.
15741589
///
1575-
/// By default, uninstallation requires a virtual environment. An path to an
1590+
/// By default, uninstallation requires a virtual environment. A path to an
15761591
/// alternative Python can be provided, but it is only recommended in
15771592
/// continuous integration (CI) environments and should be used with
15781593
/// caution, as it can modify the system Python installation.
@@ -1923,6 +1938,49 @@ pub struct PipTreeArgs {
19231938
pub compat_args: compat::PipGlobalCompatArgs,
19241939
}
19251940

1941+
#[derive(Args)]
1942+
#[allow(clippy::struct_excessive_bools)]
1943+
pub struct BuildArgs {
1944+
/// The directory from which source distributions and/or wheels should be built.
1945+
///
1946+
/// Defaults to the current working directory.
1947+
#[arg(value_parser = parse_file_path)]
1948+
pub src_dir: Option<PathBuf>,
1949+
1950+
/// Build a source distribution ("sdist") from the given directory.
1951+
#[arg(long)]
1952+
pub sdist: bool,
1953+
1954+
/// Build a built distribution ("wheel") from the given directory.
1955+
#[arg(long)]
1956+
pub wheel: bool,
1957+
1958+
/// The Python interpreter to use for the build environment.
1959+
///
1960+
/// By default, builds are executed in isolated virtual environments. The
1961+
/// discovered interpreter will be used to create those environments, and
1962+
/// will be symlinked or copied in depending on the platform.
1963+
///
1964+
/// See `uv help python` to view supported request formats.
1965+
#[arg(
1966+
long,
1967+
short,
1968+
env = "UV_PYTHON",
1969+
verbatim_doc_comment,
1970+
help_heading = "Python options"
1971+
)]
1972+
pub python: Option<String>,
1973+
1974+
#[command(flatten)]
1975+
pub resolver: ResolverArgs,
1976+
1977+
#[command(flatten)]
1978+
pub build: BuildOptionsArgs,
1979+
1980+
#[command(flatten)]
1981+
pub refresh: RefreshArgs,
1982+
}
1983+
19261984
#[derive(Args)]
19271985
#[allow(clippy::struct_excessive_bools)]
19281986
pub struct VenvArgs {
@@ -2298,7 +2356,7 @@ pub struct RunArgs {
22982356
pub installer: ResolverInstallerArgs,
22992357

23002358
#[command(flatten)]
2301-
pub build: BuildArgs,
2359+
pub build: BuildOptionsArgs,
23022360

23032361
#[command(flatten)]
23042362
pub refresh: RefreshArgs,
@@ -2426,7 +2484,7 @@ pub struct SyncArgs {
24262484
pub installer: ResolverInstallerArgs,
24272485

24282486
#[command(flatten)]
2429-
pub build: BuildArgs,
2487+
pub build: BuildOptionsArgs,
24302488

24312489
#[command(flatten)]
24322490
pub refresh: RefreshArgs,
@@ -2479,7 +2537,7 @@ pub struct LockArgs {
24792537
pub resolver: ResolverArgs,
24802538

24812539
#[command(flatten)]
2482-
pub build: BuildArgs,
2540+
pub build: BuildOptionsArgs,
24832541

24842542
#[command(flatten)]
24852543
pub refresh: RefreshArgs,
@@ -2593,7 +2651,7 @@ pub struct AddArgs {
25932651
pub installer: ResolverInstallerArgs,
25942652

25952653
#[command(flatten)]
2596-
pub build: BuildArgs,
2654+
pub build: BuildOptionsArgs,
25972655

25982656
#[command(flatten)]
25992657
pub refresh: RefreshArgs,
@@ -2662,7 +2720,7 @@ pub struct RemoveArgs {
26622720
pub installer: ResolverInstallerArgs,
26632721

26642722
#[command(flatten)]
2665-
pub build: BuildArgs,
2723+
pub build: BuildOptionsArgs,
26662724

26672725
#[command(flatten)]
26682726
pub refresh: RefreshArgs,
@@ -2722,7 +2780,7 @@ pub struct TreeArgs {
27222780
pub frozen: bool,
27232781

27242782
#[command(flatten)]
2725-
pub build: BuildArgs,
2783+
pub build: BuildOptionsArgs,
27262784

27272785
#[command(flatten)]
27282786
pub resolver: ResolverArgs,
@@ -2819,7 +2877,7 @@ pub struct ExportArgs {
28192877
pub resolver: ResolverArgs,
28202878

28212879
#[command(flatten)]
2822-
pub build: BuildArgs,
2880+
pub build: BuildOptionsArgs,
28232881

28242882
#[command(flatten)]
28252883
pub refresh: RefreshArgs,
@@ -2966,7 +3024,7 @@ pub struct ToolRunArgs {
29663024
pub installer: ResolverInstallerArgs,
29673025

29683026
#[command(flatten)]
2969-
pub build: BuildArgs,
3027+
pub build: BuildOptionsArgs,
29703028

29713029
#[command(flatten)]
29723030
pub refresh: RefreshArgs,
@@ -3018,7 +3076,7 @@ pub struct ToolInstallArgs {
30183076
pub installer: ResolverInstallerArgs,
30193077

30203078
#[command(flatten)]
3021-
pub build: BuildArgs,
3079+
pub build: BuildOptionsArgs,
30223080

30233081
#[command(flatten)]
30243082
pub refresh: RefreshArgs,
@@ -3103,7 +3161,7 @@ pub struct ToolUpgradeArgs {
31033161
pub installer: ResolverInstallerArgs,
31043162

31053163
#[command(flatten)]
3106-
pub build: BuildArgs,
3164+
pub build: BuildOptionsArgs,
31073165
}
31083166

31093167
#[derive(Args)]
@@ -3407,7 +3465,7 @@ pub struct RefreshArgs {
34073465

34083466
#[derive(Args)]
34093467
#[allow(clippy::struct_excessive_bools)]
3410-
pub struct BuildArgs {
3468+
pub struct BuildOptionsArgs {
34113469
/// Don't build source distributions.
34123470
///
34133471
/// When enabled, resolving will not run arbitrary Python code. The cached wheels of

crates/uv-cli/src/options.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use uv_resolver::PrereleaseMode;
44
use uv_settings::{PipOptions, ResolverInstallerOptions, ResolverOptions};
55

66
use crate::{
7-
BuildArgs, IndexArgs, InstallerArgs, Maybe, RefreshArgs, ResolverArgs, ResolverInstallerArgs,
7+
BuildOptionsArgs, IndexArgs, InstallerArgs, Maybe, RefreshArgs, ResolverArgs,
8+
ResolverInstallerArgs,
89
};
910

1011
/// Given a boolean flag pair (like `--upgrade` and `--no-upgrade`), resolve the value of the flag.
@@ -206,8 +207,11 @@ impl From<IndexArgs> for PipOptions {
206207
}
207208
}
208209

209-
/// Construct the [`ResolverOptions`] from the [`ResolverArgs`] and [`BuildArgs`].
210-
pub fn resolver_options(resolver_args: ResolverArgs, build_args: BuildArgs) -> ResolverOptions {
210+
/// Construct the [`ResolverOptions`] from the [`ResolverArgs`] and [`BuildOptionsArgs`].
211+
pub fn resolver_options(
212+
resolver_args: ResolverArgs,
213+
build_args: BuildOptionsArgs,
214+
) -> ResolverOptions {
211215
let ResolverArgs {
212216
index_args,
213217
upgrade,
@@ -228,7 +232,7 @@ pub fn resolver_options(resolver_args: ResolverArgs, build_args: BuildArgs) -> R
228232
no_sources,
229233
} = resolver_args;
230234

231-
let BuildArgs {
235+
let BuildOptionsArgs {
232236
no_build,
233237
build,
234238
no_build_package,
@@ -281,10 +285,10 @@ pub fn resolver_options(resolver_args: ResolverArgs, build_args: BuildArgs) -> R
281285
}
282286
}
283287

284-
/// Construct the [`ResolverInstallerOptions`] from the [`ResolverInstallerArgs`] and [`BuildArgs`].
288+
/// Construct the [`ResolverInstallerOptions`] from the [`ResolverInstallerArgs`] and [`BuildOptionsArgs`].
285289
pub fn resolver_installer_options(
286290
resolver_installer_args: ResolverInstallerArgs,
287-
build_args: BuildArgs,
291+
build_args: BuildOptionsArgs,
288292
) -> ResolverInstallerOptions {
289293
let ResolverInstallerArgs {
290294
index_args,
@@ -311,7 +315,7 @@ pub fn resolver_installer_options(
311315
no_sources,
312316
} = resolver_installer_args;
313317

314-
let BuildArgs {
318+
let BuildOptionsArgs {
315319
no_build,
316320
build,
317321
no_build_package,

crates/uv-dev/Cargo.toml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,16 @@ workspace = true
1818
[dependencies]
1919
distribution-filename = { workspace = true }
2020
distribution-types = { workspace = true }
21-
install-wheel-rs = { workspace = true }
2221
pep508_rs = { workspace = true }
2322
pypi-types = { workspace = true }
24-
uv-build = { workspace = true }
2523
uv-cache = { workspace = true, features = ["clap"] }
2624
uv-cli = { workspace = true }
2725
uv-client = { workspace = true }
28-
uv-configuration = { workspace = true }
29-
uv-dispatch = { workspace = true }
30-
uv-git = { workspace = true }
3126
uv-installer = { workspace = true }
3227
uv-macros = { workspace = true }
3328
uv-options-metadata = { workspace = true }
3429
uv-python = { workspace = true }
35-
uv-resolver = { workspace = true }
3630
uv-settings = { workspace = true, features = ["schemars"] }
37-
uv-types = { workspace = true }
3831
uv-workspace = { workspace = true, features = ["schemars"] }
3932

4033
# Any dependencies that are exclusively used in `uv-dev` should be listed as non-workspace
@@ -44,12 +37,11 @@ anyhow = { workspace = true }
4437
clap = { workspace = true, features = ["derive", "wrap_help"] }
4538
fs-err = { workspace = true, features = ["tokio"] }
4639
itertools = { workspace = true }
47-
markdown = "0.3.0"
40+
markdown = { version = "0.3.0" }
4841
owo-colors = { workspace = true }
4942
poloto = { version = "19.1.2", optional = true }
5043
pretty_assertions = { version = "1.4.0" }
5144
resvg = { version = "0.29.0", optional = true }
52-
rustc-hash = { workspace = true }
5345
schemars = { workspace = true }
5446
serde = { workspace = true }
5547
serde_json = { workspace = true }

0 commit comments

Comments
 (0)