diff --git a/Cargo.lock b/Cargo.lock index 519885d011503..9f13b43670f1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4457,6 +4457,7 @@ dependencies = [ "thiserror", "tikv-jemallocator", "tokio", + "toml", "tracing", "tracing-durations-export", "tracing-subscriber", diff --git a/crates/uv/Cargo.toml b/crates/uv/Cargo.toml index be4a1e5e3759f..13dc5c6b58038 100644 --- a/crates/uv/Cargo.toml +++ b/crates/uv/Cargo.toml @@ -58,6 +58,7 @@ tempfile = { workspace = true } textwrap = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } +toml = { workspace = true } tracing = { workspace = true } tracing-durations-export = { workspace = true, features = ["plot"], optional = true } tracing-subscriber = { workspace = true, features = ["json"] } diff --git a/crates/uv/src/cli.rs b/crates/uv/src/cli.rs index e9df8fdc41761..97de3d6528d97 100644 --- a/crates/uv/src/cli.rs +++ b/crates/uv/src/cli.rs @@ -601,6 +601,12 @@ pub(crate) struct PipCompileArgs { #[arg(long, overrides_with("emit_index_annotation"), hide = true)] pub(crate) no_emit_index_annotation: bool, + #[arg(long, overrides_with("no_unstable_uv_lock_file"), hide = true)] + pub(crate) unstable_uv_lock_file: bool, + + #[arg(long, overrides_with("unstable_uv_lock_file"), hide = true)] + pub(crate) no_unstable_uv_lock_file: bool, + #[command(flatten)] pub(crate) compat_args: compat::PipCompileCompatArgs, } diff --git a/crates/uv/src/commands/pip_compile.rs b/crates/uv/src/commands/pip_compile.rs index 434fb7164ef30..0828ab5b15dda 100644 --- a/crates/uv/src/commands/pip_compile.rs +++ b/crates/uv/src/commands/pip_compile.rs @@ -8,6 +8,7 @@ use std::str::FromStr; use anstream::{eprint, AutoStream, StripStream}; use anyhow::{anyhow, Context, Result}; +use fs_err as fs; use itertools::Itertools; use owo_colors::OwoColorize; use tempfile::tempdir_in; @@ -84,6 +85,7 @@ pub(crate) async fn pip_compile( link_mode: LinkMode, python: Option, system: bool, + uv_lock: bool, native_tls: bool, quiet: bool, cache: Cache, @@ -525,6 +527,12 @@ pub(crate) async fn pip_compile( writeln!(writer, "{}", format!("# {relevant_markers}").green())?; } + if uv_lock { + let lock = resolution.lock()?; + let encoded = toml::to_string_pretty(&lock)?; + fs::tokio::write("uv.lock", encoded.as_bytes()).await?; + } + // Write the index locations to the output channel. let mut wrote_index = false; diff --git a/crates/uv/src/main.rs b/crates/uv/src/main.rs index 87701452a431a..836f2199c1d02 100644 --- a/crates/uv/src/main.rs +++ b/crates/uv/src/main.rs @@ -229,6 +229,7 @@ async fn run() -> Result { args.shared.link_mode, args.shared.python, args.shared.system, + args.uv_lock, globals.native_tls, globals.quiet, cache, diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 745c6767d3717..a55d88fe24f26 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -127,6 +127,7 @@ pub(crate) struct PipCompileSettings { pub(crate) r#override: Vec, pub(crate) refresh: Refresh, pub(crate) upgrade: Upgrade, + pub(crate) uv_lock: bool, // Shared settings. pub(crate) shared: PipSharedSettings, @@ -194,6 +195,8 @@ impl PipCompileSettings { no_emit_marker_expression, emit_index_annotation, no_emit_index_annotation, + unstable_uv_lock_file, + no_unstable_uv_lock_file, compat_args: _, } = args; @@ -207,6 +210,7 @@ impl PipCompileSettings { r#override, refresh: Refresh::from_args(refresh, refresh_package), upgrade: Upgrade::from_args(upgrade, upgrade_package), + uv_lock: flag(unstable_uv_lock_file, no_unstable_uv_lock_file).unwrap_or(false), // Shared settings. shared: PipSharedSettings::combine(