소스 검색

Dpkg::Deps: Add new deps_iterate() function

Closes: #759747

Based-on-patch-by: Dima Kogan <dima@secretsauce.net>
Guillem Jover 12 년 전
부모
커밋
bf46f08e0f
3개의 변경된 파일59개의 추가작업 그리고 3개의 파일을 삭제
  1. 2 0
      debian/changelog
  2. 39 2
      scripts/Dpkg/Deps.pm
  3. 18 1
      scripts/t/Dpkg_Deps.t

+ 2 - 0
debian/changelog

@@ -33,6 +33,8 @@ dpkg (1.17.14) UNRELEASED; urgency=low
   * Man pages:
     - Add a mention of packaging helpers support in dpkg-maintscript-helper(1).
       Closes: #759754
+  * Add new deps_iterate() function to Dpkg::Deps. Closes: #759747
+    Based on a patch by Dima Kogan <dima@secretsauce.net>.
 
   [ Raphaël Hertzog ]
   * Explain better in deb-triggers(5) why interest/activate-noawait should be

+ 39 - 2
scripts/Dpkg/Deps.pm

@@ -49,7 +49,7 @@ All the deps_* functions are exported by default.
 use strict;
 use warnings;
 
-our $VERSION = '1.04';
+our $VERSION = '1.05';
 
 use Dpkg::Version;
 use Dpkg::Arch qw(get_host_arch get_build_arch);
@@ -58,7 +58,8 @@ use Dpkg::ErrorHandling;
 use Dpkg::Gettext;
 
 use Exporter qw(import);
-our @EXPORT = qw(deps_concat deps_parse deps_eval_implication deps_compare);
+our @EXPORT = qw(deps_concat deps_parse deps_eval_implication
+                deps_iterate deps_compare);
 
 =item deps_eval_implication($rel_p, $v_p, $rel_q, $v_q)
 
@@ -308,6 +309,38 @@ sub deps_parse {
     return $dep_and;
 }
 
+=item my $bool = deps_iterate($deps, $callback_func)
+
+This function visits all elements of the dependency object, calling the
+callback function for each element.
+
+The callback function is expected to return true when everything is fine,
+or false if something went wrong, in which case the iteration will stop.
+
+Return the same value as the callback function.
+
+=cut
+
+sub deps_iterate {
+    my ($deps, $callback_func) = @_;
+
+    my $visitor_func;
+    $visitor_func = sub {
+        foreach my $dep (@_) {
+            return unless defined $dep;
+
+            if ($dep->isa('Dpkg::Deps::Simple')) {
+                return unless &{$callback_func}($dep);
+            } else {
+                return unless &{$visitor_func}($dep->get_deps());
+            }
+        }
+        return 1;
+    };
+
+    return &{$visitor_func}($deps);
+}
+
 =item deps_compare($a, $b)
 
 Implements a comparison operator between two dependency objects.
@@ -1470,6 +1503,10 @@ sub _evaluate_simple_dep {
 
 =head1 CHANGES
 
+=head2 Version 1.05
+
+New function: Dpkg::Deps::deps_iterate().
+
 =head2 Version 1.04
 
 New options: Add use_profiles, build_profiles, reduce_profiles and

+ 18 - 1
scripts/t/Dpkg_Deps.t

@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 41;
+use Test::More tests => 43;
 use Dpkg::Arch qw(get_host_arch);
 use Dpkg::Version;
 
@@ -183,3 +183,20 @@ $SIG{__WARN__} = sub {};
 my $dep_bad_multiline = deps_parse("a, foo\nbar, c");
 ok(!defined($dep_bad_multiline), 'invalid dependency split over multiple line');
 delete $SIG{__WARN__};
+
+my $dep_iter = deps_parse('a, b:armel, c | d:armhf, d:mips (>> 1.2)');
+my %dep_arches;
+my %dep_pkgs;
+deps_iterate($dep_iter, sub {
+    my ($dep) = @_;
+
+    $dep_pkgs{$dep->{package}} = 1;
+    if ($dep->{archqual}) {
+        $dep_arches{$dep->{archqual}} = 1;
+    }
+    return 1;
+});
+my @dep_arches = sort keys %dep_arches;
+my @dep_pkgs = sort keys %dep_pkgs;
+is("@dep_arches", 'armel armhf mips', 'Dependency iterator, get arches');
+is("@dep_pkgs", 'a b c d', 'Dependency iterator, get packages');