mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00
refactor(resolver): Track minimal-versions in VersionPreferences
This had repurcussions on direct-minimal-versions as it before relied on the ordering parameter to `sort_sumarries`.
This commit is contained in:
parent
3cdddbf033
commit
bf2987b09b
@ -12,7 +12,7 @@ use std::task::Poll;
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use cargo::core::dependency::DepKind;
|
use cargo::core::dependency::DepKind;
|
||||||
use cargo::core::resolver::{self, ResolveOpts, VersionPreferences};
|
use cargo::core::resolver::{self, ResolveOpts, VersionOrdering, VersionPreferences};
|
||||||
use cargo::core::Resolve;
|
use cargo::core::Resolve;
|
||||||
use cargo::core::{Dependency, PackageId, Registry, Summary};
|
use cargo::core::{Dependency, PackageId, Registry, Summary};
|
||||||
use cargo::core::{GitReference, SourceId};
|
use cargo::core::{GitReference, SourceId};
|
||||||
@ -191,11 +191,15 @@ pub fn resolve_with_config_raw(
|
|||||||
let opts = ResolveOpts::everything();
|
let opts = ResolveOpts::everything();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let max_rust_version = None;
|
let max_rust_version = None;
|
||||||
|
let mut version_prefs = VersionPreferences::default();
|
||||||
|
if config.cli_unstable().minimal_versions {
|
||||||
|
version_prefs.version_ordering(VersionOrdering::MinimumVersionsFirst)
|
||||||
|
}
|
||||||
let resolve = resolver::resolve(
|
let resolve = resolver::resolve(
|
||||||
&[(summary, opts)],
|
&[(summary, opts)],
|
||||||
&[],
|
&[],
|
||||||
&mut registry,
|
&mut registry,
|
||||||
&VersionPreferences::default(),
|
&version_prefs,
|
||||||
Some(config),
|
Some(config),
|
||||||
true,
|
true,
|
||||||
max_rust_version,
|
max_rust_version,
|
||||||
|
@ -32,16 +32,12 @@ pub struct RegistryQueryer<'a> {
|
|||||||
pub registry: &'a mut (dyn Registry + 'a),
|
pub registry: &'a mut (dyn Registry + 'a),
|
||||||
replacements: &'a [(PackageIdSpec, Dependency)],
|
replacements: &'a [(PackageIdSpec, Dependency)],
|
||||||
version_prefs: &'a VersionPreferences,
|
version_prefs: &'a VersionPreferences,
|
||||||
/// If set the list of dependency candidates will be sorted by minimal
|
|
||||||
/// versions first. That allows `cargo update -Z minimal-versions` which will
|
|
||||||
/// specify minimum dependency versions to be used.
|
|
||||||
minimal_versions: bool,
|
|
||||||
max_rust_version: Option<RustVersion>,
|
max_rust_version: Option<RustVersion>,
|
||||||
/// a cache of `Candidate`s that fulfil a `Dependency` (and whether `first_minimal_version`)
|
/// a cache of `Candidate`s that fulfil a `Dependency` (and whether `first_version`)
|
||||||
registry_cache: HashMap<(Dependency, bool), Poll<Rc<Vec<Summary>>>>,
|
registry_cache: HashMap<(Dependency, Option<VersionOrdering>), Poll<Rc<Vec<Summary>>>>,
|
||||||
/// a cache of `Dependency`s that are required for a `Summary`
|
/// a cache of `Dependency`s that are required for a `Summary`
|
||||||
///
|
///
|
||||||
/// HACK: `first_minimal_version` is not kept in the cache key is it is 1:1 with
|
/// HACK: `first_version` is not kept in the cache key is it is 1:1 with
|
||||||
/// `parent.is_none()` (the first element of the cache key) as it doesn't change through
|
/// `parent.is_none()` (the first element of the cache key) as it doesn't change through
|
||||||
/// execution.
|
/// execution.
|
||||||
summary_cache: HashMap<
|
summary_cache: HashMap<
|
||||||
@ -57,14 +53,12 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
registry: &'a mut dyn Registry,
|
registry: &'a mut dyn Registry,
|
||||||
replacements: &'a [(PackageIdSpec, Dependency)],
|
replacements: &'a [(PackageIdSpec, Dependency)],
|
||||||
version_prefs: &'a VersionPreferences,
|
version_prefs: &'a VersionPreferences,
|
||||||
minimal_versions: bool,
|
|
||||||
max_rust_version: Option<&RustVersion>,
|
max_rust_version: Option<&RustVersion>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
RegistryQueryer {
|
RegistryQueryer {
|
||||||
registry,
|
registry,
|
||||||
replacements,
|
replacements,
|
||||||
version_prefs,
|
version_prefs,
|
||||||
minimal_versions,
|
|
||||||
max_rust_version: max_rust_version.cloned(),
|
max_rust_version: max_rust_version.cloned(),
|
||||||
registry_cache: HashMap::new(),
|
registry_cache: HashMap::new(),
|
||||||
summary_cache: HashMap::new(),
|
summary_cache: HashMap::new(),
|
||||||
@ -106,9 +100,9 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
pub fn query(
|
pub fn query(
|
||||||
&mut self,
|
&mut self,
|
||||||
dep: &Dependency,
|
dep: &Dependency,
|
||||||
first_minimal_version: bool,
|
first_version: Option<VersionOrdering>,
|
||||||
) -> Poll<CargoResult<Rc<Vec<Summary>>>> {
|
) -> Poll<CargoResult<Rc<Vec<Summary>>>> {
|
||||||
let registry_cache_key = (dep.clone(), first_minimal_version);
|
let registry_cache_key = (dep.clone(), first_version);
|
||||||
if let Some(out) = self.registry_cache.get(®istry_cache_key).cloned() {
|
if let Some(out) = self.registry_cache.get(®istry_cache_key).cloned() {
|
||||||
return out.map(Result::Ok);
|
return out.map(Result::Ok);
|
||||||
}
|
}
|
||||||
@ -122,7 +116,7 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
})?;
|
})?;
|
||||||
if ready.is_pending() {
|
if ready.is_pending() {
|
||||||
self.registry_cache
|
self.registry_cache
|
||||||
.insert((dep.clone(), first_minimal_version), Poll::Pending);
|
.insert((dep.clone(), first_version), Poll::Pending);
|
||||||
return Poll::Pending;
|
return Poll::Pending;
|
||||||
}
|
}
|
||||||
for summary in ret.iter() {
|
for summary in ret.iter() {
|
||||||
@ -144,7 +138,7 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
Poll::Ready(s) => s.into_iter(),
|
Poll::Ready(s) => s.into_iter(),
|
||||||
Poll::Pending => {
|
Poll::Pending => {
|
||||||
self.registry_cache
|
self.registry_cache
|
||||||
.insert((dep.clone(), first_minimal_version), Poll::Pending);
|
.insert((dep.clone(), first_version), Poll::Pending);
|
||||||
return Poll::Pending;
|
return Poll::Pending;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -215,16 +209,8 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we attempt versions for a package we'll want to do so in a sorted fashion to pick
|
let first_version = first_version;
|
||||||
// the "best candidates" first. VersionPreferences implements this notion.
|
self.version_prefs.sort_summaries(&mut ret, first_version);
|
||||||
let ordering = if first_minimal_version || self.minimal_versions {
|
|
||||||
VersionOrdering::MinimumVersionsFirst
|
|
||||||
} else {
|
|
||||||
VersionOrdering::MaximumVersionsFirst
|
|
||||||
};
|
|
||||||
let first_version = first_minimal_version;
|
|
||||||
self.version_prefs
|
|
||||||
.sort_summaries(&mut ret, ordering, first_version);
|
|
||||||
|
|
||||||
let out = Poll::Ready(Rc::new(ret));
|
let out = Poll::Ready(Rc::new(ret));
|
||||||
|
|
||||||
@ -243,7 +229,7 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
parent: Option<PackageId>,
|
parent: Option<PackageId>,
|
||||||
candidate: &Summary,
|
candidate: &Summary,
|
||||||
opts: &ResolveOpts,
|
opts: &ResolveOpts,
|
||||||
first_minimal_version: bool,
|
first_version: Option<VersionOrdering>,
|
||||||
) -> ActivateResult<Rc<(HashSet<InternedString>, Rc<Vec<DepInfo>>)>> {
|
) -> ActivateResult<Rc<(HashSet<InternedString>, Rc<Vec<DepInfo>>)>> {
|
||||||
// if we have calculated a result before, then we can just return it,
|
// if we have calculated a result before, then we can just return it,
|
||||||
// as it is a "pure" query of its arguments.
|
// as it is a "pure" query of its arguments.
|
||||||
@ -263,24 +249,22 @@ impl<'a> RegistryQueryer<'a> {
|
|||||||
let mut all_ready = true;
|
let mut all_ready = true;
|
||||||
let mut deps = deps
|
let mut deps = deps
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(
|
.filter_map(|(dep, features)| match self.query(&dep, first_version) {
|
||||||
|(dep, features)| match self.query(&dep, first_minimal_version) {
|
Poll::Ready(Ok(candidates)) => Some(Ok((dep, candidates, features))),
|
||||||
Poll::Ready(Ok(candidates)) => Some(Ok((dep, candidates, features))),
|
Poll::Pending => {
|
||||||
Poll::Pending => {
|
all_ready = false;
|
||||||
all_ready = false;
|
// we can ignore Pending deps, resolve will be repeatedly called
|
||||||
// we can ignore Pending deps, resolve will be repeatedly called
|
// until there are none to ignore
|
||||||
// until there are none to ignore
|
None
|
||||||
None
|
}
|
||||||
}
|
Poll::Ready(Err(e)) => Some(Err(e).with_context(|| {
|
||||||
Poll::Ready(Err(e)) => Some(Err(e).with_context(|| {
|
format!(
|
||||||
format!(
|
"failed to get `{}` as a dependency of {}",
|
||||||
"failed to get `{}` as a dependency of {}",
|
dep.package_name(),
|
||||||
dep.package_name(),
|
describe_path_in_context(cx, &candidate.package_id()),
|
||||||
describe_path_in_context(cx, &candidate.package_id()),
|
)
|
||||||
)
|
})),
|
||||||
})),
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect::<CargoResult<Vec<DepInfo>>>()?;
|
.collect::<CargoResult<Vec<DepInfo>>>()?;
|
||||||
|
|
||||||
// Attempt to resolve dependencies with fewer candidates before trying
|
// Attempt to resolve dependencies with fewer candidates before trying
|
||||||
|
@ -142,13 +142,11 @@ pub fn resolve(
|
|||||||
mut max_rust_version: Option<&RustVersion>,
|
mut max_rust_version: Option<&RustVersion>,
|
||||||
) -> CargoResult<Resolve> {
|
) -> CargoResult<Resolve> {
|
||||||
let _p = profile::start("resolving");
|
let _p = profile::start("resolving");
|
||||||
let minimal_versions = match config {
|
let first_version = match config {
|
||||||
Some(config) => config.cli_unstable().minimal_versions,
|
Some(config) if config.cli_unstable().direct_minimal_versions => {
|
||||||
None => false,
|
Some(VersionOrdering::MinimumVersionsFirst)
|
||||||
};
|
}
|
||||||
let direct_minimal_versions = match config {
|
_ => None,
|
||||||
Some(config) => config.cli_unstable().direct_minimal_versions,
|
|
||||||
None => false,
|
|
||||||
};
|
};
|
||||||
if !config
|
if !config
|
||||||
.map(|c| c.cli_unstable().msrv_policy)
|
.map(|c| c.cli_unstable().msrv_policy)
|
||||||
@ -156,22 +154,11 @@ pub fn resolve(
|
|||||||
{
|
{
|
||||||
max_rust_version = None;
|
max_rust_version = None;
|
||||||
}
|
}
|
||||||
let mut registry = RegistryQueryer::new(
|
let mut registry =
|
||||||
registry,
|
RegistryQueryer::new(registry, replacements, version_prefs, max_rust_version);
|
||||||
replacements,
|
|
||||||
version_prefs,
|
|
||||||
minimal_versions,
|
|
||||||
max_rust_version,
|
|
||||||
);
|
|
||||||
let cx = loop {
|
let cx = loop {
|
||||||
let cx = Context::new(check_public_visible_dependencies);
|
let cx = Context::new(check_public_visible_dependencies);
|
||||||
let cx = activate_deps_loop(
|
let cx = activate_deps_loop(cx, &mut registry, summaries, first_version, config)?;
|
||||||
cx,
|
|
||||||
&mut registry,
|
|
||||||
summaries,
|
|
||||||
direct_minimal_versions,
|
|
||||||
config,
|
|
||||||
)?;
|
|
||||||
if registry.reset_pending() {
|
if registry.reset_pending() {
|
||||||
break cx;
|
break cx;
|
||||||
} else {
|
} else {
|
||||||
@ -223,7 +210,7 @@ fn activate_deps_loop(
|
|||||||
mut cx: Context,
|
mut cx: Context,
|
||||||
registry: &mut RegistryQueryer<'_>,
|
registry: &mut RegistryQueryer<'_>,
|
||||||
summaries: &[(Summary, ResolveOpts)],
|
summaries: &[(Summary, ResolveOpts)],
|
||||||
direct_minimal_versions: bool,
|
first_version: Option<VersionOrdering>,
|
||||||
config: Option<&Config>,
|
config: Option<&Config>,
|
||||||
) -> CargoResult<Context> {
|
) -> CargoResult<Context> {
|
||||||
let mut backtrack_stack = Vec::new();
|
let mut backtrack_stack = Vec::new();
|
||||||
@ -241,7 +228,7 @@ fn activate_deps_loop(
|
|||||||
registry,
|
registry,
|
||||||
None,
|
None,
|
||||||
summary.clone(),
|
summary.clone(),
|
||||||
direct_minimal_versions,
|
first_version,
|
||||||
opts,
|
opts,
|
||||||
);
|
);
|
||||||
match res {
|
match res {
|
||||||
@ -441,13 +428,13 @@ fn activate_deps_loop(
|
|||||||
dep.package_name(),
|
dep.package_name(),
|
||||||
candidate.version()
|
candidate.version()
|
||||||
);
|
);
|
||||||
let direct_minimal_version = false; // this is an indirect dependency
|
let first_version = None; // this is an indirect dependency
|
||||||
let res = activate(
|
let res = activate(
|
||||||
&mut cx,
|
&mut cx,
|
||||||
registry,
|
registry,
|
||||||
Some((&parent, &dep)),
|
Some((&parent, &dep)),
|
||||||
candidate,
|
candidate,
|
||||||
direct_minimal_version,
|
first_version,
|
||||||
&opts,
|
&opts,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -659,7 +646,7 @@ fn activate(
|
|||||||
registry: &mut RegistryQueryer<'_>,
|
registry: &mut RegistryQueryer<'_>,
|
||||||
parent: Option<(&Summary, &Dependency)>,
|
parent: Option<(&Summary, &Dependency)>,
|
||||||
candidate: Summary,
|
candidate: Summary,
|
||||||
first_minimal_version: bool,
|
first_version: Option<VersionOrdering>,
|
||||||
opts: &ResolveOpts,
|
opts: &ResolveOpts,
|
||||||
) -> ActivateResult<Option<(DepsFrame, Duration)>> {
|
) -> ActivateResult<Option<(DepsFrame, Duration)>> {
|
||||||
let candidate_pid = candidate.package_id();
|
let candidate_pid = candidate.package_id();
|
||||||
@ -716,7 +703,7 @@ fn activate(
|
|||||||
parent.map(|p| p.0.package_id()),
|
parent.map(|p| p.0.package_id()),
|
||||||
&candidate,
|
&candidate,
|
||||||
opts,
|
opts,
|
||||||
first_minimal_version,
|
first_version,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Record what list of features is active for this package.
|
// Record what list of features is active for this package.
|
||||||
@ -905,14 +892,14 @@ fn generalize_conflicting(
|
|||||||
})
|
})
|
||||||
{
|
{
|
||||||
for critical_parents_dep in critical_parents_deps.iter() {
|
for critical_parents_dep in critical_parents_deps.iter() {
|
||||||
// We only want `first_minimal_version=true` for direct dependencies of workspace
|
// We only want `first_version.is_some()` for direct dependencies of workspace
|
||||||
// members which isn't the case here as this has a `parent`
|
// members which isn't the case here as this has a `parent`
|
||||||
let first_minimal_version = false;
|
let first_version = None;
|
||||||
// A dep is equivalent to one of the things it can resolve to.
|
// A dep is equivalent to one of the things it can resolve to.
|
||||||
// Thus, if all the things it can resolve to have already ben determined
|
// Thus, if all the things it can resolve to have already ben determined
|
||||||
// to be conflicting, then we can just say that we conflict with the parent.
|
// to be conflicting, then we can just say that we conflict with the parent.
|
||||||
if let Some(others) = registry
|
if let Some(others) = registry
|
||||||
.query(critical_parents_dep, first_minimal_version)
|
.query(critical_parents_dep, first_version)
|
||||||
.expect("an already used dep now error!?")
|
.expect("an already used dep now error!?")
|
||||||
.expect("an already used dep now pending!?")
|
.expect("an already used dep now pending!?")
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -18,9 +18,12 @@ use crate::util::interning::InternedString;
|
|||||||
pub struct VersionPreferences {
|
pub struct VersionPreferences {
|
||||||
try_to_use: HashSet<PackageId>,
|
try_to_use: HashSet<PackageId>,
|
||||||
prefer_patch_deps: HashMap<InternedString, HashSet<Dependency>>,
|
prefer_patch_deps: HashMap<InternedString, HashSet<Dependency>>,
|
||||||
|
version_ordering: VersionOrdering,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, PartialEq, Eq, Hash, Debug)]
|
||||||
pub enum VersionOrdering {
|
pub enum VersionOrdering {
|
||||||
|
#[default]
|
||||||
MaximumVersionsFirst,
|
MaximumVersionsFirst,
|
||||||
MinimumVersionsFirst,
|
MinimumVersionsFirst,
|
||||||
}
|
}
|
||||||
@ -39,14 +42,17 @@ impl VersionPreferences {
|
|||||||
.insert(dep);
|
.insert(dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn version_ordering(&mut self, ordering: VersionOrdering) {
|
||||||
|
self.version_ordering = ordering;
|
||||||
|
}
|
||||||
|
|
||||||
/// Sort the given vector of summaries in-place, with all summaries presumed to be for
|
/// Sort the given vector of summaries in-place, with all summaries presumed to be for
|
||||||
/// the same package. Preferred versions appear first in the result, sorted by
|
/// the same package. Preferred versions appear first in the result, sorted by
|
||||||
/// `version_ordering`, followed by non-preferred versions sorted the same way.
|
/// `version_ordering`, followed by non-preferred versions sorted the same way.
|
||||||
pub fn sort_summaries(
|
pub fn sort_summaries(
|
||||||
&self,
|
&self,
|
||||||
summaries: &mut Vec<Summary>,
|
summaries: &mut Vec<Summary>,
|
||||||
version_ordering: VersionOrdering,
|
first_version: Option<VersionOrdering>,
|
||||||
first_version: bool,
|
|
||||||
) {
|
) {
|
||||||
let should_prefer = |pkg_id: &PackageId| {
|
let should_prefer = |pkg_id: &PackageId| {
|
||||||
self.try_to_use.contains(pkg_id)
|
self.try_to_use.contains(pkg_id)
|
||||||
@ -63,7 +69,7 @@ impl VersionPreferences {
|
|||||||
match previous_cmp {
|
match previous_cmp {
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
let cmp = a.version().cmp(b.version());
|
let cmp = a.version().cmp(b.version());
|
||||||
match version_ordering {
|
match first_version.unwrap_or(self.version_ordering) {
|
||||||
VersionOrdering::MaximumVersionsFirst => cmp.reverse(),
|
VersionOrdering::MaximumVersionsFirst => cmp.reverse(),
|
||||||
VersionOrdering::MinimumVersionsFirst => cmp,
|
VersionOrdering::MinimumVersionsFirst => cmp,
|
||||||
}
|
}
|
||||||
@ -71,7 +77,7 @@ impl VersionPreferences {
|
|||||||
_ => previous_cmp,
|
_ => previous_cmp,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if first_version {
|
if first_version.is_some() {
|
||||||
let _ = summaries.split_off(1);
|
let _ = summaries.split_off(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,13 +135,15 @@ mod test {
|
|||||||
summ("foo", "1.0.9"),
|
summ("foo", "1.0.9"),
|
||||||
];
|
];
|
||||||
|
|
||||||
vp.sort_summaries(&mut summaries, VersionOrdering::MaximumVersionsFirst, false);
|
vp.version_ordering(VersionOrdering::MaximumVersionsFirst);
|
||||||
|
vp.sort_summaries(&mut summaries, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
describe(&summaries),
|
describe(&summaries),
|
||||||
"foo/1.2.3, foo/1.2.4, foo/1.1.0, foo/1.0.9".to_string()
|
"foo/1.2.3, foo/1.2.4, foo/1.1.0, foo/1.0.9".to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
vp.sort_summaries(&mut summaries, VersionOrdering::MinimumVersionsFirst, false);
|
vp.version_ordering(VersionOrdering::MinimumVersionsFirst);
|
||||||
|
vp.sort_summaries(&mut summaries, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
describe(&summaries),
|
describe(&summaries),
|
||||||
"foo/1.2.3, foo/1.0.9, foo/1.1.0, foo/1.2.4".to_string()
|
"foo/1.2.3, foo/1.0.9, foo/1.1.0, foo/1.2.4".to_string()
|
||||||
@ -154,13 +162,15 @@ mod test {
|
|||||||
summ("foo", "1.0.9"),
|
summ("foo", "1.0.9"),
|
||||||
];
|
];
|
||||||
|
|
||||||
vp.sort_summaries(&mut summaries, VersionOrdering::MaximumVersionsFirst, false);
|
vp.version_ordering(VersionOrdering::MaximumVersionsFirst);
|
||||||
|
vp.sort_summaries(&mut summaries, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
describe(&summaries),
|
describe(&summaries),
|
||||||
"foo/1.2.3, foo/1.2.4, foo/1.1.0, foo/1.0.9".to_string()
|
"foo/1.2.3, foo/1.2.4, foo/1.1.0, foo/1.0.9".to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
vp.sort_summaries(&mut summaries, VersionOrdering::MinimumVersionsFirst, false);
|
vp.version_ordering(VersionOrdering::MinimumVersionsFirst);
|
||||||
|
vp.sort_summaries(&mut summaries, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
describe(&summaries),
|
describe(&summaries),
|
||||||
"foo/1.2.3, foo/1.0.9, foo/1.1.0, foo/1.2.4".to_string()
|
"foo/1.2.3, foo/1.0.9, foo/1.1.0, foo/1.2.4".to_string()
|
||||||
@ -180,13 +190,15 @@ mod test {
|
|||||||
summ("foo", "1.0.9"),
|
summ("foo", "1.0.9"),
|
||||||
];
|
];
|
||||||
|
|
||||||
vp.sort_summaries(&mut summaries, VersionOrdering::MaximumVersionsFirst, false);
|
vp.version_ordering(VersionOrdering::MaximumVersionsFirst);
|
||||||
|
vp.sort_summaries(&mut summaries, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
describe(&summaries),
|
describe(&summaries),
|
||||||
"foo/1.2.3, foo/1.1.0, foo/1.2.4, foo/1.0.9".to_string()
|
"foo/1.2.3, foo/1.1.0, foo/1.2.4, foo/1.0.9".to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
vp.sort_summaries(&mut summaries, VersionOrdering::MinimumVersionsFirst, false);
|
vp.version_ordering(VersionOrdering::MinimumVersionsFirst);
|
||||||
|
vp.sort_summaries(&mut summaries, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
describe(&summaries),
|
describe(&summaries),
|
||||||
"foo/1.1.0, foo/1.2.3, foo/1.0.9, foo/1.2.4".to_string()
|
"foo/1.1.0, foo/1.2.3, foo/1.0.9, foo/1.2.4".to_string()
|
||||||
|
@ -61,7 +61,7 @@ use crate::core::resolver::features::{
|
|||||||
CliFeatures, FeatureOpts, FeatureResolver, ForceAllTargets, RequestedFeatures, ResolvedFeatures,
|
CliFeatures, FeatureOpts, FeatureResolver, ForceAllTargets, RequestedFeatures, ResolvedFeatures,
|
||||||
};
|
};
|
||||||
use crate::core::resolver::{
|
use crate::core::resolver::{
|
||||||
self, HasDevUnits, Resolve, ResolveOpts, ResolveVersion, VersionPreferences,
|
self, HasDevUnits, Resolve, ResolveOpts, ResolveVersion, VersionOrdering, VersionPreferences,
|
||||||
};
|
};
|
||||||
use crate::core::summary::Summary;
|
use crate::core::summary::Summary;
|
||||||
use crate::core::Feature;
|
use crate::core::Feature;
|
||||||
@ -321,6 +321,9 @@ pub fn resolve_with_previous<'cfg>(
|
|||||||
// While registering patches, we will record preferences for particular versions
|
// While registering patches, we will record preferences for particular versions
|
||||||
// of various packages.
|
// of various packages.
|
||||||
let mut version_prefs = VersionPreferences::default();
|
let mut version_prefs = VersionPreferences::default();
|
||||||
|
if ws.config().cli_unstable().minimal_versions {
|
||||||
|
version_prefs.version_ordering(VersionOrdering::MinimumVersionsFirst)
|
||||||
|
}
|
||||||
|
|
||||||
// This is a set of PackageIds of `[patch]` entries, and some related locked PackageIds, for
|
// This is a set of PackageIds of `[patch]` entries, and some related locked PackageIds, for
|
||||||
// which locking should be avoided (but which will be preferred when searching dependencies,
|
// which locking should be avoided (but which will be preferred when searching dependencies,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user