File Coverage

blib/lib/Dpkg/Deps.pm
Criterion Covered Total %
statement 153 168 91.0
branch 90 142 63.3
condition 47 67 70.1
subroutine 22 22 100.0
pod 5 5 100.0
total 317 404 78.4


line stmt bran cond sub pod time code
1             # Copyright © 1998 Richard Braakman
2             # Copyright © 1999 Darren Benham
3             # Copyright © 2000 Sean 'Shaleh' Perry
4             # Copyright © 2004 Frank Lichtenheld
5             # Copyright © 2006 Russ Allbery
6             # Copyright © 2007-2009 Raphaël Hertzog
7             # Copyright © 2008-2009,2012-2014 Guillem Jover
8             #
9             # This program is free software; you may redistribute it and/or modify
10             # it under the terms of the GNU General Public License as published by
11             # the Free Software Foundation; either version 2 of the License, or
12             # (at your option) any later version.
13             #
14             # This is distributed in the hope that it will be useful,
15             # but WITHOUT ANY WARRANTY; without even the implied warranty of
16             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17             # GNU General Public License for more details.
18             #
19             # You should have received a copy of the GNU General Public License
20             # along with this program. If not, see .
21              
22             package Dpkg::Deps;
23              
24             =encoding utf8
25              
26             =head1 NAME
27              
28             Dpkg::Deps - parse and manipulate dependencies of Debian packages
29              
30             =head1 DESCRIPTION
31              
32             The Dpkg::Deps module provides classes implementing various types of
33             dependencies.
34              
35             The most important function is deps_parse(), it turns a dependency line in
36             a set of Dpkg::Deps::{Simple,AND,OR,Union} objects depending on the case.
37              
38             =head1 FUNCTIONS
39              
40             All the deps_* functions are exported by default.
41              
42             =over 4
43              
44             =cut
45              
46 1     1   715 use strict;
  1         13  
  1         24  
47 1     1   4 use warnings;
  1         1  
  1         43  
48              
49             our $VERSION = '1.07';
50             our @EXPORT = qw(
51             deps_concat
52             deps_parse
53             deps_eval_implication
54             deps_iterate
55             deps_compare
56             );
57              
58 1     1   5 use Carp;
  1         1  
  1         57  
59 1     1   6 use Exporter qw(import);
  1         1  
  1         21  
60              
61 1     1   4 use Dpkg::Version;
  1         2  
  1         86  
62 1     1   6 use Dpkg::Arch qw(get_host_arch get_build_arch debarch_to_debtuple);
  1         1  
  1         60  
63 1     1   441 use Dpkg::BuildProfiles qw(get_build_profiles);
  1         3  
  1         42  
64 1     1   6 use Dpkg::ErrorHandling;
  1         2  
  1         57  
65 1     1   4 use Dpkg::Gettext;
  1         1  
  1         41  
66 1     1   514 use Dpkg::Deps::Simple;
  1         2  
  1         25  
67 1     1   475 use Dpkg::Deps::Union;
  1         2  
  1         26  
68 1     1   467 use Dpkg::Deps::AND;
  1         2  
  1         27  
69 1     1   455 use Dpkg::Deps::OR;
  1         2  
  1         26  
70 1     1   474 use Dpkg::Deps::KnownFacts;
  1         2  
  1         1145  
