diff --git a/crates/uv/src/commands/diagnostics.rs b/crates/uv/src/commands/diagnostics.rs index 7a9fcbd35..02412d683 100644 --- a/crates/uv/src/commands/diagnostics.rs +++ b/crates/uv/src/commands/diagnostics.rs @@ -127,6 +127,10 @@ impl OperationDiagnostic { native_tls_hint(err); None } + pip::operations::Error::OutdatedEnvironment => { + anstream::eprint!("{}", err); + None + } err => Some(err), } } diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index f79557d9e..833e59a13 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -234,6 +234,10 @@ pub(crate) async fn lock( Ok(ExitStatus::Success) } + Err(err @ ProjectError::LockMismatch(..)) => { + writeln!(printer.stderr(), "{}", err.to_string().bold())?; + Ok(ExitStatus::Failure) + } Err(ProjectError::Operation(err)) => { diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls) .report(err) @@ -346,8 +350,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 eaccaefa6..fde2b638c 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 5843df6be..40aa1b352 100644 --- a/crates/uv/src/commands/project/sync.rs +++ b/crates/uv/src/commands/project/sync.rs @@ -330,10 +330,19 @@ pub(crate) async fn sync( .report(err) .map_or(Ok(ExitStatus::Failure), |err| Err(err.into())); } - Err(ProjectError::LockMismatch(lock)) 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) + 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(prev, cur) + } else { + writeln!( + printer.stderr(), + "{}", + ProjectError::LockMismatch(prev, cur).to_string().bold() + )?; + return Ok(ExitStatus::Failure); + } } Err(err) => return Err(err.into()), }; @@ -398,7 +407,14 @@ pub(crate) async fn sync( match outcome { Outcome::Success(..) => Ok(ExitStatus::Success), - Outcome::LockMismatch(lock) => Err(ProjectError::LockMismatch(lock).into()), + Outcome::LockMismatch(prev, cur) => { + writeln!( + printer.stderr(), + "{}", + ProjectError::LockMismatch(prev, cur).to_string().bold() + )?; + Ok(ExitStatus::Failure) + } } } @@ -409,15 +425,18 @@ enum Outcome { /// The `lock` operation was successful. Success(LockResult), /// The `lock` operation successfully resolved, but failed due to a mismatch (e.g., with `--locked`). - LockMismatch(Box), + LockMismatch(Option>, Box), } impl Outcome { /// Return the [`Lock`] associated with this outcome. fn lock(&self) -> &Lock { match self { - Self::Success(lock) => lock.lock(), - Self::LockMismatch(lock) => lock, + Self::Success(lock) => match lock { + LockResult::Changed(_, lock) => lock, + LockResult::Unchanged(lock) => lock, + }, + Self::LockMismatch(_prev, cur) => cur, } } } @@ -1179,7 +1198,7 @@ impl From<(&LockTarget<'_>, &LockMode<'_>, &Outcome)> for LockReport { } } // TODO(zanieb): We don't have a way to report the outcome of the lock yet - Outcome::LockMismatch(_) => LockAction::Check, + Outcome::LockMismatch(..) => LockAction::Check, }, dry_run: matches!(mode, LockMode::DryRun(_)), } diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index d7ac9b47a..faf37a83a 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -6660,15 +6660,15 @@ fn lock_invalid_hash() -> Result<()> { "#)?; // Re-run with `--locked`. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Install from the lockfile. uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###" @@ -11743,6 +11743,95 @@ fn unconditional_overlapping_marker_disjoint_version_constraints() -> Result<()> Ok(()) } +/// Checks the output of `uv lock --check` when there isn't a lock +#[test] +fn check_no_lock() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "myproject" + version = "0.1.0" + requires-python = ">=3.11" + dependencies = ["sortedcollections"] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock() + .arg("--check"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Unable to find lockfile at `uv.lock`. To create a lockfile, run `uv lock` or `uv sync`. + "); + Ok(()) +} + +/// Checks the output of `uv lock --check` when the lock is outdated +#[test] +fn check_outdated_lock() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "myproject" + version = "0.1.0" + requires-python = ">=3.11" + dependencies = ["sortedcollections"] + "#, + )?; + + // Generate the lock + uv_snapshot!(context.filters(), context.lock(), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + "); + + // Check the --check returns fine + uv_snapshot!(context.filters(), context.lock() + .arg("--check"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + "); + + // Edit dependencies so the lock is invalid + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.11" + dependencies = ["iniconfig"] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock() + .arg("--check"), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); + Ok(()) +} + /// This checks that markers that normalize to 'false', which are serialized /// to the lockfile as `python_full_version < '0'`, get read back as false. /// Otherwise `uv lock --check` will always fail. @@ -12094,15 +12183,15 @@ fn lock_remove_member() -> Result<()> { )?; // Re-run with `--locked`. This should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-run without `--locked`. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -12239,15 +12328,15 @@ fn lock_add_member() -> Result<()> { )?; // Re-run with `--locked`. This should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 5 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-run with `--offline`. This should also fail, during the resolve phase. uv_snapshot!(context.filters(), context.lock().arg("--locked").arg("--offline").arg("--no-cache"), @r###" @@ -12476,15 +12565,15 @@ fn lock_redundant_add_member() -> Result<()> { // Re-run with `--locked`. This will fail, though in theory it could succeed, since the current // _resolution_ satisfies the requirements, even if the inputs are not identical - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-run without `--locked`. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -12674,15 +12763,15 @@ fn lock_new_constraints() -> Result<()> { )?; // Re-run with `--locked`. This should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-run without `--locked`. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -12883,16 +12972,16 @@ fn lock_remove_member_non_project() -> Result<()> { )?; // Re-run with `--locked`. This should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- warning: No `requires-python` value found in the workspace. Defaulting to `>=3.12`. Resolved in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-run without `--locked`. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -13015,15 +13104,15 @@ fn lock_rename_project() -> Result<()> { )?; // Re-run with `--locked`. This should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @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`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-run without `--locked`. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -14015,15 +14104,15 @@ fn lock_constrained_environment() -> Result<()> { )?; // Re-run with `--locked`. This should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 8 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); uv_snapshot!(context.filters(), context.lock(), @r###" success: true @@ -15278,15 +15367,15 @@ fn lock_add_empty_dependency_group() -> Result<()> { )?; // Re-run with `--locked`; this should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @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`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-lock the project. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -15360,15 +15449,15 @@ fn lock_add_empty_dependency_group() -> Result<()> { )?; // Re-run with `--locked`; this should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @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`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); // Re-lock the project. uv_snapshot!(context.filters(), context.lock(), @r###" @@ -23253,15 +23342,15 @@ fn lock_dynamic_to_static() -> Result<()> { )?; // Rerunning with `--locked` should fail, since the project is no longer dynamic. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); uv_snapshot!(context.filters(), context.lock(), @r###" success: true @@ -23384,15 +23473,15 @@ fn lock_static_to_dynamic() -> Result<()> { .write_str("__version__ = '0.1.0'")?; // Rerunning with `--locked` should fail, since the project is no longer static. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); uv_snapshot!(context.filters(), context.lock(), @r###" success: true @@ -23486,15 +23575,15 @@ fn lock_bump_static_version() -> Result<()> { )?; // Rerunning with `--locked` should fail. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); uv_snapshot!(context.filters(), context.lock(), @r###" success: true @@ -25302,15 +25391,15 @@ fn lock_script() -> Result<()> { })?; // Re-run with `--locked`. - uv_snapshot!(context.filters(), context.lock().arg("--script").arg("script.py").arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--script").arg("script.py").arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); Ok(()) } @@ -27631,15 +27720,15 @@ fn lock_empty_extra() -> Result<()> { )?; // Re-run with `--locked`. We expect this to fail, since we've added an extra. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 3 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); uv_snapshot!(context.filters(), context.lock(), @r###" success: true @@ -27667,15 +27756,15 @@ fn lock_empty_extra() -> Result<()> { )?; // Re-run with `--locked`. We expect this to fail, since we've added an extra. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 3 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. - "###); + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "); uv_snapshot!(context.filters(), context.lock(), @r###" success: true @@ -28341,12 +28430,12 @@ fn lock_trailing_slash_index_url_in_pyproject_not_index_argument() -> Result<()> // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); Ok(()) @@ -28432,12 +28521,12 @@ fn lock_trailing_slash_index_url_in_lockfile_not_pyproject() -> Result<()> { // Run `uv lock --locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); Ok(()) @@ -28523,12 +28612,12 @@ fn lock_trailing_slash_index_url_in_pyproject_and_not_lockfile() -> Result<()> { // Run `uv lock --locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); Ok(()) @@ -28714,12 +28803,12 @@ fn lock_trailing_slash_find_links() -> Result<()> { // Re-run with `--locked` uv_snapshot!(context.filters(), context.lock().arg("--locked"), @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`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); uv_snapshot!(context.filters(), context.lock(), @r" diff --git a/crates/uv/tests/it/sync.rs b/crates/uv/tests/it/sync.rs index 0165cc7f6..c225225b8 100644 --- a/crates/uv/tests/it/sync.rs +++ b/crates/uv/tests/it/sync.rs @@ -88,12 +88,12 @@ fn locked() -> Result<()> { // Running with `--locked` should error. uv_snapshot!(context.filters(), context.sync().arg("--locked"), @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`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); let updated = context.read("uv.lock"); @@ -424,12 +424,12 @@ fn sync_json() -> Result<()> { .arg("--locked") .arg("--output-format").arg("json"), @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`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); Ok(()) @@ -894,7 +894,7 @@ fn check() -> Result<()> { // Running `uv sync --check` should fail. uv_snapshot!(context.filters(), context.sync().arg("--check"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- @@ -904,7 +904,7 @@ fn check() -> Result<()> { Would download 1 package Would install 1 package + iniconfig==2.0.0 - error: The environment is outdated; run `uv sync` to update the environment + The environment is outdated; run `uv sync` to update the environment "); // Sync the environment. @@ -8626,7 +8626,7 @@ fn sync_dry_run_and_locked() -> Result<()> { // Running with `--locked` and `--dry-run` should error. uv_snapshot!(context.filters(), context.sync().arg("--locked").arg("--dry-run"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- @@ -8635,7 +8635,7 @@ fn sync_dry_run_and_locked() -> Result<()> { Would download 1 package Would install 1 package + iniconfig==2.0.0 - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); let updated = context.read("uv.lock"); @@ -8962,13 +8962,13 @@ fn sync_locked_script() -> Result<()> { // Re-run with `--locked`. uv_snapshot!(&filters, context.sync().arg("--script").arg("script.py").arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Using script environment at: [CACHE_DIR]/environments-v2/script-[HASH] Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); uv_snapshot!(&filters, context.sync().arg("--script").arg("script.py"), @r" @@ -9064,14 +9064,14 @@ fn sync_locked_script() -> Result<()> { // Re-run with `--locked`. uv_snapshot!(&filters, context.sync().arg("--script").arg("script.py").arg("--locked"), @r" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Updating script environment at: [CACHE_DIR]/environments-v2/script-[HASH] warning: Ignoring existing lockfile due to fork markers being disjoint with `requires-python`: `python_full_version >= '3.11'` vs `python_full_version >= '3.8' and python_full_version < '3.11'` Resolved 6 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); uv_snapshot!(&filters, context.sync().arg("--script").arg("script.py"), @r" @@ -9944,12 +9944,12 @@ fn sync_build_constraints() -> Result<()> { // This should fail, given that the build constraints have changed. uv_snapshot!(context.filters(), context.sync().arg("--locked"), @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`. + The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "); // Changing the build constraints should lead to a re-resolve.