From 5983a8876b74d0b3cdcf50b7ecb62c281c4dbd9b Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Sat, 8 Nov 2025 09:44:17 -0600 Subject: [PATCH] Refactor to remove some cruft from `ExcludeNewer` propagation (#16641) I think using a wire here is less convoluted. --- crates/uv-resolver/src/lock/mod.rs | 65 ++++++++++--------- ...r__lock__tests__hash_optional_missing.snap | 8 ++- ...r__lock__tests__hash_optional_present.snap | 8 ++- ...r__lock__tests__hash_required_present.snap | 8 ++- ...missing_dependency_source_unambiguous.snap | 8 ++- ...dependency_source_version_unambiguous.snap | 8 ++- ...s__missing_dependency_version_dynamic.snap | 8 ++- ...issing_dependency_version_unambiguous.snap | 8 ++- ...lock__tests__source_direct_has_subdir.snap | 8 ++- ..._lock__tests__source_direct_no_subdir.snap | 8 ++- ...solver__lock__tests__source_directory.snap | 8 ++- ...esolver__lock__tests__source_editable.snap | 8 ++- crates/uv/src/commands/pip/latest.rs | 2 +- crates/uv/src/commands/pip/list.rs | 2 +- crates/uv/src/commands/pip/tree.rs | 2 +- crates/uv/src/commands/project/tree.rs | 2 +- 16 files changed, 103 insertions(+), 58 deletions(-) diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index 4e6a509a1..361249179 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -59,8 +59,8 @@ pub use crate::lock::tree::TreeDisplay; use crate::resolution::{AnnotatedDist, ResolutionGraphNode}; use crate::universal_marker::{ConflictMarker, UniversalMarker}; use crate::{ - ExcludeNewer, ExcludeNewerTimestamp, InMemoryIndex, MetadataResponse, PrereleaseMode, - ResolutionMode, ResolverOutput, + ExcludeNewer, ExcludeNewerPackage, ExcludeNewerTimestamp, InMemoryIndex, MetadataResponse, + PrereleaseMode, ResolutionMode, ResolverOutput, }; mod export; @@ -342,23 +342,12 @@ impl Lock { } let packages = packages.into_values().collect(); - let (exclude_newer, exclude_newer_package) = { - let exclude_newer = &resolution.options.exclude_newer; - let global_exclude_newer = exclude_newer.global; - let package_exclude_newer = if exclude_newer.package.is_empty() { - None - } else { - Some(exclude_newer.package.clone().into_inner()) - }; - (global_exclude_newer, package_exclude_newer) - }; let options = ResolverOptions { resolution_mode: resolution.options.resolution_mode, prerelease_mode: resolution.options.prerelease_mode, fork_strategy: resolution.options.fork_strategy, - exclude_newer, - exclude_newer_package, + exclude_newer: resolution.options.exclude_newer.clone().into(), }; let lock = Self::new( VERSION, @@ -818,7 +807,9 @@ impl Lock { /// Returns the exclude newer setting used to generate this lock. pub fn exclude_newer(&self) -> ExcludeNewer { - self.options.exclude_newer() + // TODO(zanieb): It'd be nice not to hide this clone here, but I am hesitant to introduce + // a whole new `ExcludeNewerRef` type just for this + self.options.exclude_newer.clone().into() } /// Returns the conflicting groups that were used to generate this lock. @@ -1065,7 +1056,7 @@ impl Lock { value(self.options.fork_strategy.to_string()), ); } - let exclude_newer = &self.options.exclude_newer(); + let exclude_newer = ExcludeNewer::from(self.options.exclude_newer.clone()); if !exclude_newer.is_empty() { // Always serialize global exclude-newer as a string if let Some(global) = exclude_newer.global { @@ -2131,24 +2122,34 @@ struct ResolverOptions { /// The [`ForkStrategy`] used to generate this lock. #[serde(default)] fork_strategy: ForkStrategy, - /// The global [`ExcludeNewer`] timestamp. - exclude_newer: Option, - /// Package-specific [`ExcludeNewer`] timestamps. - exclude_newer_package: Option>, + /// The [`ExcludeNewer`] setting used to generate this lock. + #[serde(flatten)] + exclude_newer: ExcludeNewerWire, } -impl ResolverOptions { - /// Get the combined exclude-newer configuration. - fn exclude_newer(&self) -> ExcludeNewer { - ExcludeNewer::from_args( - self.exclude_newer, - self.exclude_newer_package - .clone() - .unwrap_or_default() - .into_iter() - .map(Into::into) - .collect(), - ) +#[derive(Clone, Debug, Default, serde::Deserialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +struct ExcludeNewerWire { + exclude_newer: Option, + #[serde(default, skip_serializing_if = "ExcludeNewerPackage::is_empty")] + exclude_newer_package: ExcludeNewerPackage, +} + +impl From for ExcludeNewer { + fn from(wire: ExcludeNewerWire) -> Self { + Self { + global: wire.exclude_newer, + package: wire.exclude_newer_package, + } + } +} + +impl From for ExcludeNewerWire { + fn from(exclude_newer: ExcludeNewer) -> Self { + Self { + exclude_newer: exclude_newer.global, + exclude_newer_package: exclude_newer.package, + } } } diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap index 7c04e11ef..46298339f 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_present.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_present.snap index 7bddd799b..c5ef76e9a 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_present.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_optional_present.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_required_present.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_required_present.snap index 8bf591754..eb24b2b94 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_required_present.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__hash_required_present.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap index 05079e25c..4414974a0 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap index 05079e25c..4414974a0 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_dynamic.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_dynamic.snap index 2e0c24a1d..50a5965e3 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_dynamic.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_dynamic.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap index 05079e25c..4414974a0 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap index 20b59b7d9..454db2287 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap index b470f5ac2..70d7b0e5c 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_directory.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_directory.snap index ade8411b7..614e25dab 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_directory.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_directory.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_editable.snap b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_editable.snap index 75794fe76..a54bf70f8 100644 --- a/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_editable.snap +++ b/crates/uv-resolver/src/lock/snapshots/uv_resolver__lock__tests__source_editable.snap @@ -36,8 +36,12 @@ Ok( resolution_mode: Highest, prerelease_mode: IfNecessaryOrExplicit, fork_strategy: RequiresPython, - exclude_newer: None, - exclude_newer_package: None, + exclude_newer: ExcludeNewerWire { + exclude_newer: None, + exclude_newer_package: ExcludeNewerPackage( + {}, + ), + }, }, packages: [ Package { diff --git a/crates/uv/src/commands/pip/latest.rs b/crates/uv/src/commands/pip/latest.rs index c72903ad3..678095e37 100644 --- a/crates/uv/src/commands/pip/latest.rs +++ b/crates/uv/src/commands/pip/latest.rs @@ -18,7 +18,7 @@ pub(crate) struct LatestClient<'env> { pub(crate) client: &'env RegistryClient, pub(crate) capabilities: &'env IndexCapabilities, pub(crate) prerelease: PrereleaseMode, - pub(crate) exclude_newer: ExcludeNewer, + pub(crate) exclude_newer: &'env ExcludeNewer, pub(crate) tags: Option<&'env Tags>, pub(crate) requires_python: &'env RequiresPython, } diff --git a/crates/uv/src/commands/pip/list.rs b/crates/uv/src/commands/pip/list.rs index 4940e7acf..908cacbf0 100644 --- a/crates/uv/src/commands/pip/list.rs +++ b/crates/uv/src/commands/pip/list.rs @@ -111,7 +111,7 @@ pub(crate) async fn pip_list( client: &client, capabilities: &capabilities, prerelease, - exclude_newer, + exclude_newer: &exclude_newer, tags: Some(tags), requires_python: &requires_python, }; diff --git a/crates/uv/src/commands/pip/tree.rs b/crates/uv/src/commands/pip/tree.rs index 2adcb4381..a0b172fba 100644 --- a/crates/uv/src/commands/pip/tree.rs +++ b/crates/uv/src/commands/pip/tree.rs @@ -113,7 +113,7 @@ pub(crate) async fn pip_tree( client: &client, capabilities: &capabilities, prerelease, - exclude_newer, + exclude_newer: &exclude_newer, tags: Some(tags), requires_python: &requires_python, }; diff --git a/crates/uv/src/commands/project/tree.rs b/crates/uv/src/commands/project/tree.rs index 49d2a25d1..e2d6bf6f2 100644 --- a/crates/uv/src/commands/project/tree.rs +++ b/crates/uv/src/commands/project/tree.rs @@ -229,7 +229,7 @@ pub(crate) async fn tree( client: &client, capabilities: &capabilities, prerelease: lock.prerelease_mode(), - exclude_newer: lock.exclude_newer(), + exclude_newer: &lock.exclude_newer(), requires_python: lock.requires_python(), tags: None, };