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   944 use strict;
  1         18  
  1         30  
47 1     1   6 use warnings;
  1         2  
  1         54  
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         2  
  1         62  
59 1     1   6 use Exporter qw(import);
  1         1  
  1         30  
60              
61 1     1   5 use Dpkg::Version;
  1         2  
  1         79  
62 1     1   6 use Dpkg::Arch qw(get_host_arch get_build_arch debarch_to_debtuple);
  1         2  
  1         81  
63 1     1   582 use Dpkg::BuildProfiles qw(get_build_profiles);
  1         2  
  1         53  
64 1     1   8 use Dpkg::ErrorHandling;
  1         2  
  1         74  
65 1     1   6 use Dpkg::Gettext;
  1         2  
  1         50  
66 1     1   660 use Dpkg::Deps::Simple;
  1         5  
  1         31  
67 1     1   632 use Dpkg::Deps::Union;
  1         3  
  1         31  
68 1     1   590 use Dpkg::Deps::AND;
  1         3  
  1         32  
69 1     1   572 use Dpkg::Deps::OR;
  1         3  
  1         32  
70 1     1   653 use Dpkg::Deps::KnownFacts;
  1         3  
  1         1453  
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 61 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     91 return unless defined($v_p) and $v_p->is_valid();
91 25 50 33     89 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       62 if ($rel_q eq REL_EQ) {
96 3 100       18 if ($rel_p eq REL_LT) {
    50          
    50          
    0          
    0          
97 2 100       9 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       45 if ($rel_q eq REL_LE) {
113 3 50       13 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       4 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       38 if ($rel_q eq REL_LT) {
127 4 100 100     35 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       9 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       28 if ($rel_q eq REL_GE) {
140 10 50       32 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       5 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       23 return ($v_p >= $v_q) ? 1 : undef;
148             }
149             }
150 5 50       26 if ($rel_q eq REL_GT) {
151 5 100 66     35 if ($rel_p eq REL_LT or $rel_p eq REL_LE) {
    50          
    100          
152 1 50       4 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       3 return ($v_p > $v_q) ? 1 : 0;
157             } else {
158 3 50       12 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 626 my (@dep_list) = @_;
174              
175 5         14 return join ', ', grep { defined } @dep_list;
  7         30  
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 5526 my ($dep_line, %options) = @_;
261              
262             # Validate arguments.
263             croak "invalid host_arch $options{host_arch}"
264 67 100 100     235 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     165 if defined $options{build_arch} and not defined debarch_to_debtuple($options{build_arch});
267              
268 59   50     252 $options{use_arch} //= 1;
269 59   100     214 $options{reduce_arch} //= 0;
270 59   50     189 $options{use_profiles} //= 1;
271 59   100     198 $options{reduce_profiles} //= 0;
272 59   100     184 $options{reduce_restrictions} //= 0;
273 59   100     214 $options{union} //= 0;
274 59   50     180 $options{virtual} //= 0;
275 59   100     174 $options{build_dep} //= 0;
276 59   100     198 $options{tests_dep} //= 0;
277              
278 59 100       114 if ($options{reduce_restrictions}) {
279 1         2 $options{reduce_arch} = 1;
280 1         2 $options{reduce_profiles} = 1;
281             }
282 59 100       97 if ($options{reduce_arch}) {
283 4   66     17 $options{host_arch} //= get_host_arch();
284 4   33     31 $options{build_arch} //= get_build_arch();
285             }
286 59 100       97 if ($options{reduce_profiles}) {
287 5   50     12 $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         202 );
297              
298             # Strip trailing/leading spaces
299 59         254 $dep_line =~ s/^\s+//;
300 59         298 $dep_line =~ s/\s+$//;
301              
302 59         86 my @dep_list;
303 59         350 foreach my $dep_and (split(/\s*,\s*/m, $dep_line)) {
304 219         361 my @or_list = ();
305 219         581 foreach my $dep_or (split(/\s*\|\s*/m, $dep_and)) {
306 254         930 my $dep_simple = Dpkg::Deps::Simple->new($dep_or, %deps_options);
307 254 100       665 if (not defined $dep_simple->{package}) {
308 4         30 warning(g_("can't parse dependency %s"), $dep_or);
309 4         42 return;
310             }
311 250 0 33     490 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       424 $dep_simple->{arches} = undef if not $options{use_arch};
318 250 100       438 if ($options{reduce_arch}) {
319 15         46 $dep_simple->reduce_arch($options{host_arch});
320 15 100       32 next if not $dep_simple->arch_is_concerned($options{host_arch});
321             }
322 244 50       397 $dep_simple->{restrictions} = undef if not $options{use_profiles};
323 244 100       402 if ($options{reduce_profiles}) {
324 62         180 $dep_simple->reduce_profiles($options{build_profiles});
325 62 100       127 next if not $dep_simple->profile_is_concerned($options{build_profiles});
326             }
327 215         475 push @or_list, $dep_simple;
328             }
329 215 100       440 next if not @or_list;
330 181 100       310 if (scalar @or_list == 1) {
331 159         288 push @dep_list, $or_list[0];
332             } else {
333 22         77 my $dep_or = Dpkg::Deps::OR->new();
334 22         76 $dep_or->add($_) foreach (@or_list);
335 22         42 push @dep_list, $dep_or;
336             }
337             }
338 55         100 my $dep_and;
339 55 100       96 if ($options{union}) {
340 3         55 $dep_and = Dpkg::Deps::Union->new();
341             } else {
342 52         180 $dep_and = Dpkg::Deps::AND->new();
343             }
344 55         100 foreach my $dep (@dep_list) {
345 179 50 66     699 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         347 $dep_and->add($dep);
350             }
351 55         337 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 127 my ($deps, $callback_func) = @_;
368              
369 65         79 my $visitor_func;
370             $visitor_func = sub {
371 74     74   121 foreach my $dep (@_) {
372 85 50       188 return unless defined $dep;
373              
374 85 100       220 if ($dep->isa('Dpkg::Deps::Simple')) {
375 76 50       111 return unless $callback_func->($dep);
376             } else {
377 9 50       25 return unless $visitor_func->($dep->get_deps());
378             }
379             }
380 74         136 return 1;
381 65         234 };
382              
383 65         132 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 47 my ($aref, $bref) = @_;
406              
407 32         41 my (@as, @bs);
408 32     34   135 deps_iterate($aref, sub { push @as, @_ });
  34         90  
409 32     37   161 deps_iterate($bref, sub { push @bs, @_ });
  37         96  
410              
411 32         42 while (1) {
412 35         58 my ($a, $b) = (shift @as, shift @bs);
413 35 100       124 my $aundef = not defined $a or $a->is_empty();
414 35 50       87 my $bundef = not defined $b or $b->is_empty();
415              
416 35 50 66     67 return 0 if $aundef and $bundef;
417 35 100       59 return -1 if $aundef;
418 33 50       49 return 1 if $bundef;
419              
420 33   100     68 my $ar = $a->{relation} // 'undef';
421 33   100     62 my $br = $b->{relation} // 'undef';
422 33   100     106 my $av = $a->{version} // '';
423 33   100     80 my $bv = $b->{version} // '';
424              
425             my $res = (($a->{package} cmp $b->{package}) ||
426 33   66     97 ($relation_ordering{$ar} <=> $relation_ordering{$br}) ||
427             ($av cmp $bv));
428 33 100       128 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;