From d3e3f4e519e6bd556c529f260d0ad6c90944f071 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Fri, 20 Jun 2025 15:17:02 -0400 Subject: [PATCH] Add better diagnostic for lock --check --- crates/uv/src/commands/project/lock.rs | 19 +++++++++++++++++-- crates/uv/src/commands/project/mod.rs | 2 +- crates/uv/src/commands/project/sync.rs | 10 +++++----- crates/uv/tests/it/lock.rs | 9 +++++++-- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index 97ee01767..429ce3d98 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -232,6 +232,18 @@ pub(crate) async fn lock( Ok(ExitStatus::Success) } + Err(ProjectError::LockMismatch(previous, lock)) => { + // we're --locked and there was a mismatch, show all changes and exit as Failure + for event in LockEvent::detect_changes(previous.as_deref(), &lock, dry_run) { + writeln!(printer.stderr(), "{event}")?; + } + writeln!( + printer.stderr(), + "{}", + "The lockfile is outdated; run `uv lock` to update it".bold() + )?; + Ok(ExitStatus::Failure) + } Err(ProjectError::Operation(err)) => { diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls) .report(err) @@ -340,8 +352,11 @@ impl<'env> LockOperation<'env> { .await?; // If the lockfile changed, return an error. - if matches!(result, LockResult::Changed(_, _)) { - return Err(ProjectError::LockMismatch(Box::new(result.into_lock()))); + if let LockResult::Changed(prev, cur) = result { + return Err(ProjectError::LockMismatch( + prev.map(Box::new), + Box::new(cur), + )); } Ok(result) diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index a3249b11a..02823e036 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -75,7 +75,7 @@ pub(crate) enum ProjectError { #[error( "The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`." )] - LockMismatch(Box), + LockMismatch(Option>, Box), #[error( "Unable to find lockfile at `uv.lock`. To create a lockfile, run `uv lock` or `uv sync`." diff --git a/crates/uv/src/commands/project/sync.rs b/crates/uv/src/commands/project/sync.rs index f1a73b8c8..12bf3caae 100644 --- a/crates/uv/src/commands/project/sync.rs +++ b/crates/uv/src/commands/project/sync.rs @@ -422,10 +422,10 @@ pub(crate) async fn sync( .report(err) .map_or(Ok(ExitStatus::Failure), |err| Err(err.into())); } - Err(ProjectError::LockMismatch(lock)) if dry_run.enabled() => { + Err(ProjectError::LockMismatch(prev, cur)) if dry_run.enabled() => { // The lockfile is mismatched, but we're in dry-run mode. We should proceed with the // sync operation, but exit with a non-zero status. - Outcome::LockMismatch(lock) + Outcome::LockMismatch(prev, cur) } Err(err) => return Err(err.into()), }; @@ -469,7 +469,7 @@ pub(crate) async fn sync( match outcome { Outcome::Success(..) => Ok(ExitStatus::Success), - Outcome::LockMismatch(lock) => Err(ProjectError::LockMismatch(lock).into()), + Outcome::LockMismatch(prev, cur) => Err(ProjectError::LockMismatch(prev, cur).into()), } } @@ -480,7 +480,7 @@ enum Outcome { /// The `lock` operation was successful. Success(Lock), /// The `lock` operation successfully resolved, but failed due to a mismatch (e.g., with `--locked`). - LockMismatch(Box), + LockMismatch(Option>, Box), } impl Outcome { @@ -488,7 +488,7 @@ impl Outcome { fn lock(&self) -> &Lock { match self { Self::Success(lock) => lock, - Self::LockMismatch(lock) => lock, + Self::LockMismatch(_prev, cur) => cur, } } } diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 1144674a8..03afb3a0b 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -11826,12 +11826,17 @@ fn check_outdated_lock() -> Result<()> { uv_snapshot!(context.filters(), context.lock() .arg("--check"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 2 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + Added iniconfig v2.0.0 + Removed myproject v0.1.0 + Added project v0.1.0 + Removed sortedcollections v2.1.0 + Removed sortedcontainers v2.4.0 + The lockfile is outdated; run `uv lock` to update it "); Ok(()) }