test: Move test_data_file() to test.h
[dpkg.git] / scripts / Dpkg / Deps / Simple.pm
bloba9dbf631e410419394a779a402aab075e16d22e2
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 <hertzog@debian.org>
7 # Copyright © 2008-2009, 2012-2014 Guillem Jover <guillem@debian.org>
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.
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.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
22 =encoding utf8
24 =head1 NAME
26 Dpkg::Deps::Simple - represents a single dependency statement
28 =head1 DESCRIPTION
30 This class represents a single dependency statement.
31 It has several interesting properties:
33 =over 4
35 =item package
37 The package name (can be undef if the dependency has not been initialized
38 or if the simplification of the dependency lead to its removal).
40 =item relation
42 The relational operator: "=", "<<", "<=", ">=" or ">>". It can be
43 undefined if the dependency had no version restriction. In that case the
44 following field is also undefined.
46 =item version
48 The version.
50 =item arches
52 The list of architectures where this dependency is applicable. It is
53 undefined when there's no restriction, otherwise it is an
54 array ref. It can contain an exclusion list, in that case each
55 architecture is prefixed with an exclamation mark.
57 =item archqual
59 The arch qualifier of the dependency (can be undef if there is none).
60 In the dependency "python:any (>= 2.6)", the arch qualifier is "any".
62 =item restrictions
64 The restrictions formula for this dependency. It is undefined when there
65 is no restriction formula. Otherwise it is an array ref.
67 =back
69 =cut
71 package Dpkg::Deps::Simple 1.02;
73 use strict;
74 use warnings;
76 use Carp;
78 use Dpkg::Arch qw(debarch_is_concerned debarch_list_parse);
79 use Dpkg::BuildProfiles qw(parse_build_profiles evaluate_restriction_formula);
80 use Dpkg::Version;
81 use Dpkg::ErrorHandling;
82 use Dpkg::Gettext;
84 use parent qw(Dpkg::Interface::Storable);
86 =head1 METHODS
88 =over 4
90 =item $dep = Dpkg::Deps::Simple->new([$dep[, %opts]]);
92 Creates a new object. Some options can be set through %opts:
94 =over
96 =item host_arch
98 Sets the host architecture.
100 =item build_arch
102 Sets the build architecture.
104 =item build_dep
106 Specifies whether the parser should consider it a build dependency.
107 Defaults to 0.
109 =item tests_dep
111 Specifies whether the parser should consider it a tests dependency.
112 Defaults to 0.
114 =back
116 =cut
118 sub new {
119 my ($this, $arg, %opts) = @_;
120 my $class = ref($this) || $this;
121 my $self = {};
123 bless $self, $class;
124 $self->reset();
125 $self->{host_arch} = $opts{host_arch};
126 $self->{build_arch} = $opts{build_arch};
127 $self->{build_dep} = $opts{build_dep} // 0;
128 $self->{tests_dep} = $opts{tests_dep} // 0;
129 $self->parse_string($arg) if defined $arg;
130 return $self;
133 =item $dep->reset()
135 Clears any dependency information stored in $dep so that $dep->is_empty()
136 returns true.
138 =cut
140 sub reset {
141 my $self = shift;
143 $self->{package} = undef;
144 $self->{relation} = undef;
145 $self->{version} = undef;
146 $self->{arches} = undef;
147 $self->{archqual} = undef;
148 $self->{restrictions} = undef;
151 =item $dep->parse_string($dep_string)
153 Parses the dependency string and modifies internal properties to match the
154 parsed dependency.
156 =cut
158 sub parse_string {
159 my ($self, $dep) = @_;
161 my $pkgname_re;
162 if ($self->{tests_dep}) {
163 $pkgname_re = qr/[\@a-zA-Z0-9][\@a-zA-Z0-9+.-]*/;
164 } else {
165 $pkgname_re = qr/[a-zA-Z0-9][a-zA-Z0-9+.-]*/;
168 ## no critic (RegularExpressions::ProhibitCaptureWithoutTest)
169 return if not $dep =~
170 m{^\s* # skip leading whitespace
171 ($pkgname_re) # package name
172 (?: # start of optional part
173 : # colon for architecture
174 ([a-zA-Z0-9][a-zA-Z0-9-]*) # architecture name
175 )? # end of optional part
176 (?: # start of optional part
177 \s* \( # open parenthesis for version part
178 \s* (<<|<=|=|>=|>>|[<>]) # relation part
179 \s* ([^\)\s]+) # do not attempt to parse version
180 \s* \) # closing parenthesis
181 )? # end of optional part
182 (?: # start of optional architecture
183 \s* \[ # open bracket for architecture
184 \s* ([^\]]+) # don't parse architectures now
185 \s* \] # closing bracket
186 )? # end of optional architecture
188 (?: # start of optional restriction
189 \s* < # open bracket for restriction
190 \s* [^>]+ # do not parse restrictions now
191 \s* > # closing bracket
193 )? # end of optional restriction
194 \s*$ # trailing spaces at end
196 if (defined $2) {
197 return if $2 eq 'native' and not $self->{build_dep};
198 $self->{archqual} = $2;
200 $self->{package} = $1;
201 $self->{relation} = version_normalize_relation($3) if defined $3;
202 if (defined $4) {
203 $self->{version} = Dpkg::Version->new($4);
205 if (defined $5) {
206 $self->{arches} = [ debarch_list_parse($5) ];
208 if (defined $6) {
209 $self->{restrictions} = [ parse_build_profiles($6) ];
213 =item $dep->parse($fh, $desc)
215 Parse a dependency line from a filehandle.
217 =cut
219 sub parse {
220 my ($self, $fh, $desc) = @_;
222 my $line = <$fh>;
223 chomp $line;
224 return $self->parse_string($line);
227 =item $dep->load($filename)
229 Parse a dependency line from $filename.
231 =item $dep->output([$fh])
233 =item "$dep"
235 Returns a string representing the dependency. If $fh is set, it prints
236 the string to the filehandle.
238 =cut
240 sub output {
241 my ($self, $fh) = @_;
243 my $res = $self->{package};
244 if (defined $self->{archqual}) {
245 $res .= ':' . $self->{archqual};
247 if (defined $self->{relation}) {
248 $res .= ' (' . $self->{relation} . ' ' . $self->{version} . ')';
250 if (defined $self->{arches}) {
251 $res .= ' [' . join(' ', @{$self->{arches}}) . ']';
253 if (defined $self->{restrictions}) {
254 for my $restrlist (@{$self->{restrictions}}) {
255 $res .= ' <' . join(' ', @{$restrlist}) . '>';
258 if (defined $fh) {
259 print { $fh } $res;
261 return $res;
264 =item $dep->save($filename)
266 Save the dependency into the given $filename.
268 =cut
270 # _arch_is_superset(\@p, \@q)
272 # Returns true if the arch list @p is a superset of arch list @q.
273 # The arguments can also be undef in case there's no explicit architecture
274 # restriction.
275 sub _arch_is_superset {
276 my ($p, $q) = @_;
277 my $p_arch_neg = defined $p and $p->[0] =~ /^!/;
278 my $q_arch_neg = defined $q and $q->[0] =~ /^!/;
280 if (not defined $p) {
281 # If "p" has no arches, it is a superset of q and we should fall through
282 # to the version check.
283 return 1;
284 } elsif (not defined $q) {
285 # If q has no arches, it is a superset of p and there are no useful
286 # implications.
287 return 0;
288 } elsif (not $p_arch_neg and not $q_arch_neg) {
289 # Both have arches. If neither are negated, we know nothing useful
290 # unless q is a subset of p.
292 my %p_arches = map { $_ => 1 } @{$p};
293 my $subset = 1;
294 for my $arch (@{$q}) {
295 $subset = 0 unless $p_arches{$arch};
297 return 0 unless $subset;
298 } elsif ($p_arch_neg and $q_arch_neg) {
299 # If both are negated, we know nothing useful unless p is a subset of
300 # q (and therefore has fewer things excluded, and therefore is more
301 # general).
303 my %q_arches = map { $_ => 1 } @{$q};
304 my $subset = 1;
305 for my $arch (@{$p}) {
306 $subset = 0 unless $q_arches{$arch};
308 return 0 unless $subset;
309 } elsif (not $p_arch_neg and $q_arch_neg) {
310 # If q is negated and p isn't, we'd need to know the full list of
311 # arches to know if there's any relationship, so bail.
312 return 0;
313 } elsif ($p_arch_neg and not $q_arch_neg) {
314 # If p is negated and q isn't, q is a subset of p if none of the
315 # negated arches in p are present in q.
317 my %q_arches = map { $_ => 1 } @{$q};
318 my $subset = 1;
319 for my $arch (@{$p}) {
320 $subset = 0 if $q_arches{substr($arch, 1)};
322 return 0 unless $subset;
324 return 1;
327 # _arch_qualifier_implies($p, $q)
329 # Returns true if the arch qualifier $p and $q are compatible with the
330 # implication $p -> $q, false otherwise. $p/$q can be undef/"any"/"native"
331 # or an architecture string.
333 # Because we are handling dependencies in isolation, and the full context
334 # of the implications are only known when doing dependency resolution at
335 # run-time, we can only assert that they are implied if they are equal.
337 # For example dependencies with different arch-qualifiers cannot be simplified
338 # as these depend on the state of Multi-Arch field in the package depended on.
339 sub _arch_qualifier_implies {
340 my ($p, $q) = @_;
342 return $p eq $q if defined $p and defined $q;
343 return 1 if not defined $p and not defined $q;
344 return 0;
347 # _restrictions_imply($p, $q)
349 # Returns true if the restrictions $p and $q are compatible with the
350 # implication $p -> $q, false otherwise.
351 # NOTE: We don't try to be very clever here, so we may conservatively
352 # return false when there is an implication.
353 sub _restrictions_imply {
354 my ($p, $q) = @_;
356 if (not defined $p) {
357 return 1;
358 } elsif (not defined $q) {
359 return 0;
360 } else {
361 # Check whether set difference is empty.
362 my %restr;
364 for my $restrlist (@{$q}) {
365 my $reststr = join ' ', sort @{$restrlist};
366 $restr{$reststr} = 1;
368 for my $restrlist (@{$p}) {
369 my $reststr = join ' ', sort @{$restrlist};
370 delete $restr{$reststr};
373 return keys %restr == 0;
377 =item $dep->implies($other_dep)
379 Returns 1 when $dep implies $other_dep. Returns 0 when $dep implies
380 NOT($other_dep). Returns undef when there is no implication. $dep and
381 $other_dep do not need to be of the same type.
383 =cut
385 sub implies {
386 my ($self, $o) = @_;
388 if ($o->isa('Dpkg::Deps::Simple')) {
389 # An implication is only possible on the same package
390 return if $self->{package} ne $o->{package};
392 # Our architecture set must be a superset of the architectures for
393 # o, otherwise we can't conclude anything.
394 return unless _arch_is_superset($self->{arches}, $o->{arches});
396 # The arch qualifier must not forbid an implication
397 return unless _arch_qualifier_implies($self->{archqual},
398 $o->{archqual});
400 # Our restrictions must imply the restrictions for o
401 return unless _restrictions_imply($self->{restrictions},
402 $o->{restrictions});
404 # If o has no version clause, then our dependency is stronger
405 return 1 if not defined $o->{relation};
406 # If o has a version clause, we must also have one, otherwise there
407 # can't be an implication
408 return if not defined $self->{relation};
410 return Dpkg::Deps::deps_eval_implication($self->{relation},
411 $self->{version}, $o->{relation}, $o->{version});
412 } elsif ($o->isa('Dpkg::Deps::AND')) {
413 # TRUE: Need to imply all individual elements
414 # FALSE: Need to NOT imply at least one individual element
415 my $res = 1;
416 foreach my $dep ($o->get_deps()) {
417 my $implication = $self->implies($dep);
418 unless (defined $implication and $implication == 1) {
419 $res = $implication;
420 last if defined $res;
423 return $res;
424 } elsif ($o->isa('Dpkg::Deps::OR')) {
425 # TRUE: Need to imply at least one individual element
426 # FALSE: Need to not apply all individual elements
427 # UNDEF: The rest
428 my $res = undef;
429 foreach my $dep ($o->get_deps()) {
430 my $implication = $self->implies($dep);
431 if (defined $implication) {
432 if (not defined $res) {
433 $res = $implication;
434 } else {
435 if ($implication) {
436 $res = 1;
437 } else {
438 $res = 0;
441 last if defined $res and $res == 1;
444 return $res;
445 } else {
446 croak 'Dpkg::Deps::Simple cannot evaluate implication with a ' .
447 ref($o);
451 =item $dep->get_deps()
453 Returns a list of sub-dependencies, which for this object it means it
454 returns itself.
456 =cut
458 sub get_deps {
459 my $self = shift;
461 return $self;
464 =item $dep->sort()
466 This method is a no-op for this object.
468 =cut
470 sub sort {
471 # Nothing to sort
474 =item $dep->arch_is_concerned($arch)
476 Returns true if the dependency applies to the indicated architecture.
478 =cut
480 sub arch_is_concerned {
481 my ($self, $host_arch) = @_;
483 return 0 if not defined $self->{package}; # Empty dep
484 return 1 if not defined $self->{arches}; # Dep without arch spec
486 return debarch_is_concerned($host_arch, @{$self->{arches}});
489 =item $dep->reduce_arch($arch)
491 Simplifies the dependency to contain only information relevant to the given
492 architecture. This object can be left empty after this operation. This trims
493 off the architecture restriction list of these objects.
495 =cut
497 sub reduce_arch {
498 my ($self, $host_arch) = @_;
500 if (not $self->arch_is_concerned($host_arch)) {
501 $self->reset();
502 } else {
503 $self->{arches} = undef;
507 =item $dep->has_arch_restriction()
509 Returns the package name if the dependency applies only to a subset of
510 architectures.
512 =cut
514 sub has_arch_restriction {
515 my $self = shift;
517 if (defined $self->{arches}) {
518 return $self->{package};
519 } else {
520 return ();
524 =item $dep->profile_is_concerned()
526 Returns true if the dependency applies to the indicated profile.
528 =cut
530 sub profile_is_concerned {
531 my ($self, $build_profiles) = @_;
533 return 0 if not defined $self->{package}; # Empty dep
534 return 1 if not defined $self->{restrictions}; # Dep without restrictions
535 return evaluate_restriction_formula($self->{restrictions}, $build_profiles);
538 =item $dep->reduce_profiles()
540 Simplifies the dependency to contain only information relevant to the given
541 profile. This object can be left empty after this operation. This trims off
542 the profile restriction list of this object.
544 =cut
546 sub reduce_profiles {
547 my ($self, $build_profiles) = @_;
549 if (not $self->profile_is_concerned($build_profiles)) {
550 $self->reset();
551 } else {
552 $self->{restrictions} = undef;
556 =item $dep->get_evaluation($facts)
558 Evaluates the dependency given a list of installed packages and a list of
559 virtual packages provided. These lists are part of the Dpkg::Deps::KnownFacts
560 object given as parameters.
562 Returns 1 when it's true, 0 when it's false, undef when some information
563 is lacking to conclude.
565 =cut
567 sub get_evaluation {
568 my ($self, $facts) = @_;
570 return if not defined $self->{package};
571 return $facts->evaluate_simple_dep($self);
574 =item $dep->simplify_deps($facts, @assumed_deps)
576 Simplifies the dependency as much as possible given the list of facts (see
577 class Dpkg::Deps::KnownFacts) and a list of other dependencies that are
578 known to be true.
580 =cut
582 sub simplify_deps {
583 my ($self, $facts) = @_;
585 my $eval = $self->get_evaluation($facts);
586 $self->reset() if defined $eval and $eval == 1;
589 =item $dep->is_empty()
591 Returns true if the dependency is empty and doesn't contain any useful
592 information. This is true when the object has not yet been initialized.
594 =cut
596 sub is_empty {
597 my $self = shift;
599 return not defined $self->{package};
602 =item $dep->merge_union($other_dep)
604 Returns true if $dep could be modified to represent the union of both
605 dependencies. Otherwise returns false.
607 =cut
609 sub merge_union {
610 my ($self, $o) = @_;
612 return 0 if not $o->isa('Dpkg::Deps::Simple');
613 return 0 if $self->is_empty() or $o->is_empty();
614 return 0 if $self->{package} ne $o->{package};
615 return 0 if defined $self->{arches} or defined $o->{arches};
617 if (not defined $o->{relation} and defined $self->{relation}) {
618 # Union is the non-versioned dependency
619 $self->{relation} = undef;
620 $self->{version} = undef;
621 return 1;
624 my $implication = $self->implies($o);
625 my $rev_implication = $o->implies($self);
626 if (defined $implication) {
627 if ($implication) {
628 $self->{relation} = $o->{relation};
629 $self->{version} = $o->{version};
630 return 1;
631 } else {
632 return 0;
635 if (defined $rev_implication) {
636 if ($rev_implication) {
637 # Already merged...
638 return 1;
639 } else {
640 return 0;
643 return 0;
646 =back
648 =head1 CHANGES
650 =head2 Version 1.02 (dpkg 1.17.10)
652 New methods: Add $dep->profile_is_concerned() and $dep->reduce_profiles().
654 =head2 Version 1.01 (dpkg 1.16.1)
656 New method: Add $dep->reset().
658 New property: recognizes the arch qualifier "any" and stores it in the
659 "archqual" property when present.
661 =head2 Version 1.00 (dpkg 1.15.6)
663 Mark the module as public.
665 =cut