File Coverage

File:Dpkg/Deps/KnownFacts.pm
Coverage:83.3%

linestmtbrancondsubpodtimecode
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>
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 <https://www.gnu.org/licenses/>.
21
22=encoding utf8
23
24 - 33
=head1 NAME

Dpkg::Deps::KnownFacts - list of installed real and virtual packages

=head1 DESCRIPTION

This class represents a list of installed packages and a list of virtual
packages provided (by the set of installed packages).

=cut
34
35package Dpkg::Deps::KnownFacts 2.00;
36
37
12
12
12
63
9
402
use strict;
38
12
12
12
30
9
623
use warnings;
39
40
12
12
12
77
9
6638
use Dpkg::Version;
41
42 - 50
=head1 METHODS

=over 4

=item $facts = Dpkg::Deps::KnownFacts->new();

Creates a new object.

=cut
51
52sub new {
53
3
1
4
    my $this = shift;
54
3
11
    my $class = ref($this) || $this;
55
3
6
    my $self = {
56        pkg => {},
57        virtualpkg => {},
58    };
59
60
3
2
    bless $self, $class;
61
3
4
    return $self;
62}
63
64 - 74
=item $facts->add_installed_package($package, $version, $arch, $multiarch)

Records that the given version of the package is installed. If
$version/$arch is undefined we know that the package is installed but we
don't know which version/architecture it is. $multiarch is the Multi-Arch
field of the package. If $multiarch is undef, it will be equivalent to
"Multi-Arch: no".

Note that $multiarch is only used if $arch is provided.

=cut
75
76sub add_installed_package {
77
27
1
24
    my ($self, $pkg, $ver, $arch, $multiarch) = @_;
78
27
40
    my $p = {
79        package => $pkg,
80        version => $ver,
81        architecture => $arch,
82        multiarch => $multiarch // 'no',
83    };
84
85
27
41
    $self->{pkg}{"$pkg:$arch"} = $p if defined $arch;
86
27
27
14
38
    push @{$self->{pkg}{$pkg}}, $p;
87}
88
89 - 95
=item $facts->add_provided_package($virtual, $relation, $version, $by)

Records that the "$by" package provides the $virtual package. $relation
and $version correspond to the associated relation given in the Provides
field (if present).

=cut
96
97sub add_provided_package {
98
9
1
8
    my ($self, $pkg, $rel, $ver, $by) = @_;
99
9
23
    my $v = {
100        package => $pkg,
101        relation => $rel,
102        version => $ver,
103        provider => $by,
104    };
105
106
9
34
    $self->{virtualpkg}{$pkg} //= [];
107
9
9
5
15
    push @{$self->{virtualpkg}{$pkg}}, $v;
108}
109
110##
111## The functions below are private to Dpkg::Deps::KnownFacts.
112##
113
114sub _find_package {
115
168
153
    my ($self, $dep, $lackinfos) = @_;
116
168
182
    my ($pkg, $archqual) = ($dep->{package}, $dep->{archqual});
117
118
168
265
    return if not exists $self->{pkg}{$pkg};
119
120
33
76
    my $host_arch = $dep->{host_arch} // Dpkg::Arch::get_host_arch();
121
33
60
    my $build_arch = $dep->{build_arch} // Dpkg::Arch::get_build_arch();
122
123
33
33
18
41
    foreach my $p (@{$self->{pkg}{$pkg}}) {
124
33
29
        my $a = $p->{architecture};
125
33
28
        my $ma = $p->{multiarch};
126
127
33
30
        if (not defined $a) {
128
0
0
            $$lackinfos = 1;
129
0
0
            next;
130        }
131
33
43
        if (not defined $archqual) {
132
24
31
            return $p if $ma eq 'foreign';
133
15
42
            return $p if $a eq $host_arch or $a eq 'all';
134        } elsif ($archqual eq 'any') {
135
3
10
            return $p if $ma eq 'allowed';
136        } elsif ($archqual eq 'native') {
137
6
13
            return if $ma eq 'foreign';
138
3
17
            return $p if $a eq $build_arch or $a eq 'all';
139        } else {
140
0
0
            return $p if $a eq $archqual;
141        }
142    }
143
6
5
    return;
144}
145
146sub _find_virtual_packages {
147
144
133
    my ($self, $pkg) = @_;
148
149
144
177
    return () if not exists $self->{virtualpkg}{$pkg};
150
18
18
13
30
    return @{$self->{virtualpkg}{$pkg}};
151}
152
153 - 157
=item $facts->evaluate_simple_dep()

This method is private and should not be used except from within L<Dpkg::Deps>.

=cut
158
159sub evaluate_simple_dep {
160
168
1
135
    my ($self, $dep) = @_;
161
168
178
    my ($lackinfos, $pkg) = (0, $dep->{package});
162
163
168
197
    my $p = $self->_find_package($dep, \$lackinfos);
164
168
163
    if ($p) {
165
24
27
        if (defined $dep->{relation}) {
166
3
4
            if (defined $p->{version}) {
167                return 1 if version_compare_relation($p->{version},
168                                                     $dep->{relation},
169
3
4
                                                     $dep->{version});
170            } else {
171
0
0
                $lackinfos = 1;
172            }
173        } else {
174
21
27
            return 1;
175        }
176    }
177
144
148
    foreach my $virtpkg ($self->_find_virtual_packages($pkg)) {
178        next if defined $virtpkg->{relation} and
179
18
83
                $virtpkg->{relation} ne REL_EQ;
180
181
15
16
        if (defined $dep->{relation}) {
182
9
12
            next if not defined $virtpkg->{version};
183            return 1 if version_compare_relation($virtpkg->{version},
184                                                 $dep->{relation},
185
6
14
                                                 $dep->{version});
186        } else {
187
6
10
            return 1;
188        }
189    }
190
135
111
    return if $lackinfos;
191
135
148
    return 0;
192}
193
194=back
195
196 - 214
=head1 CHANGES

=head2 Version 2.00 (dpkg 1.20.0)

Remove method: $facts->check_package().

=head2 Version 1.01 (dpkg 1.16.1)

New option: $facts->add_installed_package() now accepts 2
supplementary parameters ($arch and $multiarch).

Deprecated method: $facts->check_package() is obsolete,
it should not have been part of the public API.

=head2 Version 1.00 (dpkg 1.15.6)

Mark the module as public.

=cut
215
2161;