aboutsummaryrefslogtreecommitdiffstats
path: root/URPM/Resolve.pm
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@mandriva.com>2009-03-25 13:22:27 +0000
committerChristophe Fergeau <cfergeau@mandriva.com>2009-03-25 13:22:27 +0000
commite1f8bfbd4b8498ea168323f8b13bdf86f221885e (patch)
tree5a5c6f7623ce74d42b7dd2fce3853c0d3df0dd75 /URPM/Resolve.pm
parente7048f53f0e2783783eab9b739ccf42f81ccd945 (diff)
downloadperl-URPM-e1f8bfbd4b8498ea168323f8b13bdf86f221885e.tar
perl-URPM-e1f8bfbd4b8498ea168323f8b13bdf86f221885e.tar.gz
perl-URPM-e1f8bfbd4b8498ea168323f8b13bdf86f221885e.tar.bz2
perl-URPM-e1f8bfbd4b8498ea168323f8b13bdf86f221885e.tar.xz
perl-URPM-e1f8bfbd4b8498ea168323f8b13bdf86f221885e.zip
Postpone user choices as much as possible
Fixes bug #48100, patch from Anssi Hannula Package A requires D and E. Package B provides D and E. Package C provides E. If the require on E happens to be resolved first, then perl-URPM will prompt the user, even though installing B is enough.
Diffstat (limited to 'URPM/Resolve.pm')
-rw-r--r--URPM/Resolve.pm64
1 files changed, 28 insertions, 36 deletions
diff --git a/URPM/Resolve.pm b/URPM/Resolve.pm
index 8faa4eb..5cd7480 100644
--- a/URPM/Resolve.pm
+++ b/URPM/Resolve.pm
@@ -381,54 +381,44 @@ sub _score_for_locales {
}
}
-#- side-effects: $properties
+#- side-effects: $properties, $choices
#- + those of backtrack_selected ($state->{backtrack}, $state->{rejected}, $state->{selected}, $state->{whatrequires}, flag_requested, flag_required)
sub _choose_required {
- my ($urpm, $db, $state, $dep, $properties, %options) = @_;
+ my ($urpm, $db, $state, $dep, $properties, $choices, %options) = @_;
#- take the best choice possible.
my ($chosen, $prefered) = find_required_package($urpm, $db, $state, $dep->{required});
- if ((@$chosen > 1) && ($dep->{from})) {
- #- if another package requires one of the potential candidates,
- #- we select this candidate instead of keeping all the
- #- other packages.
- foreach my $pkg (@$chosen) {
- #- get list of packages that requires something provided by $pkg
- my @requiring_pkg = grep { exists $state->{whatrequires}->{$_} } $pkg->provides_nosense;
- foreach (@requiring_pkg) {
- my @requires_from_elsewhere = grep { $_->name ne $dep->{from}->name } whatrequires($urpm, $state, $_) or next;
-
- $urpm->{debug_URPM}("forcing use of " . $pkg->name . " for $dep->{required} because " . join(", ", map { $_->name } @requires_from_elsewhere) . " require(s) it") if $urpm->{debug_URPM};
- @$chosen = $pkg;
- undef $prefered;
- }
- }
- }
-
#- If no choice is found, this means that nothing can be possibly selected
#- according to $dep, so we need to retry the selection, allowing all
#- packages that conflict or anything similar to see which strategy can be
#- tried. Backtracking is used to avoid trying multiple times the same
- #- packages. If multiple packages are possible, simply ask the user which
+ #- packages. If multiple packages are possible and properties is not
+ #- empty, postpone the choice for a later time as one of the packages
+ #- may be selected for another reason. Otherwise simply ask the user which
#- one to choose; else take the first one available.
if (!@$chosen) {
$urpm->{debug_URPM}("no packages match " . _dep_to_name($urpm, $dep) . " (it is either in skip.list or already rejected)") if $urpm->{debug_URPM};
unshift @$properties, backtrack_selected($urpm, $db, $state, $dep, %options);
return; #- backtrack code choose to continue with same package or completely new strategy.
- } elsif ($options{callback_choices} && @$chosen > 1) {
- my @l = grep { ref $_ } $options{callback_choices}->($urpm, $db, $state, $chosen, _dep_to_name($urpm, $dep), $prefered);
- $urpm->{debug_URPM}("replacing " . _dep_to_name($urpm, $dep) . " with " .
- join(' ', map { $_->name } @l)) if $urpm->{debug_URPM};
- unshift @$properties, map {
- +{
- required => $_->id,
- _choices => $dep->{required},
- exists $dep->{from} ? (from => $dep->{from}) : @{[]},
- exists $dep->{requested} ? (requested => $dep->{requested}) : @{[]},
- };
- } @l;
- return; #- always redo according to choices.
+ } elsif (@$chosen > 1) {
+ if (@$properties) {
+ unshift @$choices, $dep;
+ return;
+ } elsif ($options{callback_choices}) {
+ my @l = grep { ref $_ } $options{callback_choices}->($urpm, $db, $state, $chosen, _dep_to_name($urpm, $dep), $prefered);
+ $urpm->{debug_URPM}("replacing " . _dep_to_name($urpm, $dep) . " with " .
+ join(' ', map { $_->name } @l)) if $urpm->{debug_URPM};
+ unshift @$properties, map {
+ +{
+ required => $_->id,
+ _choices => $dep->{required},
+ exists $dep->{from} ? (from => $dep->{from}) : @{[]},
+ exists $dep->{requested} ? (requested => $dep->{requested}) : @{[]},
+ };
+ } @l;
+ return; #- always redo according to choices.
+ }
}
@@ -929,7 +919,7 @@ sub resolve_requested__no_suggests_ {
{ required => $_, requested => $requested->{$_} };
} keys %$requested;
- my (@diff_provides, @selected);
+ my (@diff_provides, @selected, @choices);
#- for each dep property evaluated, examine which package will be obsoleted on $db,
#- then examine provides that will be removed (which need to be satisfied by another
@@ -942,7 +932,7 @@ sub resolve_requested__no_suggests_ {
exists $state->{selected}{$dep->{from}->id} or next;
}
- my $pkg = _choose_required($urpm, $db, $state, $dep, \@properties, %options) or next;
+ my $pkg = _choose_required($urpm, $db, $state, $dep, \@properties, \@choices, %options) or next;
!$pkg || exists $state->{selected}{$pkg->id} and next;
@@ -1016,8 +1006,10 @@ sub resolve_requested__no_suggests_ {
}
if (my $diff = shift @diff_provides) {
_handle_diff_provides($urpm, $db, $state, \@properties, \@diff_provides, $diff->{name}, $diff->{pkg}, %options);
+ } elsif (my $dep = shift @choices) {
+ push @properties, $dep;
}
- } while @diff_provides || @properties;
+ } while @diff_provides || @properties || @choices;
#- return what has been selected by this call (not all selected hash which may be not empty
#- previously. avoid returning rejected packages which weren't selectable.