File Coverage

lib/CPAN/Audit/Query.pm
Criterion Covered Total %
statement 42 42 100.0
branch 10 10 100.0
condition 8 11 72.7
subroutine 7 7 100.0
pod 2 2 100.0
total 69 72 95.8


line stmt bran cond sub pod time code
1             package CPAN::Audit::Query;
2 14     14   134516 use strict;
  14         27  
  14         594  
3 14     14   75 use warnings;
  14         26  
  14         693  
4 14     14   611 use CPAN::Audit::Version;
  14         27  
  14         6924  
5              
6             our $VERSION = "1.002";
7              
8             =encoding utf8
9              
10             =head1 NAME
11              
12             CPAN::Audit::Query - filter the database for advisories that interest you
13              
14             =head1 SYNOPSIS
15              
16             use CPAN::Audit::Query;
17              
18             my $query = CPAN::Audit::Query->new( db => ... );
19             my @advisories = $query->advisories_for( $dist_name, $version_range );
20              
21             =head1 DESCRIPTION
22              
23             =head2 Class methods
24              
25             =over 4
26              
27             =item * new(HASH)
28              
29             The only parameter is the hash reference from L (deprecated) or
30             L. With no C parameter, it uses the empty hash,
31             which means that you'll find no advisories.
32              
33             =cut
34              
35             sub new {
36 9     9 1 232907 my($class, %params) = @_;
37 9   50     37 $params{db} ||= {};
38 9         24 my $self = bless {}, $class;
39 9         49 $self->{db} = $params{db};
40 9         34 return $self;
41             }
42              
43             =back
44              
45             =head2 Instance methods
46              
47             =over 4
48              
49             =item * advisories_for( DISTNAME, VERSION_RANGE )
50              
51             Returns a list of advisories for DISTNAME in VERSION_RANGE.
52              
53             my @advisories = $query->advisories_for( 'Business::ISBN', '1.23' );
54              
55             my @advisories = $query->advisories_for( 'Business::ISBN', '>1.23,<2.45' );
56              
57             my @advisories = $query->advisories_for( 'Business::ISBN', '<1.23' );
58              
59             =cut
60              
61             sub advisories_for {
62 155     155 1 357 my( $self, $distname, $dist_version_range ) = @_;
63              
64 155 100 100     624 $dist_version_range = '>0' unless
65             defined $dist_version_range && 0 < length $dist_version_range;
66              
67 155         636 my $dist = $self->{db}->{dists}->{$distname};
68 155 100       395 return unless $dist;
69              
70             # select only the known distribution versions from the database,
71             # ignoring all others. For example, if $dist_version_range is
72             # ">5.1", we don't care about any versions less than or equal to 5.1.
73             # If $dist_version_range is "5.1", that really means ">=5.1"
74             my %advisories =
75 20142         44640 map { $_->{id}, $_ }
76             map {
77 3410         5592 my $dist_version = $_;
78             grep {
79 43658         84071 my $affected = _includes( $_->{affected_versions}, $dist_version );
80 43658         76166 my $f = $_->{fixed_versions};
81 43658 100 66     195414 if( exists $_->{fixed_versions} and defined $f and length $f ) {
      66        
82 43642         73229 my $fixed = _includes( $f, $dist_version );
83 43642 100       103015 $fixed ? 0 : $affected
84             }
85 16         25 else { $affected }
86 3410         4397 } @{ $dist->{advisories} };
  3410         7617  
87             }
88 19408         40276 grep { CPAN::Audit::Version->in_range( $_, $dist_version_range ) }
89 19408         38073 map { $_->{version} }
90 154         238 @{ $dist->{versions} };
  154         640  
91              
92 154         7125 values %advisories;
93             }
94              
95             sub _includes {
96 87300     87300   139795 my( $range, $version ) = @_;
97 87300 100       158801 $range = [$range] unless ref $range;
98 87300         112495 my $rc = 0;
99 87300         133541 foreach my $r ( @$range ) {
100 14     14   108 no warnings 'uninitialized';
  14         41  
  14         1537  
101 83300         189117 $rc += CPAN::Audit::Version->in_range( $version, $r );
102             }
103 87300         165020 return $rc;
104             }
105              
106             =back
107              
108             =head1 LICENSE
109              
110             Copyright (C) Viacheslav Tykhanovskyi.
111              
112             This library is free software; you can redistribute it and/or modify
113             it under the same terms as Perl itself.
114              
115             =head1 AUTHOR
116              
117             Viacheslav Tykhanovskyi Eviacheslav.t@gmail.comE
118              
119             =cut
120              
121             1;