test: Move test_data_file() to test.h
[dpkg.git] / scripts / Dpkg / Deps / KnownFacts.pm
blob5ef7e7c69b06a90b9b8443f5196afe307d7ce5ef
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::KnownFacts - list of installed real and virtual packages
28 =head1 DESCRIPTION
30 This class represents a list of installed packages and a list of virtual
31 packages provided (by the set of installed packages).
33 =cut
35 package Dpkg::Deps::KnownFacts 2.00;
37 use strict;
38 use warnings;
40 use Dpkg::Version;
42 =head1 METHODS
44 =over 4
46 =item $facts = Dpkg::Deps::KnownFacts->new();
48 Creates a new object.
50 =cut
52 sub new {
53 my $this = shift;
54 my $class = ref($this) || $this;
55 my $self = {
56 pkg => {},
57 virtualpkg => {},
60 bless $self, $class;
61 return $self;
64 =item $facts->add_installed_package($package, $version, $arch, $multiarch)
66 Records that the given version of the package is installed. If
67 $version/$arch is undefined we know that the package is installed but we
68 don't know which version/architecture it is. $multiarch is the Multi-Arch
69 field of the package. If $multiarch is undef, it will be equivalent to
70 "Multi-Arch: no".
72 Note that $multiarch is only used if $arch is provided.
74 =cut
76 sub add_installed_package {
77 my ($self, $pkg, $ver, $arch, $multiarch) = @_;
78 my $p = {
79 package => $pkg,
80 version => $ver,
81 architecture => $arch,
82 multiarch => $multiarch // 'no',
85 $self->{pkg}{"$pkg:$arch"} = $p if defined $arch;
86 push @{$self->{pkg}{$pkg}}, $p;
89 =item $facts->add_provided_package($virtual, $relation, $version, $by)
91 Records that the "$by" package provides the $virtual package. $relation
92 and $version correspond to the associated relation given in the Provides
93 field (if present).
95 =cut
97 sub add_provided_package {
98 my ($self, $pkg, $rel, $ver, $by) = @_;
99 my $v = {
100 package => $pkg,
101 relation => $rel,
102 version => $ver,
103 provider => $by,
106 $self->{virtualpkg}{$pkg} //= [];
107 push @{$self->{virtualpkg}{$pkg}}, $v;
111 ## The functions below are private to Dpkg::Deps::KnownFacts.
114 sub _find_package {
115 my ($self, $dep, $lackinfos) = @_;
116 my ($pkg, $archqual) = ($dep->{package}, $dep->{archqual});
118 return if not exists $self->{pkg}{$pkg};
120 my $host_arch = $dep->{host_arch} // Dpkg::Arch::get_host_arch();
121 my $build_arch = $dep->{build_arch} // Dpkg::Arch::get_build_arch();
123 foreach my $p (@{$self->{pkg}{$pkg}}) {
124 my $a = $p->{architecture};
125 my $ma = $p->{multiarch};
127 if (not defined $a) {
128 $$lackinfos = 1;
129 next;
131 if (not defined $archqual) {
132 return $p if $ma eq 'foreign';
133 return $p if $a eq $host_arch or $a eq 'all';
134 } elsif ($archqual eq 'any') {
135 return $p if $ma eq 'allowed';
136 } elsif ($archqual eq 'native') {
137 return if $ma eq 'foreign';
138 return $p if $a eq $build_arch or $a eq 'all';
139 } else {
140 return $p if $a eq $archqual;
143 return;
146 sub _find_virtual_packages {
147 my ($self, $pkg) = @_;
149 return () if not exists $self->{virtualpkg}{$pkg};
150 return @{$self->{virtualpkg}{$pkg}};
153 =item $facts->evaluate_simple_dep()
155 This method is private and should not be used except from within Dpkg::Deps.
157 =cut
159 sub evaluate_simple_dep {
160 my ($self, $dep) = @_;
161 my ($lackinfos, $pkg) = (0, $dep->{package});
163 my $p = $self->_find_package($dep, \$lackinfos);
164 if ($p) {
165 if (defined $dep->{relation}) {
166 if (defined $p->{version}) {
167 return 1 if version_compare_relation($p->{version},
168 $dep->{relation},
169 $dep->{version});
170 } else {
171 $lackinfos = 1;
173 } else {
174 return 1;
177 foreach my $virtpkg ($self->_find_virtual_packages($pkg)) {
178 next if defined $virtpkg->{relation} and
179 $virtpkg->{relation} ne REL_EQ;
181 if (defined $dep->{relation}) {
182 next if not defined $virtpkg->{version};
183 return 1 if version_compare_relation($virtpkg->{version},
184 $dep->{relation},
185 $dep->{version});
186 } else {
187 return 1;
190 return if $lackinfos;
191 return 0;
194 =back
196 =head1 CHANGES
198 =head2 Version 2.00 (dpkg 1.20.0)
200 Remove method: $facts->check_package().
202 =head2 Version 1.01 (dpkg 1.16.1)
204 New option: Dpkg::Deps::KnownFacts->add_installed_package() now accepts 2
205 supplementary parameters ($arch and $multiarch).
207 Deprecated method: Dpkg::Deps::KnownFacts->check_package() is obsolete,
208 it should not have been part of the public API.
210 =head2 Version 1.00 (dpkg 1.15.6)
212 Mark the module as public.
214 =cut