71              
72             =item deps_eval_implication($rel_p, $v_p, $rel_q, $v_q)
73              
74             ($rel_p, $v_p) and ($rel_q, $v_q) express two dependencies as (relation,
75             version). The relation variable can have the following values that are
76             exported by Dpkg::Version: REL_EQ, REL_LT, REL_LE, REL_GT, REL_GT.
77              
78             This functions returns 1 if the "p" dependency implies the "q"
79             dependency. It returns 0 if the "p" dependency implies that "q" is
80             not satisfied. It returns undef when there's no implication.
81              
82             The $v_p and $v_q parameter should be Dpkg::Version objects.
83              
84             =cut
85              
86             sub deps_eval_implication {
87 25     25 1 49 my ($rel_p, $v_p, $rel_q, $v_q) = @_;
88              
89             # If versions are not valid, we can't decide of any implication
90 25 50 33     74 return unless defined($v_p) and $v_p->is_valid();
91 25 50 33     68 return unless defined($v_q) and $v_q->is_valid();
92              
93             # q wants an exact version, so p must provide that exact version. p
94             # disproves q if q's version is outside the range enforced by p.
95 25 100       49 if ($rel_q eq REL_EQ) {
96 3 100       8 if ($rel_p eq REL_LT) {
    50          
    50          
    0          
    0          
97 2 100       5 return ($v_p <= $v_q) ? 0 : undef;
98             } elsif ($rel_p eq REL_LE) {
99 0 0       0 return ($v_p < $v_q) ? 0 : undef;
100             } elsif ($rel_p eq REL_GT) {
101 1 50       3 return ($v_p >= $v_q) ? 0 : undef;
102             } elsif ($rel_p eq REL_GE) {
103 0 0       0 return ($v_p > $v_q) ? 0 : undef;
104             } elsif ($rel_p eq REL_EQ) {
105 0         0 return ($v_p == $v_q);
106             }
107             }
108              
109             # A greater than clause may disprove a less than clause. An equal
110             # cause might as well. Otherwise, if
111             # p's clause is <<, <=, or =, the version must be <= q's to imply q.
112 22 100       30 if ($rel_q eq REL_LE) {
113 3 50       10 if ($rel_p eq REL_GT) {
    100          
    50          
114 0 0       0 return ($v_p >= $v_q) ? 0 : undef;
115             } elsif ($rel_p eq REL_GE) {
116 1 50       3 return ($v_p > $v_q) ? 0 : undef;
117             } elsif ($rel_p eq REL_EQ) {
118 0 0       0 return ($v_p <= $v_q) ? 1 : 0;
119             } else { # <<, <=
120 2 100       5 return ($v_p <= $v_q) ? 1 : undef;
121             }
122             }
123              
124             # Similar, but << is stronger than <= so p's version must be << q's
125             # version if the p relation is <= or =.
126 19 100       27 if ($rel_q eq REL_LT) {
127 4 100 100     22 if ($rel_p eq REL_GT or $rel_p eq REL_GE) {
    50          
    50          
128 2 50       6 return ($v_p >= $v_p) ? 0 : undef;
129             } elsif ($rel_p eq REL_LT) {
130 0 0       0 return ($v_p <= $v_q) ? 1 : undef;
131             } elsif ($rel_p eq REL_EQ) {
132 2 100       8 return ($v_p < $v_q) ? 1 : 0;
133             } else { # <<, <=
134 0 0       0 return ($v_p < $v_q) ? 1 : undef;
135             }
136             }
137              
138             # Same logic as above, only inverted.
139 15 100       26 if ($rel_q eq REL_GE) {
140 10 50       25 if ($rel_p eq REL_LT) {
    100          
    50          
141 0 0       0 return ($v_p <= $v_q) ? 0 : undef;
142             } elsif ($rel_p eq REL_LE) {
143 2 50       4 return ($v_p < $v_q) ? 0 : undef;
144             } elsif ($rel_p eq REL_EQ) {
145 0 0       0 return ($v_p >= $v_q) ? 1 : 0;
146             } else { # >>, >=
147 8 100       20 return ($v_p >= $v_q) ? 1 : undef;
148             }
149             }
150 5 50       14 if ($rel_q eq REL_GT) {
151 5 100 66     26 if ($rel_p eq REL_LT or $rel_p eq REL_LE) {
    50          
    100          
152 1 50       3 return ($v_p <= $v_q) ? 0 : undef;
153             } elsif ($rel_p eq REL_GT) {
154 0 0       0 return ($v_p >= $v_q) ? 1 : undef;
155             } elsif ($rel_p eq REL_EQ) {
156 1 50       2 return ($v_p > $v_q) ? 1 : 0;
157             } else {
158 3 50       9 return ($v_p > $v_q) ? 1 : undef;
159             }
160             }
161              
162 0         0 return;
163             }
164              
165             =item $dep = deps_concat(@dep_list)
166              
167             This function concatenates multiple dependency lines into a single line,
168             joining them with ", " if appropriate, and always returning a valid string.
169              
170             =cut
171              
172             sub deps_concat {
173 5     5 1 536 my (@dep_list) = @_;
174              
175 5         13 return join ', ', grep { defined } @dep_list;
  7         24  
176             }
177              
178             =item $dep = deps_parse($line, %options)
179              
180             This function parses the dependency line and returns an object, either a
181             Dpkg::Deps::AND or a Dpkg::Deps::Union. Various options can alter the
182             behaviour of that function.
183              
184             =over 4
185              
186             =item use_arch (defaults to 1)
187              
188             Take into account the architecture restriction part of the dependencies.
189             Set to 0 to completely ignore that information.
190              
191             =item host_arch (defaults to the current architecture)
192              
193             Define the host architecture. By default it uses
194             Dpkg::Arch::get_host_arch() to identify the proper architecture.
195              
196             =item build_arch (defaults to the current architecture)
197              
198             Define the build architecture. By default it uses
199             Dpkg::Arch::get_build_arch() to identify the proper architecture.
200              
201             =item reduce_arch (defaults to 0)
202              
203             If set to 1, ignore dependencies that do not concern the current host
204             architecture. This implicitly strips off the architecture restriction
205             list so that the resulting dependencies are directly applicable to the
206             current architecture.
207              
208             =item use_profiles (defaults to 1)
209              
210             Take into account the profile restriction part of the dependencies. Set
211             to 0 to completely ignore that information.
212              
213             =item build_profiles (defaults to no profile)
214              
215             Define the active build profiles. By default no profile is defined.
216              
217             =item reduce_profiles (defaults to 0)
218              
219             If set to 1, ignore dependencies that do not concern the current build
220             profile. This implicitly strips off the profile restriction formula so
221             that the resulting dependencies are directly applicable to the current
222             profiles.
223              
224             =item reduce_restrictions (defaults to 0)
225              
226             If set to 1, ignore dependencies that do not concern the current set of
227             restrictions. This implicitly strips off any architecture restriction list
228             or restriction formula so that the resulting dependencies are directly
229             applicable to the current restriction.
230             This currently implies C and C, and overrides
231             them if set.
232              
233             =item union (defaults to 0)
234              
235             If set to 1, returns a Dpkg::Deps::Union instead of a Dpkg::Deps::AND. Use
236             this when parsing non-dependency fields like Conflicts.
237              
238             =item virtual (defaults to 0)
239              
240             If set to 1, allow only virtual package version relations, that is none,
241             or “=”.
242             This should be set whenever working with Provides fields.
243              
244             =item build_dep (defaults to 0)
245              
246             If set to 1, allow build-dep only arch qualifiers, that is “:native”.
247             This should be set whenever working with build-deps.
248              
249             =item tests_dep (defaults to 0)
250              
251             If set to 1, allow tests-specific package names in dependencies, that is
252             "@" and "@builddeps@" (since dpkg 1.18.7). This should be set whenever
253             working with dependency fields from F.
254              
255             =back
256              
257             =cut
258              
259             sub deps_parse {
260 67     67 1 4623 my ($dep_line, %options) = @_;
261              
262             # Validate arguments.
263             croak "invalid host_arch $options{host_arch}"
264 67 100 100     170 if defined $options{host_arch} and not defined debarch_to_debtuple($options{host_arch});
265             croak "invalid build_arch $options{build_arch}"
266 63 100 66     139 if defined $options{build_arch} and not defined debarch_to_debtuple($options{build_arch});
267              
268 59   50     201 $options{use_arch} //= 1;
269 59   100     167 $options{reduce_arch} //= 0;
270 59   50     177 $options{use_profiles} //= 1;
271 59   100     138 $options{reduce_profiles} //= 0;
272 59   100     174 $options{reduce_restrictions} //= 0;
273 59   100     156 $options{union} //= 0;
274 59   50     152 $options{virtual} //= 0;
275 59   100     190 $options{build_dep} //= 0;
276 59   100     161 $options{tests_dep} //= 0;
277              
278 59 100       96 if ($options{reduce_restrictions}) {
279 1         2 $options{reduce_arch} = 1;
280 1         1 $options{reduce_profiles} = 1;
281             }
282 59 100       81 if ($options{reduce_arch}) {
283 4   66     13 $options{host_arch} //= get_host_arch();
284 4   33     26 $options{build_arch} //= get_build_arch();
285             }
286 59 100       76 if ($options{reduce_profiles}) {
287 5   50     10 $options{build_profiles} //= [ get_build_profiles() ];
288             }
289              
290             # Options for Dpkg::Deps::Simple.
291             my %deps_options = (
292             host_arch => $options{host_arch},
293             build_arch => $options{build_arch},
294             build_dep => $options{build_dep},
295             tests_dep => $options{tests_dep},
296 59         173 );
297              
298             # Strip trailing/leading spaces
299 59         188 $dep_line =~ s/^\s+//;
300 59         210 $dep_line =~ s/\s+$//;
301              
302 59         70 my @dep_list;
303 59         289 foreach my $dep_and (split(/\s*,\s*/m, $dep_line)) {
304 219         254 my @or_list = ();
305 219         440 foreach my $dep_or (split(/\s*\|\s*/m, $dep_and)) {
306 254         727 my $dep_simple = Dpkg::Deps::Simple->new($dep_or, %deps_options);
307 254 100       490 if (not defined $dep_simple->{package}) {
308 4         24 warning(g_("can't parse dependency %s"), $dep_or);
309 4         36 return;
310             }
311 250 0 33     391 if ($options{virtual} && defined $dep_simple->{relation} &&
      33        
312             $dep_simple->{relation} ne '=') {
313 0         0 warning(g_('virtual dependency contains invalid relation: %s'),
314             $dep_simple->output);
315 0         0 return;
316             }
317 250 50       332 $dep_simple->{arches} = undef if not $options{use_arch};
318 250 100       340 if ($options{reduce_arch}) {
319 15         41 $dep_simple->reduce_arch($options{host_arch});
320 15 100       30 next if not $dep_simple->arch_is_concerned($options{host_arch});
321             }
322 244 50       307 $dep_simple->{restrictions} = undef if not $options{use_profiles};
323 244 100       350 if ($options{reduce_profiles}) {
324 62         125 $dep_simple->reduce_profiles($options{build_profiles});
325 62 100       95 next if not $dep_simple->profile_is_concerned($options{build_profiles});
326             }
327 215         346 push @or_list, $dep_simple;
328             }
329 215 100       323 next if not @or_list;
330 181 100       274 if (scalar @or_list == 1) {
331 159         235 push @dep_list, $or_list[0];
332             } else {
333 22         56 my $dep_or = Dpkg::Deps::OR->new();
334 22         48 $dep_or->add($_) foreach (@or_list);
335 22         41 push @dep_list, $dep_or;
336             }
337             }
338 55         72 my $dep_and;
339 55 100       76 if ($options{union}) {
340 3         33 $dep_and = Dpkg::Deps::Union->new();
341             } else {
342 52         133 $dep_and = Dpkg::Deps::AND->new();
343             }
344 55         83 foreach my $dep (@dep_list) {
345 179 50 66     288 if ($options{union} and not $dep->isa('Dpkg::Deps::Simple')) {
346 0         0 warning(g_('an union dependency can only contain simple dependencies'));
347 0         0 return;
348             }
349 179         269 $dep_and->add($dep);
350             }
351 55         248 return $dep_and;
352             }
353              
354             =item $bool = deps_iterate($deps, $callback_func)
355              
356             This function visits all elements of the dependency object, calling the
357             callback function for each element.
358              
359             The callback function is expected to return true when everything is fine,
360             or false if something went wrong, in which case the iteration will stop.
361              
362             Return the same value as the callback function.
363              
364             =cut
365              
366             sub deps_iterate {
367 65     65 1 91 my ($deps, $callback_func) = @_;
368              
369 65         62 my $visitor_func;
370             $visitor_func = sub {
371 74     74   110 foreach my $dep (@_) {
372 85 50       147 return unless defined $dep;
373              
374 85 100       175 if ($dep->isa('Dpkg::Deps::Simple')) {
375 76 50       101 return unless $callback_func->($dep);
376             } else {
377 9 50       20 return unless $visitor_func->($dep->get_deps());
378             }
379             }
380 74         117 return 1;
381 65         182 };
382              
383 65         94 return $visitor_func->($deps);
384             }
385              
386             =item deps_compare($a, $b)
387              
388             Implements a comparison operator between two dependency objects.
389             This function is mainly used to implement the sort() method.
390              
391             =back
392              
393             =cut
394              
395             my %relation_ordering = (
396             undef => 0,
397             REL_GE() => 1,
398             REL_GT() => 2,
399             REL_EQ() => 3,
400             REL_LT() => 4,
401             REL_LE() => 5,
402             );
403              
404             sub deps_compare {
405 32     32 1 40 my ($aref, $bref) = @_;
406              
407 32         32 my (@as, @bs);
408 32     34   100 deps_iterate($aref, sub { push @as, @_ });
  34         73  
409 32     37   126 deps_iterate($bref, sub { push @bs, @_ });
  37         106  
410              
411 32         36 while (1) {
412 35         44 my ($a, $b) = (shift @as, shift @bs);
413 35 100       103 my $aundef = not defined $a or $a->is_empty();
414 35 50       72 my $bundef = not defined $b or $b->is_empty();
415              
416 35 50 66     56 return 0 if $aundef and $bundef;
417 35 100       46 return -1 if $aundef;
418 33 50       42 return 1 if $bundef;
419              
420 33   100     53 my $ar = $a->{relation} // 'undef';
421 33   100     52 my $br = $b->{relation} // 'undef';
422 33   100     89 my $av = $a->{version} // '';
423 33   100     66 my $bv = $b->{version} // '';
424              
425             my $res = (($a->{package} cmp $b->{package}) ||
426 33   66     79 ($relation_ordering{$ar} <=> $relation_ordering{$br}) ||
427             ($av cmp $bv));
428 33 100       99 return $res if $res != 0;
429             }
430             }
431              
432             =head1 CLASSES - Dpkg::Deps::*
433              
434             There are several kind of dependencies. A Dpkg::Deps::Simple dependency
435             represents a single dependency statement (it relates to one package only).
436             Dpkg::Deps::Multiple dependencies are built on top of this class
437             and combine several dependencies in different manners. Dpkg::Deps::AND
438             represents the logical "AND" between dependencies while Dpkg::Deps::OR
439             represents the logical "OR". Dpkg::Deps::Multiple objects can contain
440             Dpkg::Deps::Simple object as well as other Dpkg::Deps::Multiple objects.
441              
442             In practice, the code is only meant to handle the realistic cases which,
443             given Debian's dependencies structure, imply those restrictions: AND can
444             contain Simple or OR objects, OR can only contain Simple objects.
445              
446             Dpkg::Deps::KnownFacts is a special class that is used while evaluating
447             dependencies and while trying to simplify them. It represents a set of
448             installed packages along with the virtual packages that they might
449             provide.
450              
451             =head1 CHANGES
452              
453             =head2 Version 1.07 (dpkg 1.20.0)
454              
455             New option: Add virtual option to Dpkg::Deps::deps_parse().
456              
457             =head2 Version 1.06 (dpkg 1.18.7; module version bumped on dpkg 1.18.24)
458              
459             New option: Add tests_dep option to Dpkg::Deps::deps_parse().
460              
461             =head2 Version 1.05 (dpkg 1.17.14)
462              
463             New function: Dpkg::Deps::deps_iterate().
464              
465             =head2 Version 1.04 (dpkg 1.17.10)
466              
467             New options: Add use_profiles, build_profiles, reduce_profiles and
468             reduce_restrictions to Dpkg::Deps::deps_parse().
469              
470             =head2 Version 1.03 (dpkg 1.17.0)
471              
472             New option: Add build_arch option to Dpkg::Deps::deps_parse().
473              
474             =head2 Version 1.02 (dpkg 1.17.0)
475              
476             New function: Dpkg::Deps::deps_concat()
477              
478             =head2 Version 1.01 (dpkg 1.16.1)
479              
480            
481              
482             =head2 Version 1.00 (dpkg 1.15.6)
483              
484             Mark the module as public.
485              
486             =cut
487              
488             1;