From f88b3c02a16cda5951b0cf5a66e86ae9f1d3cc6e Mon Sep 17 00:00:00 2001 From: Alad Wenter Date: Fri, 14 Jun 2024 15:01:53 +0200 Subject: [PATCH] Revert "Depends.pm: refactor extract to solve" This reverts commit ca8c02dd780539cda42ef1fa1fdaab136ed8382e. --- lib/aur-depends | 2 +- perl/AUR/Depends.pm | 134 ++++++++++++++++++++++++++-------------------------- perl/t/depends.t | 2 +- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/lib/aur-depends b/lib/aur-depends index 6d4ff7e4..f13ca50d 100755 --- a/lib/aur-depends +++ b/lib/aur-depends @@ -128,7 +128,7 @@ unless(caller) { # Retrieve AUR results # JSON -> hash -> extract depends[] -> repeat until none -> prune - my ($results, $dag, $dag_foreign) = solve(\@ARGV, \@types, \&callback_query, + my ($results, $dag, $dag_foreign) = get(\@ARGV, \@types, \&callback_query, $opt_verify, $opt_provides, $opt_installed); # Add `RequiredBy` to results diff --git a/perl/AUR/Depends.pm b/perl/AUR/Depends.pm index b83b424e..588704e4 100644 --- a/perl/AUR/Depends.pm +++ b/perl/AUR/Depends.pm @@ -6,7 +6,7 @@ use v5.20; use List::Util qw(first); use Carp; use Exporter qw(import); -our @EXPORT_OK = qw(vercmp recurse prune graph solve); +our @EXPORT_OK = qw(vercmp extract prune graph get); our $VERSION = 'unstable'; # Maximum number of calling the callback @@ -18,7 +18,7 @@ AUR::Depends - Resolve dependencies from AUR package information =head1 SYNOPSIS - use AUR::Depends qw(vercmp recurse prune graph solve); + use AUR::Depends qw(vercmp extract depends prune graph); =head1 DESCRIPTION @@ -85,11 +85,12 @@ sub vercmp { } } -=head2 recurse() +=head2 extract() -Solve dependencies rescursively with a callback function (C<$callback>), for a -matching series of dependency types (C<$types>). An example is -from C combined with from C. +Extracts dependency (C<$pkgdeps>) and provider (C<$pkgmap>) +information from an array of package information hashes, retrieved +through a callback function. An example is from +C combined with from C. Dependencies are tallied and only queried when newly encountered. @@ -102,8 +103,6 @@ Parameters: =item C<$targets> -The pkgnames for which to compute the dependency tree(s) of. - =item C<$types> =item C<$callback> @@ -112,15 +111,21 @@ The pkgnames for which to compute the dependency tree(s) of. =cut -sub recurse { +sub extract { my ($targets, $types, $callback) = @_; - my (%results, %tally); # indexed by pkgname - - # Main loop - my $a; my @depends = @{$targets}; - for ($a = 1; $a < $aur_callback_max; $a++) { + my (%results, %pkgdeps, %pkgmap, %tally); + + # Populate depends map with command-line targets (#1136) + for my $target (@{$targets}) { + push(@{$pkgdeps{$target}}, [$target, 'Self']); + } + + # XXX: return $a for testing number of requests, e.g. 7 for ros-noetic-desktop + my $a = 1; + while ($a < $aur_callback_max) + { if (defined $ENV{'AUR_DEBUG'}) { say STDERR join(" ", "callback: [$a]", @depends); } @@ -130,28 +135,42 @@ sub recurse { if (not scalar(@level) and $a == 1) { last; # no results } + $a++; + # Retrieve next level of dependencies from results @depends = (); for my $node (@level) { - my $name = $node->{'Name'}; + my $name = $node->{'Name'}; + my $version = $node->{'Version'}; $results{$name} = $node; + # Iterate over explicit provides + for my $spec (@{$node->{'Provides'} // []}) { + my ($prov, $prov_version) = split(/=/, $spec); + + # XXX: the first provider takes precedence + # keep multiple providers and warn on ambiguity instead + if (not defined $pkgmap{$prov} and $prov ne $name) { + $pkgmap{$prov} = [$name, $prov_version]; + } + } + # Filter out dependency types early (#882) $tally{$name} = $a; for my $deptype (@{$types}) { - if (not defined($node->{$deptype})) { - next; # no dependency of this type - } + next if (not defined($node->{$deptype})); # no dependency of this type + for my $spec (@{$node->{$deptype}}) { - # Valid operators (important: <= before <) + # Push versioned dependency to depends map + push(@{$pkgdeps{$name}}, [$spec, $deptype]); + + # Valid operators (important: <= before <) my ($dep, $op, $ver) = split(/(<=|>=|<|=|>)/, $spec); # Avoid querying duplicate packages (#4) - if (defined $tally{$dep}) { - next; - } + next if defined $tally{$dep}; push(@depends, $dep); # Mark as incomplete (retrieved in next level or repo package) @@ -179,7 +198,7 @@ sub recurse { say STDERR __PACKAGE__ . ": total requests: $a (out of range)"; exit(34); } - return \%results, $a + return \%results, \%pkgdeps, \%pkgmap; } =head2 graph() @@ -199,7 +218,9 @@ Parameters: =item C<$results> -=item C<$types> +=item C<$pkgdeps> + +=item C<$pkgmap> =item C<$verify> @@ -209,56 +230,40 @@ Parameters: =cut +# XXX: only used for versions and checking if AUR target sub graph { - my ($results, $types, $verify, $provides) = @_; - my (%dag, %dag_foreign, %pkgdeps, %pkgmap); + my ($results, $pkgdeps, $pkgmap, $verify, $provides) = @_; + my (%dag, %dag_foreign); my $dag_valid = 1; $verify //= 1; # run vercmp by default - # Iterate over packages, retrieve provides - for my $name (keys %{$results}) { - my $node = $results->{$name}; - - # Iterate over explicit provides - for my $spec (@{$node->{'Provides'} // []}) { - my ($prov, $prov_version) = split(/=/, $spec); - - # XXX: the first provider takes precedence - # keep multiple providers and warn on ambiguity instead - if (not defined $pkgmap{$prov} and $prov ne $name) { - $pkgmap{$prov} = [$name, $prov_version]; - } - } - for my $deptype (@{$types}) { - if (not defined($node->{$deptype})) { - next; # no dependency of this type - } - for my $spec (@{$node->{$deptype}}) { - # Push versioned dependency to depends map - push(@{$pkgdeps{$name}}, [$spec, $deptype]); - } + # Iterate over packages + for my $name (keys %{$pkgdeps}) { + # Add a loop to command-line targets (#402, #1065, #1136) + if (defined $pkgdeps->{$name} and $pkgdeps->{$name} eq $name) { + $dag{$name}{$name} = 'Self'; } - } - # Iterate over depends - for my $name (keys %{$pkgdeps}) - { + # Iterate over dependencies for my $dep (@{$pkgdeps->{$name}}) { - # Retrieve dependency requirements my ($dep_spec, $dep_type) = @{$dep}; # ['foo>=1.0', 'Depends'] + + # Retrieve dependency requirements my ($dep_name, $dep_op, $dep_req) = split(/(<=|>=|<|=|>)/, $dep_spec); if (defined $results->{$dep_name}) { # Split results version to pkgver and pkgrel my @dep_ver = split("-", $results->{$dep_name}->{'Version'}, 2); - # Provides precede regular packages, unless $provides is false. - my ($prov_name, $prov_ver) = ($dep_name, $dep_ver[0]); + # Provides take precedence over regular packages, unless + # $provides is false. + my ($prov_name, $prov_ver) = ($dep_name, $dep_ver[0]); if ($provides and defined $pkgmap->{$dep_name}) { ($prov_name, $prov_ver) = @{$pkgmap->{$dep_name}}; } + # Run vercmp with provider and versioned dependency # XXX: a dependency can be both fulfilled by a package and a # different package (provides). In this case an error should @@ -334,9 +339,9 @@ sub prune { return \@removals; } -=head2 solve() +=head2 get() -High-level function which combines C, C and C. +High-level function which combines C, C and C. Parameters: @@ -350,28 +355,21 @@ Parameters: =item C<$opt_verify> -=item C<$opt_provides> - -=item C<$opt_installed> - =back =cut -sub solve { +sub get { my ($targets, $types, $callback, $opt_verify, $opt_provides, $opt_installed) = @_; # Retrieve AUR results (JSON -> dict -> extract depends -> repeat until none) - my ($results, undef) = recurse($targets, $types, $callback); + my ($results, $pkgdeps, $pkgmap) = extract($targets, $types, $callback); # Verify dependency requirements - my ($dag, $dag_foreign) = graph($results, $types, $opt_verify, $opt_provides); + my ($dag, $dag_foreign) = graph($results, $pkgdeps, $pkgmap, + $opt_verify, $opt_provides); my $removals = []; - # Add a loop to command-line targets (#402, #1065, #1136) - for my $name (@{$targets}) { - $dag{$name}{$name} = 'Self'; - } # Remove virtual dependencies from dependency graph (#1063) if ($opt_provides) { my @virtual = keys %{$pkgmap}; diff --git a/perl/t/depends.t b/perl/t/depends.t index ca4863e7..79882bb7 100644 --- a/perl/t/depends.t +++ b/perl/t/depends.t @@ -7,7 +7,7 @@ use Test::More; # Check if module can be imported require_ok "AUR::Depends"; -use AUR::Depends qw(vercmp recurse prune graph solve); +use AUR::Depends qw(vercmp extract prune graph get); ok(vercmp("1.0", "1.0", '=')); ok(vercmp("1.0a", "1.0b", '<')); -- 2.11.4.GIT