mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-02 21:02:37 +00:00
Avoid filtering preferences by --reinstall (#3929)
## Summary In general, it's not quite right to filter preferences by `--reinstall` -- we still want to respect existing versions, we just don't want to respect _installed_ versions. But now that the installed versions and preferences are decoupled, we can remove this (`--reinstall` is enforced on the installed versions via the `Exclusions` struct that we pass to the resolver). While I was here, I also cleaned up the lockfile preference code to better match the structure for `requirements.txt`.
This commit is contained in:
parent
438b5c61d0
commit
a14fe2f6c7
6 changed files with 70 additions and 38 deletions
|
|
@ -27,6 +27,7 @@ uv-resolver = { workspace = true, features = ["clap"] }
|
|||
uv-types = { workspace = true }
|
||||
uv-warnings = { workspace = true }
|
||||
|
||||
anstream = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
configparser = { workspace = true }
|
||||
console = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -2,21 +2,26 @@ use std::path::Path;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use anstream::eprint;
|
||||
use requirements_txt::RequirementsTxt;
|
||||
use uv_client::{BaseClientBuilder, Connectivity};
|
||||
use uv_configuration::Upgrade;
|
||||
use uv_resolver::{Preference, PreferenceError};
|
||||
use uv_resolver::{Lock, Preference, PreferenceError};
|
||||
|
||||
/// Load the preferred requirements from an existing lockfile, applying the upgrade strategy.
|
||||
pub async fn read_lockfile(
|
||||
use crate::ProjectWorkspace;
|
||||
|
||||
/// Load the preferred requirements from an existing `requirements.txt`, applying the upgrade strategy.
|
||||
pub async fn read_requirements_txt(
|
||||
output_file: Option<&Path>,
|
||||
upgrade: Upgrade,
|
||||
upgrade: &Upgrade,
|
||||
) -> Result<Vec<Preference>> {
|
||||
// As an optimization, skip reading the lockfile is we're upgrading all packages anyway.
|
||||
let Some(output_file) = output_file
|
||||
.filter(|_| !upgrade.is_all())
|
||||
.filter(|output_file| output_file.exists())
|
||||
else {
|
||||
if upgrade.is_all() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
// If the lockfile doesn't exist, don't respect any pinned versions.
|
||||
let Some(output_file) = output_file.filter(|path| path.exists()) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
|
||||
|
|
@ -27,6 +32,8 @@ pub async fn read_lockfile(
|
|||
&BaseClientBuilder::new().connectivity(Connectivity::Offline),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Map each entry in the lockfile to a preference.
|
||||
let preferences = requirements_txt
|
||||
.requirements
|
||||
.into_iter()
|
||||
|
|
@ -47,3 +54,50 @@ pub async fn read_lockfile(
|
|||
.collect(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Load the preferred requirements from an existing lockfile, applying the upgrade strategy.
|
||||
pub async fn read_lockfile(
|
||||
project: &ProjectWorkspace,
|
||||
upgrade: &Upgrade,
|
||||
) -> Result<Vec<Preference>> {
|
||||
// As an optimization, skip reading the lockfile is we're upgrading all packages anyway.
|
||||
if upgrade.is_all() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
// If an existing lockfile exists, build up a set of preferences.
|
||||
let lockfile = project.workspace().root().join("uv.lock");
|
||||
let lock = match fs_err::tokio::read_to_string(&lockfile).await {
|
||||
Ok(encoded) => match toml::from_str::<Lock>(&encoded) {
|
||||
Ok(lock) => lock,
|
||||
Err(err) => {
|
||||
eprint!("Failed to parse lockfile; ignoring locked requirements: {err}");
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
},
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
|
||||
// Map each entry in the lockfile to a preference.
|
||||
let preferences: Vec<Preference> = lock
|
||||
.distributions()
|
||||
.iter()
|
||||
.map(Preference::from_lock)
|
||||
.collect();
|
||||
|
||||
// Apply the upgrade strategy to the requirements.
|
||||
Ok(match upgrade {
|
||||
// Respect all pinned versions from the existing lockfile.
|
||||
Upgrade::None => preferences,
|
||||
// Ignore all pinned versions from the existing lockfile.
|
||||
Upgrade::All => vec![],
|
||||
// Ignore pinned versions for the specified packages.
|
||||
Upgrade::Packages(packages) => preferences
|
||||
.into_iter()
|
||||
.filter(|preference| !packages.contains(preference.name()))
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue