Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 4 additions & 31 deletions crates/uv-resolver/src/lock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ static ANDROID_X86_MARKERS: LazyLock<UniversalMarker> = LazyLock::new(|| {
marker
});

#[derive(Clone, Debug, serde::Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
#[serde(try_from = "LockWire")]
pub struct Lock {
/// The (major) version of the lockfile format.
Expand Down Expand Up @@ -3233,34 +3233,6 @@ struct PackageMetadata {
dependency_groups: BTreeMap<GroupName, BTreeSet<Requirement>>,
}

impl PackageMetadata {
fn unwire(self, requires_python: &RequiresPython) -> Self {
// We need to complexify these markers so things like
// `requires_python < '0'` get normalized to False
let unwire_requirements = |requirements: BTreeSet<Requirement>| -> BTreeSet<Requirement> {
requirements
.into_iter()
.map(|mut requirement| {
let complexified_marker =
requires_python.complexify_markers(requirement.marker);
requirement.marker = complexified_marker;
requirement
})
.collect()
};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not necessary because we simplify the markers when comparing? I ran through the test cases from the linked PR (https://github.com/astral-sh/uv/pull/13635/files#diff-82edd36151736f44055f699a34c8b19a63ffc4cf3c86bf5fb34d69f8ac88a957) and they still pass.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\cc @Gankra


Self {
requires_dist: unwire_requirements(self.requires_dist),
provides_extra: self.provides_extra,
dependency_groups: self
.dependency_groups
.into_iter()
.map(|(group, requirements)| (group, unwire_requirements(requirements)))
.collect(),
}
}
}

impl PackageWire {
fn unwire(
self,
Expand Down Expand Up @@ -3292,7 +3264,7 @@ impl PackageWire {

Ok(Package {
id: self.id,
metadata: self.metadata.unwire(requires_python),
metadata: self.metadata,
sdist: self.sdist,
wheels: self.wheels,
fork_markers: self
Expand Down Expand Up @@ -4826,11 +4798,12 @@ impl Dependency {
) -> Self {
let simplified_marker =
SimplifiedMarkerTree::new(requires_python, complexified_marker.combined());
let complexified_marker = simplified_marker.into_marker(requires_python);
Self {
package_id,
extra,
simplified_marker,
complexified_marker,
complexified_marker: UniversalMarker::from_combined(complexified_marker),
}
}

Expand Down
40 changes: 35 additions & 5 deletions crates/uv/src/commands/project/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use owo_colors::OwoColorize;
use rustc_hash::{FxBuildHasher, FxHashMap};
use tracing::debug;

use uv_cache::Cache;
use uv_cache::{Cache, Refresh};
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
Concurrency, Constraints, DependencyGroupsWithDefaults, DryRun, ExtrasSpecification, Reinstall,
Expand Down Expand Up @@ -84,6 +84,7 @@ pub(crate) async fn lock(
locked: bool,
frozen: bool,
dry_run: DryRun,
refresh: Refresh,
python: Option<String>,
install_mirrors: PythonInstallMirrors,
settings: ResolverSettings,
Expand Down Expand Up @@ -201,20 +202,25 @@ pub(crate) async fn lock(
printer,
preview,
)
.with_refresh(&refresh)
.execute(target)
.await
{
Ok(lock) => {
if dry_run.enabled() {
// In `--dry-run` mode, show all changes.
let mut changed = false;
if let LockResult::Changed(previous, lock) = &lock {
let mut changed = false;
for event in LockEvent::detect_changes(previous.as_ref(), lock, dry_run) {
changed = true;
writeln!(printer.stderr(), "{event}")?;
}
}
if !changed {

// If we didn't report any version changes, but the lockfile changed, report back.
if !changed {
writeln!(printer.stderr(), "{}", "Lockfile changes detected".bold())?;
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this because LockResult::Changed now means that there was some change in the lockfile. It's more accurate now.

} else {
writeln!(
printer.stderr(),
"{}",
Expand Down Expand Up @@ -260,6 +266,7 @@ pub(super) enum LockMode<'env> {
pub(super) struct LockOperation<'env> {
mode: LockMode<'env>,
constraints: Vec<NameRequirementSpecification>,
refresh: Option<&'env Refresh>,
settings: &'env ResolverSettings,
client_builder: &'env BaseClientBuilder<'env>,
state: &'env UniversalState,
Expand Down Expand Up @@ -288,6 +295,7 @@ impl<'env> LockOperation<'env> {
Self {
mode,
constraints: vec![],
refresh: None,
settings,
client_builder,
state,
Expand All @@ -310,6 +318,13 @@ impl<'env> LockOperation<'env> {
self
}

/// Set the refresh strategy for the [`LockOperation`].
#[must_use]
pub(super) fn with_refresh(mut self, refresh: &'env Refresh) -> Self {
self.refresh = Some(refresh);
self
}

/// Perform a [`LockOperation`].
pub(super) async fn execute(self, target: LockTarget<'_>) -> Result<LockResult, ProjectError> {
match self.mode {
Expand All @@ -334,6 +349,7 @@ impl<'env> LockOperation<'env> {
interpreter,
Some(existing),
self.constraints,
self.refresh,
self.settings,
self.client_builder,
self.state,
Expand Down Expand Up @@ -376,6 +392,7 @@ impl<'env> LockOperation<'env> {
interpreter,
existing,
self.constraints,
self.refresh,
self.settings,
self.client_builder,
self.state,
Expand Down Expand Up @@ -407,6 +424,7 @@ async fn do_lock(
interpreter: &Interpreter,
existing_lock: Option<Lock>,
external: Vec<NameRequirementSpecification>,
refresh: Option<&Refresh>,
settings: &ResolverSettings,
client_builder: &BaseClientBuilder<'_>,
state: &UniversalState,
Expand Down Expand Up @@ -743,6 +761,7 @@ async fn do_lock(
&requires_python,
index_locations,
upgrade,
refresh,
&options,
&hasher,
state.index(),
Expand Down Expand Up @@ -917,7 +936,11 @@ async fn do_lock(
.unwrap_or_default(),
);

Ok(LockResult::Changed(previous, lock))
if previous.as_ref().is_some_and(|previous| *previous == lock) {
Ok(LockResult::Unchanged(lock))
} else {
Ok(LockResult::Changed(previous, lock))
}
}
}
}
Expand Down Expand Up @@ -957,6 +980,7 @@ impl ValidatedLock {
requires_python: &RequiresPython,
index_locations: &IndexLocations,
upgrade: &Upgrade,
refresh: Option<&Refresh>,
options: &Options,
hasher: &HashStrategy,
index: &InMemoryIndex,
Expand Down Expand Up @@ -1142,6 +1166,12 @@ impl ValidatedLock {
return Ok(Self::Versions(lock));
}

// If the user specified `--refresh`, then we have to re-resolve.
if matches!(refresh, Some(Refresh::All(..) | Refresh::Packages(..))) {
debug!("Resolving despite existing lockfile due to `--refresh`");
return Ok(Self::Preferable(lock));
}

// If the user provided at least one index URL (from the command line, or from a configuration
// file), don't use the existing lockfile if it references any registries that are no longer
// included in the current configuration.
Expand Down
2 changes: 2 additions & 0 deletions crates/uv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,7 @@ async fn run_project(
// Initialize the cache.
let cache = cache.init()?.with_refresh(
args.refresh
.clone()
.combine(Refresh::from(args.settings.upgrade.clone())),
);

Expand All @@ -1923,6 +1924,7 @@ async fn run_project(
args.locked,
args.frozen,
args.dry_run,
args.refresh,
args.python,
args.install_mirrors,
args.settings,
Expand Down
Loading
Loading