File Coverage

blib/lib/CPAN/Perl/Releases/MetaCPAN.pm
Criterion Covered Total %
statement 15 67 22.3
branch 0 14 0.0
condition 0 5 0.0
subroutine 5 11 45.4
pod 0 5 0.0
total 20 102 19.6


line stmt bran cond sub pod time code
1             package CPAN::Perl::Releases::MetaCPAN;
2 1     1   67945 use strict;
  1         2  
  1         25  
3 1     1   5 use warnings;
  1         2  
  1         32  
4              
5             our $VERSION = '0.005';
6 1     1   605 use JSON::PP ();
  1         13593  
  1         26  
7 1     1   465 use HTTP::Tinyish;
  1         801  
  1         29  
8              
9 1     1   6 use Exporter 'import';
  1         2  
  1         768  
10             our @EXPORT_OK = qw(perl_tarballs perl_versions perl_pumpkins);
11              
12             sub new {
13 0     0 0   my ($class, %option) = @_;
14 0   0       my $uri = $option{uri} || "https://fastapi.metacpan.org/v1/release";
15 0           $uri =~ s{/$}{};
16 0 0         my $cache = exists $option{cache} ? $option{cache} : 1;
17 0           my $http = HTTP::Tinyish->new(verify_SSL => 1, agent => __PACKAGE__ . "/$VERSION");
18 0           my $json = JSON::PP->new->canonical(1);
19 0           bless { uri => $uri, http => $http, cache => $cache, json => $json }, $class;
20             }
21              
22             sub get {
23 0     0 0   my $self = shift;
24 0 0 0       return $self->{_releases} if $self->{cache} and $self->{_releases};
25              
26 0           my $uri = "$self->{uri}/_search";
27             # copy from
28             # https://github.com/metacpan/metacpan-web/blob/master/lib/MetaCPAN/Web/Model/API/Release.pm
29             # https://github.com/metacpan/metacpan-api/blob/master/lib/MetaCPAN/Document/Release/Set.pm
30 0           my $query = {
31             query => {
32             bool => {
33             must => [
34             { term => { distribution => "perl" } },
35             ],
36             },
37             },
38             size => 500,
39             sort => [ { date => 'desc' } ],
40             fields => [qw( name date author version status maturity authorized download_url )],
41             };
42             my $res = $self->{http}->post($uri, {
43 0           content => $self->{json}->encode($query),
44             headers => {
45             'content-type' => 'application/json',
46             }
47             });
48 0 0         die "$res->{status} $res->{reason}, $uri\n" unless $res->{success};
49 0           my $hash = $self->{json}->decode($res->{content});
50             my $releases = [
51 0           map { $_->{authorized} = 1; $_ }
  0            
52 0           grep { $_->{authorized} }
53 0           map { $_->{fields} }
54 0           @{$hash->{hits}{hits}}
  0            
55             ];
56 0 0         $self->{_releases} = $releases if $self->{cache};
57 0           $releases;
58             }
59              
60             sub _self {
61 0 0   0     my $self = eval { $_[0]->isa(__PACKAGE__) } ? shift : __PACKAGE__->new;
  0            
62 0 0         wantarray ? ($self, @_) : $self;
63             }
64              
65             sub perl_tarballs {
66 0     0 0   my ($self, $arg) = _self @_;
67 0           my $releases = $self->get;
68             my %tarballs =
69             map {
70 0           my $url = $_->{download_url};
71 0           $url =~ s{.*authors/id/}{};
72 0 0         if ($url =~ /\.(tar\.\S+)$/) {
73 0           ($1, $url);
74             } else {
75 0           ();
76             }
77             }
78 0           grep { my $name = $_->{name}; $name =~ s/^perl-?//; $name eq $arg }
  0            
  0            
79 0           grep { $_->{status} =~ /^(?:cpan|latest)$/ }
  0            
80             @$releases;
81 0           \%tarballs;
82             }
83              
84             sub perl_versions {
85 0     0 0   my $self = _self @_;
86 0           my $releases = $self->get;
87             my @versions =
88 0           map { my $name = $_->{name}; $name =~ s/^perl-?//; $name }
  0            
  0            
89 0           grep { $_->{status} =~ /^(?:cpan|latest)$/ }
  0            
90             @$releases;
91 0           @versions;
92             }
93              
94             sub perl_pumpkins {
95 0     0 0   my $self = _self @_;
96 0           my $releases = $self->get;
97             my %author =
98 0           map { $_->{author} => 1 }
99 0           grep { $_->{status} =~ /^(?:cpan|latest)$/ }
  0            
100             @$releases;
101 0           sort keys %author;
102             }
103              
104             1;
105             __END__