diff options
-rw-r--r-- | urpm.pm | 152 | ||||
-rwxr-xr-x | urpmi | 20 | ||||
-rw-r--r-- | urpmi.spec | 8 | ||||
-rwxr-xr-x | urpmq | 7 |
4 files changed, 103 insertions, 84 deletions
@@ -1227,7 +1227,7 @@ sub search_packages { #- it is a way of speedup, providing the name of a package directly help #- to find the package. #- this is necessary if providing a name list of package to upgrade. - if ($urpm->{params}{names}{$v} && defined $urpm->{params}{names}{$v}{id}) { + if (!$options{fuzzy} && $urpm->{params}{names}{$v} && defined $urpm->{params}{names}{$v}{id}) { $exact{$v} = $urpm->{params}{names}{$v}{id}; next; } @@ -1235,13 +1235,15 @@ sub search_packages { my $qv = quotemeta $v; if ($options{use_provides}) { - #- try to search through provides. - if (my @l = grep { defined $_ } map { $_ && $_->{id} } map { $urpm->{params}{info}{$_} } - keys %{$urpm->{params}{provides}{$v} || {}}) { - #- we assume that if the there is at least one package providing the resource exactly, - #- this should be the best ones that is described. - $exact{$v} = join '|', @l; - next; + unless ($options{fuzzy}) { + #- try to search through provides. + if (my @l = grep { defined $_ } map { $_ && $_->{id} } map { $urpm->{params}{info}{$_} } + keys %{$urpm->{params}{provides}{$v} || {}}) { + #- we assume that if the there is at least one package providing the resource exactly, + #- this should be the best ones that is described. + $exact{$v} = join '|', @l; + next; + } } foreach (keys %{$urpm->{params}{provides}}) { @@ -1264,15 +1266,17 @@ sub search_packages { my $pack_a = "$pack_ra-$info->{release}"; my $pack = "$pack_a.$info->{arch}"; - if ($pack eq $v) { - $exact{$v} = $id; - next; - } elsif ($pack_a eq $v) { - push @{$exact_a{$v}}, $id; - next; - } elsif ($pack_ra eq $v) { - push @{$exact_ra{$v}}, $id; - next; + unless ($options{fuzzy}) { + if ($pack eq $v) { + $exact{$v} = $id; + next; + } elsif ($pack_a eq $v) { + push @{$exact_a{$v}}, $id; + next; + } elsif ($pack_ra eq $v) { + push @{$exact_ra{$v}}, $id; + next; + } } $pack =~ /$qv/ and push @{$found{$v}}, $id; @@ -1476,69 +1480,47 @@ sub filter_packages_to_upgrade { #- defining %provides here could slow the algorithm but it solves multi-pass #- where a provides is A and after A == version-release, when A is already #- installed. - my (%diffprovides, %provides); + my (%diff_provides, %provides); rpmtools::db_traverse_tag($db, - 'name', [ $pkg->{name} ], + 'name', [ $pkg->{name}, @{$pkg->{obsoletes} || []} ], [ qw(name version release sense provides) ], sub { my ($p) = @_; foreach (@{$p->{provides}}) { s/\[\*\]//; s/\[([^\]]*)\]/ $1/; - /^(\S*\s*\S*\s*)(\d+:)?([^\s-]*)(-?\S*)/ or next; - foreach ($_, "$1$3", "$1$2$3", "$1$3$4") { - $diffprovides{$_} = "$p->{name}-$p->{version}-$p->{release}"; - } + $diff_provides{$_} = "$p->{name}-$p->{version}-$p->{release}"; } }); + foreach (@{$pkg->{provides} || []}) { s/\[\*\]//; s/\[([^\]]*)\]/ $1/; - /^(\S*\s*\S*\s*)(\d+:)?([^\s-]*)(-?\S*)/ or next; - foreach ($_, "$1$3", "$1$2$3", "$1$3$4") { - delete $diffprovides{$_}; - } - } - foreach ($pkg->{name}, "$pkg->{name} == $pkg->{version}", "$pkg->{name} == $pkg->{version}-$pkg->{release}") { - delete $diffprovides{$_}; + delete $diff_provides{$_}; } - delete $diffprovides{""}; - foreach (keys %diffprovides) { + foreach (keys %diff_provides) { #- analyse the difference in provide and select other package. if (my ($n, $o, $e, $v, $r) = /^(\S*)\s*(\S*)\s*(\d+:)?([^\s-]*)-?(\S*)/) { - rpmtools::db_traverse_tag($db, 'whatprovides', [ $n ], [ qw(name version release) ], sub{ - $_[0]{name} eq $pkg->{name} and return; - $o and $n eq $_[0]{name} || return; - $v and eval(rpmtools::version_compare($_[0]{version}, $v) . $o . 0) || return; - $r && rpmtools::version_compare($_[0]{version}, $v) == 0 and - eval(rpmtools::version_compare($_[0]{release}, $r) . $o . 0) || return; - $provides{$_} = "$_[0]{name}-$_[0]{version}-$_[0]{release}"; - }); - unless (exists $provides{$_}) { - foreach my $fullname (keys %{$urpm->{params}{provides}{$n} || {}}) { - exists $conflicts{$fullname} and next; - my $p = $urpm->{params}{info}{$fullname}; - $o and $n eq $p->{name} || next; - $v and eval(rpmtools::version_compare($p->{version}, $v) . $o . 0) || next; - $r && rpmtools::version_compare($p->{version}, $v) == 0 and - eval(rpmtools::version_compare($p->{release}, $r) . $o . 0) || next; - #- this is incomplete, exact provides is not kept. - $provides{$_} = undef; + my $check = sub { + my ($p) = @_; + my ($needed, $satisfied) = (0, 0); + foreach (@{$p->{requires}}) { + if (my ($pn, $po, $pv, $pr) = /^([^\s\[]*)(?:\[\*\])?(?:\s+|\[)?([^\s\]]*)\s*([^\s\-\]]*)-?([^\s\]]*)/) { + $pn eq $n && $pn eq $pkg->{name} or next; + ++$needed; + $pv and eval(rpmtools::version_compare($pkg->{version}, $pv) . $po . 0) || next; + $pr && rpmtools::version_compare($pkg->{version}, $pv) == 0 and + eval(rpmtools::version_compare($pkg->{release}, $pr) . $po . 0) || next; + #- an existing provides (propably the one examined) is satisfying the underlying. + ++$satisfied; + } } - } - unless (exists $provides{$_}) { - rpmtools::db_traverse_tag($db, - 'whatrequires', [ $1 ], - [ qw(name version release sense requires) ], sub{ - my ($p) = @_; - foreach (@{$p->{requires}}) { - s/\[\*\]//; - s/\[([^\]]*)\]/ $1/; - exists $diffprovides{$_} and $provides{$p->{name}} = undef; - } - }); - } + #- check if the package need to be updated because it + #- losts some of its requires regarding the current diff_provides. + $needed > $satisfied and $provides{$p->{name}} = undef; + }; + rpmtools::db_traverse_tag($db, 'whatrequires', [ $n ], [ qw(name version release sense requires) ], $check); } } @@ -1546,17 +1528,17 @@ sub filter_packages_to_upgrade { $provides{$pkg->{name}} = undef; #"$pkg->{name}-$pkg->{version}-$pkg->{release}"; foreach (@{$pkg->{requires} || []}) { if (my ($n, $o, $v, $r) = /^([^\s\[]*)(?:\[\*\])?(?:\s+|\[)?([^\s\]]*)\s*([^\s\-\]]*)-?([^\s\]]*)/) { - exists $provides{$_} || exists $selected{$_} and next; + exists $provides{$n} || exists $selected{$n} and next; #- if the provides is not found, it will be resolved at next step, else #- it will be resolved by searching the rpm database. - $provides{$_} ||= undef; + $provides{$n} ||= undef; my $check_pkg = sub { $options{keep_alldeps} and return; $o and $n eq $_[0]{name} || return; $v and eval(rpmtools::version_compare($_[0]{version}, $v) . $o . 0) || return; $r && rpmtools::version_compare($_[0]{version}, $v) == 0 and eval(rpmtools::version_compare($_[0]{release}, $r) . $o . 0) || return; - $provides{$_} = "$_[0]{name}-$_[0]{version}-$_[0]{release}"; + $provides{$n} = "$_[0]{name}-$_[0]{version}-$_[0]{release}"; }; rpmtools::db_traverse_tag($db, $n =~ m|^/| ? 'path' : 'whatprovides', [ $n ], [ qw (name version release) ], $check_pkg); @@ -1592,19 +1574,35 @@ sub filter_packages_to_upgrade { #- at this point, all unresolved provides (requires) should be fixed by #- provides files, try to minimize choice at this level. foreach (keys %provides) { - $provides{$_} || exists $selected{$_} and next; - $selected{$_} = undef; - my (%pre_choices, @pre_choices, @choices, @upgradable_choices, %choices_id); if (my ($n, $o, $v, $r) = /^([^\s\[]*)(?:\[\*\])?(?:\s+|\[)?([^\s\]]*)\s*([^\s\-\]]*)-?([^\s\]]*)/) { + $provides{$n} || exists $selected{$n} and next; + $selected{$n} = undef; + + #my (%pre_choices, @pre_choices, @choices, @upgradable_choices, %choices_id); + #if (my ($n, $o, $v, $r) = /^([^\s\[]*)(?:\[\*\])?(?:\s+|\[)?([^\s\]]*)\s*([^\s\-\]]*)-?([^\s\]]*)/) { foreach my $fullname (keys %{$urpm->{params}{provides}{$n} || {}}) { exists $conflicts{$fullname} and next; my $pkg = $urpm->{params}{info}{$fullname}; - $o and $n eq $pkg->{name} || next; - $v and eval(rpmtools::version_compare($pkg->{version}, $v) . $o . 0) || next; - $r && rpmtools::version_compare($pkg->{version}, $v) == 0 and - eval(rpmtools::version_compare($pkg->{release}, $r) . $o . 0) || next; - push @{$pre_choices{$pkg->{name}}}, $pkg; + if ($n ne $pkg->{name} && $o) { + #- a virtual provides exists with a specific version and maybe release. + #- try to resolve. + foreach (@{$pkg->{provides}}) { + if (my ($pn, $po, $pv, $pr) = /^([^\s\[]*)(?:\[\*\])?(?:\s+|\[)?([^\s\]]*)\s*([^\s\-\]]*)-?([^\s\]]*)/) { + $pn eq $n or next; + my $no = $po eq '==' ? $o : $po; #- CHECK TODO ? + $pv and eval(rpmtools::version_compare($pv, $v) . $no . 0) || next; + $pr && rpmtools::version_compare($pv, $v) == 0 and + eval(rpmtools::version_compare($pr, $r) . $no . 0) || next; + push @{$pre_choices{$pkg->{name}}}, $pkg; + } + } + } else { + $v and eval(rpmtools::version_compare($pkg->{version}, $v) . $o . 0) || next; + $r && rpmtools::version_compare($pkg->{version}, $v) == 0 and + eval(rpmtools::version_compare($pkg->{release}, $r) . $o . 0) || next; + push @{$pre_choices{$pkg->{name}}}, $pkg; + } } } foreach (values %pre_choices) { @@ -1628,7 +1626,7 @@ sub filter_packages_to_upgrade { foreach my $pkg (@pre_choices) { push @choices, $pkg; - unless ($options{keep_alldeps}) { + unless ($options{keep_alldeps} || exists $installed{$pkg->{id}}) { rpmtools::db_traverse_tag($db, 'name', [ $pkg->{name} ], [ qw(name version release serial) ], sub { @@ -1642,12 +1640,14 @@ sub filter_packages_to_upgrade { }); } $installed{$pkg->{id}} and delete $packages->{$pkg->{id}}; + exists $installed{$pkg->{id}} and push @upgradable_choices, $pkg; + } + foreach my $pkg (@pre_choices) { if (exists $packages->{$pkg->{id}} || $installed{$pkg->{id}}) { #- the package is already selected, or installed with a better version and release. @choices = @upgradable_choices = (); last; } - exists $installed{$pkg->{id}} and push @upgradable_choices, $pkg; } @upgradable_choices > 0 and @choices = @upgradable_choices; @choices_id{map { $_->{id} } @choices} = (); @@ -36,6 +36,7 @@ my $WID = 0; my $all = 0; my $rpm_opt = "vh"; my $use_provides = 1; +my $fuzzy = 0; my $verbose = 0; my $uid; @@ -69,6 +70,8 @@ usage: X or text mode. ") . _(" -a - select all matches on command line. ") . _(" -p - allow search in provides to find package. +") . _(" -P - do not search in provides to find package. +") . _(" -y - impose fuzzy search. ") . _(" -q - quiet mode. ") . _(" -v - verbose mode. ") . "\n" . _(" names or rpm files given on command line are installed. @@ -104,6 +107,8 @@ for (@ARGV) { /M/ and do { next }; #- nop /q/ and do { $rpm_opt = ""; next }; /p/ and do { $use_provides = 1; next }; + /P/ and do { $use_provides = 0; next }; + /y/ and do { $fuzzy = 1; next }; /v/ and do { $verbose = 1; next }; die _("urpmi: unknown option \"-%s\", check usage with --help\n", $1); } next }; @nextargv and do { my $r = shift @nextargv; $r and $$r = $_; next }; @@ -119,6 +124,7 @@ for (@ARGV) { #- params contains informations to parse installed system. my $urpm = new urpm; +my ($pid_out, $pid_err); if ($uid) { #- only src files are installable using urpmi. @@ -130,8 +136,6 @@ if ($uid) { #- log only at this point in case of query usage. log_it(scalar localtime, " urpmi called with @ARGV\n"); - my ($pid_out, $pid_err); - open SAVEOUT, ">&STDOUT"; select SAVEOUT; $| = 1; open SAVEERR, ">&STDERR"; select SAVEERR; $| = 1; unless ($pid_out = open STDOUT, "|-") { @@ -196,7 +200,9 @@ if ($uid) { my %packages; $urpm->search_packages(\%packages, [ @names], all => $all, - use_provides => $use_provides) or $force or exit 1; + use_provides => $use_provides, + fuzzy => $fuzzy) + or $force or exit 1; #- filter to add in packages selected required packages. my $ask_choice = sub { @@ -379,9 +385,11 @@ if (@rpms_install || @rpms_upgrade) { #- this help flushing correctly by closing this file before (piped on tee). #- but killing them is generally better. -fork() or do { sleep 1; kill 15, $pid_err, $pid_out }; -close STDERR; -close STDOUT; +if ($pid_err && $pid_out) { + fork() or do { sleep 1; kill 15, $pid_err, $pid_out }; + close STDERR; + close STDOUT; +} sub toMb { my $nb = $_[0] / 1024 / 1024; @@ -2,7 +2,7 @@ Name: urpmi Version: 3.2 -Release: 4mdk +Release: 5mdk License: GPL Source0: %{name}.tar.bz2 Source1: %{name}.logrotate @@ -144,6 +144,12 @@ fi %changelog +* Tue Jan 29 2002 François Pons <fpons@mandrakesoft.com> 3.2-5mdk +- added -y options to urpmi/urpmq to impose fuzzy search. +- cleaned dependancy resolver algorithm. +- fixed package asked to be installed but already installed (rare). +- fixed TERM signal send to itself. + * Mon Jan 28 2002 François Pons <fpons@mandrakesoft.com> 3.2-4mdk - integrated patch for supermount from Andrej Borsenkow. - fixed --wget (or --curl) not used in urpmi.update. @@ -42,6 +42,8 @@ usage: ") . _(" -u - remove package if a better version is already installed. ") . _(" -c - choose complete method for resolving requires closure. ") . _(" -p - allow search in provides to find package. +") . _(" -P - do not search in provides to find package. +") . _(" -y - impose fuzzy search. ") . _(" -g - print groups too with name. ") . _(" -r - print version and release too with name. ") . _(" -f - print version, release and arch with name. @@ -77,6 +79,8 @@ for (@ARGV) { /c/ and do { $query->{complete} = 1; next }; /g/ and do { $query->{group} = 1; next }; /p/ and do { $query->{use_provides} = 1; next }; + /P/ and do { $query->{use_provides} = 0; next }; + /y/ and do { $query->{fuzzy} = 1; next }; /v/ and do { $query->{verbose} = 1; next }; /r/ and do { $query->{version} = $query->{release} = 1; next }; /f/ and do { $query->{version} = $query->{release} = $query->{arch} = 1; next }; @@ -119,7 +123,8 @@ $urpm->relocate_depslist_provides(); #- will be updated too. my %packages; $urpm->search_packages(\%packages, [ @names ], - use_provides => $query->{use_provides}) + use_provides => $query->{use_provides}, + fuzzy => $query->{fuzzy}) or $query->{force} or exit 1; #- auto select package for upgrading the distribution. |