File Coverage

blib/lib/Github/ReleaseFetcher.pm
Criterion Covered Total %
statement 52 56 92.8
branch 13 24 54.1
condition 5 13 38.4
subroutine 9 9 100.0
pod 1 1 100.0
total 80 103 77.6


line stmt bran cond sub pod time code
1             package Github::ReleaseFetcher 1.001;
2              
3 1     1   290148 use strict;
  1         3  
  1         40  
4 1     1   8 use warnings;
  1         2  
  1         97  
5              
6             # ABSTRACT: Fetch either the latest or a particular named version of a file in a release from github
7 1     1   35 use 5.006;
  1         5  
8 1     1   12 use v5.14.0; # Before 5.006, v5.10.0 would not be understood.
  1         4  
9              
10 1     1   655 use Carp::Always;
  1         1042  
  1         5  
11 1     1   98 use HTTP::Tiny();
  1         3  
  1         39  
12 1     1   615 use HTML::TreeBuilder::Select();
  1         104396  
  1         39  
13 1     1   11 use File::Basename qw{basename};
  1         2  
  1         713  
14              
15              
16             our $BASE_URI = "http://github.com";
17              
18             sub fetch {
19 3     3 1 322381 my ( $outdir, $owner, $project, $search, $rename, $version, $ua ) = @_;
20              
21 3 50 33     14 die "Must pass outdir that exists" if $outdir && !-d $outdir;
22 3 50       7 die "Must pass owner" unless $owner;
23 3 50       10 die "Must pass project" unless $owner;
24              
25 3   50     16 $outdir //= "";
26              
27 3   50     10 $version //= 'latest';
28 3         8 my $index = "$BASE_URI/$owner/$project/releases/$version";
29              
30 3   33     29 $ua //= HTTP::Tiny->new();
31 3         331 my $res;
32              
33             # Figure out *what* the latest version number is.
34 3 50       10 if ( $version eq 'latest' ) {
35 3         101 my $res = $ua->get($index);
36 3 100       23457 die "$res->{reason} :\n$res->{content}\n" unless $res->{success};
37              
38             #Snag the url we were redirected to, as this is the actual version
39 2         99 $version = basename( $res->{url} );
40             }
41 2         7 $index = "$BASE_URI/$owner/$project/releases/expanded_assets/$version";
42 2         75 $res = $ua->get($index);
43 2 100       3032 die "$res->{reason} :\n$res->{content}\n" unless $res->{success};
44              
45 1         24 my $parsed = HTML::TreeBuilder::Select->new_from_content( $res->{content} );
46             my @matches =
47 10         22 map { $_->[0][0] }
48 10 50       285 grep { ref $_ eq "ARRAY" && ref $_->[0] eq "ARRAY"; }
49 1         31960 map { $_->extract_links() } $parsed->select('a');
  10         16322  
50 1 50       9 @matches = grep { $_ =~ $search } @matches if $search;
  0         0  
51              
52             my %names = map {
53 1         18 my $subj = $_;
  10         18  
54 10   33     451 my $name = $rename // basename($subj);
55 10         45 "$BASE_URI/$subj" => "$outdir/$name"
56             } @matches;
57              
58 1         14 foreach my $to_write ( reverse sort keys %names ) {
59 10 50       25 $ua->mirror( $to_write, $names{$to_write} ) if $outdir;
60 10 50       22 last if $rename;
61             }
62              
63 1 50       168 return keys(%names) unless $outdir;
64              
65 0           my @written = values(%names);
66 0 0         return pop(@written) if $rename;
67 0           return @written;
68             }
69              
70             1;
71              
72             __END__