mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-01 06:21:13 +00:00
Always show lock updates in uv lock
(#5413)
## Summary Closes https://github.com/astral-sh/uv/issues/5412.
This commit is contained in:
parent
3d36b71ab1
commit
22db997240
7 changed files with 56 additions and 41 deletions
|
@ -244,7 +244,7 @@ pub(crate) async fn add(
|
|||
project::sync::do_sync(
|
||||
&VirtualProject::Project(project),
|
||||
&venv,
|
||||
&lock,
|
||||
&lock.lock,
|
||||
&extras,
|
||||
dev,
|
||||
Modifications::Sufficient,
|
||||
|
|
|
@ -32,6 +32,15 @@ use crate::commands::{pip, ExitStatus};
|
|||
use crate::printer::Printer;
|
||||
use crate::settings::{ResolverSettings, ResolverSettingsRef};
|
||||
|
||||
/// The result of running a lock operation.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct LockResult {
|
||||
/// The previous lock, if any.
|
||||
pub(crate) previous: Option<Lock>,
|
||||
/// The updated lock.
|
||||
pub(crate) lock: Lock,
|
||||
}
|
||||
|
||||
/// Resolve the project requirements into a lockfile.
|
||||
pub(crate) async fn lock(
|
||||
locked: bool,
|
||||
|
@ -86,7 +95,12 @@ pub(crate) async fn lock(
|
|||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Ok(ExitStatus::Success),
|
||||
Ok(lock) => {
|
||||
if let Some(previous) = lock.previous.as_ref() {
|
||||
report_upgrades(previous, &lock.lock, printer)?;
|
||||
}
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
Err(ProjectError::Operation(pip::operations::Error::Resolve(
|
||||
uv_resolver::ResolveError::NoSolution(err),
|
||||
))) => {
|
||||
|
@ -112,12 +126,16 @@ pub(super) async fn do_safe_lock(
|
|||
native_tls: bool,
|
||||
cache: &Cache,
|
||||
printer: Printer,
|
||||
) -> Result<Lock, ProjectError> {
|
||||
) -> Result<LockResult, ProjectError> {
|
||||
if frozen {
|
||||
// Read the existing lockfile, but don't attempt to lock the project.
|
||||
read(workspace)
|
||||
let existing = read(workspace)
|
||||
.await?
|
||||
.ok_or_else(|| ProjectError::MissingLockfile)
|
||||
.ok_or_else(|| ProjectError::MissingLockfile)?;
|
||||
Ok(LockResult {
|
||||
previous: None,
|
||||
lock: existing,
|
||||
})
|
||||
} else if locked {
|
||||
// Read the existing lockfile.
|
||||
let existing = read(workspace)
|
||||
|
@ -145,7 +163,10 @@ pub(super) async fn do_safe_lock(
|
|||
return Err(ProjectError::LockMismatch);
|
||||
}
|
||||
|
||||
Ok(lock)
|
||||
Ok(LockResult {
|
||||
previous: Some(existing),
|
||||
lock,
|
||||
})
|
||||
} else {
|
||||
// Read the existing lockfile.
|
||||
let existing = read(workspace).await?;
|
||||
|
@ -166,16 +187,19 @@ pub(super) async fn do_safe_lock(
|
|||
)
|
||||
.await?;
|
||||
|
||||
if !existing.is_some_and(|existing| existing == lock) {
|
||||
if !existing.as_ref().is_some_and(|existing| *existing == lock) {
|
||||
commit(&lock, workspace).await?;
|
||||
}
|
||||
|
||||
Ok(lock)
|
||||
Ok(LockResult {
|
||||
previous: existing,
|
||||
lock,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Lock the project requirements into a lockfile.
|
||||
pub(super) async fn do_lock(
|
||||
async fn do_lock(
|
||||
workspace: &Workspace,
|
||||
interpreter: &Interpreter,
|
||||
existing_lock: Option<&Lock>,
|
||||
|
@ -506,16 +530,7 @@ pub(super) async fn do_lock(
|
|||
// Notify the user of any resolution diagnostics.
|
||||
pip::operations::diagnose_resolution(resolution.diagnostics(), printer)?;
|
||||
|
||||
let new_lock = Lock::from_resolution_graph(&resolution)?;
|
||||
|
||||
// Notify the user of any dependency updates
|
||||
if !upgrade.is_none() {
|
||||
if let Some(existing_lock) = existing_lock {
|
||||
report_upgrades(existing_lock, &new_lock, printer)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(new_lock)
|
||||
Ok(Lock::from_resolution_graph(&resolution)?)
|
||||
}
|
||||
|
||||
/// Write the lockfile to disk.
|
||||
|
|
|
@ -131,7 +131,7 @@ pub(crate) async fn remove(
|
|||
project::sync::do_sync(
|
||||
&VirtualProject::Project(project),
|
||||
&venv,
|
||||
&lock,
|
||||
&lock.lock,
|
||||
&extras,
|
||||
dev,
|
||||
Modifications::Exact,
|
||||
|
|
|
@ -238,7 +238,7 @@ pub(crate) async fn run(
|
|||
project::sync::do_sync(
|
||||
&project,
|
||||
&venv,
|
||||
&lock,
|
||||
&lock.lock,
|
||||
&extras,
|
||||
dev,
|
||||
Modifications::Sufficient,
|
||||
|
|
|
@ -95,7 +95,7 @@ pub(crate) async fn sync(
|
|||
do_sync(
|
||||
&project,
|
||||
&venv,
|
||||
&lock,
|
||||
&lock.lock,
|
||||
&extras,
|
||||
dev,
|
||||
modifications,
|
||||
|
|
|
@ -83,7 +83,7 @@ pub(crate) async fn tree(
|
|||
|
||||
// Read packages from the lockfile.
|
||||
let mut packages: IndexMap<_, Vec<_>> = IndexMap::new();
|
||||
for dist in lock.into_distributions() {
|
||||
for dist in lock.lock.into_distributions() {
|
||||
let name = dist.name().clone();
|
||||
let metadata = dist.to_metadata(workspace.install_path())?;
|
||||
packages.entry(name).or_default().push(metadata);
|
||||
|
|
|
@ -3569,23 +3569,23 @@ fn lock_new_extras() -> Result<()> {
|
|||
"#,
|
||||
)?;
|
||||
|
||||
deterministic! { context =>
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--preview"), @r###"
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--preview"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
Added pysocks v1.7.1
|
||||
"###);
|
||||
|
||||
let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
|
||||
let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
|
||||
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
exclude-newer = "2024-03-25 00:00:00 UTC"
|
||||
|
@ -3678,9 +3678,8 @@ fn lock_new_extras() -> Result<()> {
|
|||
{ url = "https://files.pythonhosted.org/packages/a2/73/a68704750a7679d0b6d3ad7aa8d4da8e14e151ae82e6fee774e6e0d05ec8/urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", size = 121067 },
|
||||
]
|
||||
"###
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -3863,14 +3862,15 @@ fn lock_resolution_mode() -> Result<()> {
|
|||
|
||||
// Locking with `lowest-direct` should ignore the existing lockfile.
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--resolution").arg("lowest-direct"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
warning: `uv lock` is experimental and may change without warning
|
||||
Ignoring existing lockfile due to change in resolution mode: `highest` vs. `lowest-direct`
|
||||
Resolved 4 packages in [TIME]
|
||||
----- stderr -----
|
||||
warning: `uv lock` is experimental and may change without warning
|
||||
Ignoring existing lockfile due to change in resolution mode: `highest` vs. `lowest-direct`
|
||||
Resolved 4 packages in [TIME]
|
||||
Updated anyio v4.3.0 -> v3.0.0
|
||||
"###);
|
||||
|
||||
let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue