Skip to content

Commit 021b424

Browse files
J Robert Rayjrray
J Robert Ray
authored andcommitted
Fix requests for :all not filtering invalid versions
Messed up the logic when checking :all cases. Add test for this case. Signed-off-by: J Robert Ray <[email protected]>
1 parent 6b4d8a7 commit 021b424

File tree

2 files changed

+77
-40
lines changed

2 files changed

+77
-40
lines changed

crates/spk-solve/src/cdcl_solver/spk_provider.rs

+45-38
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ impl DependencyProvider for SpkProvider {
679679
let compatible = pkg_request
680680
.is_version_applicable(located_build_ident_with_component.ident.version());
681681
if compatible.is_ok() {
682+
tracing::trace!(pkg_request = %pkg_request.pkg, version = %located_build_ident_with_component.ident.version(), "version applicable");
682683
let is_source =
683684
located_build_ident_with_component.ident.build().is_source();
684685

@@ -710,52 +711,57 @@ impl DependencyProvider for SpkProvider {
710711
// Only select All component for requests of All
711712
// component.
712713
if located_build_ident_with_component.component.is_all() {
713-
if pkg_request.pkg.components.contains(&Component::All) ^ inverse {
714-
selected.push(*candidate);
715-
}
716-
continue;
717-
} else
718-
// Only the All component can satisfy requests for All.
719-
if pkg_request.pkg.components.contains(&Component::All) {
720-
if inverse {
721-
selected.push(*candidate);
722-
}
723-
continue;
724-
}
725-
726-
// Only the x component can satisfy requests for x.
727-
let mut at_least_one_request_matched_this_solvable = None;
728-
for component in pkg_request.pkg.components.iter() {
729-
if component.is_all() {
730-
continue;
731-
}
732-
if component == &located_build_ident_with_component.component {
733-
at_least_one_request_matched_this_solvable = Some(true);
734-
break;
735-
} else {
736-
at_least_one_request_matched_this_solvable = Some(false);
737-
}
738-
}
739-
740-
match at_least_one_request_matched_this_solvable {
741-
Some(true) => {
714+
// This can disqualify but not qualify; version
715+
// compatibility check is still required.
716+
if !pkg_request.pkg.components.contains(&Component::All) {
742717
if inverse {
743-
continue;
718+
selected.push(*candidate);
744719
}
720+
continue;
745721
}
746-
Some(false) => {
747-
// The request is for specific components but
748-
// this solvable doesn't match any of them.
722+
} else {
723+
// Only the All component can satisfy requests for All.
724+
if pkg_request.pkg.components.contains(&Component::All) {
749725
if inverse {
750726
selected.push(*candidate);
727+
}
728+
continue;
729+
}
730+
731+
// Only the x component can satisfy requests for x.
732+
let mut at_least_one_request_matched_this_solvable = None;
733+
for component in pkg_request.pkg.components.iter() {
734+
if component.is_all() {
751735
continue;
752736
}
737+
if component == &located_build_ident_with_component.component {
738+
at_least_one_request_matched_this_solvable = Some(true);
739+
break;
740+
} else {
741+
at_least_one_request_matched_this_solvable = Some(false);
742+
}
753743
}
754-
None => {
755-
// TODO: if at_least_one_request_matched_this_solvable
756-
// is None it means the request didn't specify a
757-
// component. Decide which specific component this
758-
// should match.
744+
745+
match at_least_one_request_matched_this_solvable {
746+
Some(true) => {
747+
if inverse {
748+
continue;
749+
}
750+
}
751+
Some(false) => {
752+
// The request is for specific components but
753+
// this solvable doesn't match any of them.
754+
if inverse {
755+
selected.push(*candidate);
756+
continue;
757+
}
758+
}
759+
None => {
760+
// TODO: if at_least_one_request_matched_this_solvable
761+
// is None it means the request didn't specify a
762+
// component. Decide which specific component this
763+
// should match.
764+
}
759765
}
760766
}
761767

@@ -772,6 +778,7 @@ impl DependencyProvider for SpkProvider {
772778
.await
773779
{
774780
if pkg_request.is_satisfied_by(&package).is_ok() ^ inverse {
781+
tracing::trace!(pkg_request = %pkg_request.pkg, package = %package.ident(), %inverse, "satisfied by");
775782
selected.push(*candidate);
776783
}
777784
} else if inverse {

crates/spk-solve/src/solver_test.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,15 @@ fn solver() -> Solver {
4545
/// of resolved components, or the specific build of the package.
4646
macro_rules! assert_resolved {
4747
($solution:ident, $pkg:literal, $version:literal) => {
48-
assert_resolved!($solution, $pkg, $version, "wrong package version was resolved")
48+
assert_resolved!($solution, $pkg, version = $version, "wrong package version was resolved")
49+
};
50+
($solution:ident, $pkg:literal, version = $version:expr) => {
51+
assert_resolved!($solution, $pkg, version = $version, "wrong package version was resolved")
4952
};
5053
($solution:ident, $pkg:literal, $version:literal, $message:literal) => {
5154
assert_resolved!($solution, $pkg, version = $version, $message)
5255
};
53-
($solution:ident, $pkg:literal, version = $version:literal, $message:literal) => {{
56+
($solution:ident, $pkg:literal, version = $version:expr, $message:literal) => {{
5457
let pkg = $solution
5558
.get($pkg)
5659
.expect("expected package to be in solution");
@@ -2912,3 +2915,30 @@ async fn test_version_number_masking(
29122915
);
29132916
assert_ne!(resolved.spec.ident().build(), &Build::Source);
29142917
}
2918+
2919+
#[rstest]
2920+
#[case::og(og_solver())]
2921+
#[case::cdcl(cdcl_solver())]
2922+
#[tokio::test]
2923+
async fn request_for_all_component_picks_correct_version(
2924+
#[case] mut solver: SolverImpl,
2925+
#[values("1.0.0", "2.0.0", "3.0.0")] version: &str,
2926+
) {
2927+
// A request for :all component still controls for version compatibility
2928+
2929+
let repo = make_repo!(
2930+
[
2931+
{ "pkg": "mypkg/1.0.0" },
2932+
{ "pkg": "mypkg/2.0.0" },
2933+
{ "pkg": "mypkg/3.0.0" },
2934+
]
2935+
);
2936+
let repo = Arc::new(repo);
2937+
2938+
solver.add_repository(repo);
2939+
let request_str = format!("mypkg:all/{version}");
2940+
solver.add_request(request!(request_str));
2941+
2942+
let solution = run_and_print_resolve_for_tests(&mut solver).await.unwrap();
2943+
assert_resolved!(solution, "mypkg", version = version);
2944+
}

0 commit comments

Comments
 (0)