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   80889 use strict;
  14         20  
  14         421  
3 14     14   61 use warnings;
  14         16  
  14         583  
4 14     14   416 use CPAN::Audit::Version;
  14         19  
  14         4799  
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 129029 my($class, %params) = @_;
37 9   50     43 $params{db} ||= {};
38 9         33 my $self = bless {}, $class;
39 9         39 $self->{db} = $params{db};
40 9         30 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 161     161 1 254 my( $self, $distname, $dist_version_range ) = @_;
63              
64 161 100 100     515 $dist_version_range = '>0' unless
65             defined $dist_version_range && 0 < length $dist_version_range;
66              
67 161         382 my $dist = $self->{db}->{dists}->{$distname};
68 161 100       356 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 20489         28571 map { $_->{id}, $_ }
76             map {
77 3521         4070 my $dist_version = $_;
78             grep {
79 42896         53882 my $affected = _includes( $_->{affected_versions}, $dist_version );
80 42896         48071 my $f = $_->{fixed_versions};
81 42896 100 66     122530 if( exists $_->{fixed_versions} and defined $f and length $f ) {
      66        
82 42880         50401 my $fixed = _includes( $f, $dist_version );
83 42880 100       66070 $fixed ? 0 : $affected
84             }
85 16         24 else { $affected }
86 3521         3327 } @{ $dist->{advisories} };
  3521         8844  
87             }
88 20297         27295 grep { CPAN::Audit::Version->in_range( $_, $dist_version_range ) }
89 20297         25704 map { $_->{version} }
90 160         182 @{ $dist->{versions} };
  160         501  
91              
92 160         4218 values %advisories;
93             }
94              
95             sub _includes {
96 85776     85776   98552 my( $range, $version ) = @_;
97 85776 100       105446 $range = [$range] unless ref $range;
98 85776         77702 my $rc = 0;
99 85776         88818 foreach my $r ( @$range ) {
100 14     14   125 no warnings 'uninitialized';
  14         26  
  14         1136  
101 81934         115639 $rc += CPAN::Audit::Version->in_range( $version, $r );
102             }
103 85776         94621 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;