File Coverage

blib/lib/Alien/Build/Plugin/Fetch/Cache.pm
Criterion Covered Total %
statement 59 73 80.8
branch 13 24 54.1
condition 4 15 26.6
subroutine 12 13 92.3
pod 1 1 100.0
total 89 126 70.6


line stmt bran cond sub pod time code
1             package Alien::Build::Plugin::Fetch::Cache;
2              
3 1     1   266047 use strict;
  1         9  
  1         32  
4 1     1   6 use warnings;
  1         2  
  1         36  
5 1     1   26 use 5.010001;
  1         3  
6 1     1   442 use Alien::Build::Plugin;
  1         11214  
  1         7  
7 1     1   710 use URI 1.71;
  1         4345  
  1         42  
8 1     1   11 use Path::Tiny 0.100 ();
  1         21  
  1         24  
9 1     1   610 use Sereal 3.015 qw( encode_sereal decode_sereal );
  1         896  
  1         58  
10 1     1   7 use Digest::MD5;
  1         3  
  1         31  
11 1     1   7 use File::Glob qw( bsd_glob );
  1         2  
  1         762  
12              
13             # ABSTRACT: Alien::Build plugin to cache files downloaded from the internet
14             our $VERSION = '0.05'; # VERSION
15              
16              
17             sub _local_file
18             {
19 7     7   19 my($uri) = @_;
20              
21 7         383 Path::Tiny
22             ->new(bsd_glob '~/.alienbuild/plugin_fetch_cache')
23             ->child($uri->scheme)
24             ->child($uri->host)
25             ->child($uri->path)
26             ->child('meta');
27             }
28              
29             sub init
30             {
31 1     1 1 49578 my($self, $meta) = @_;
32              
33             $meta->around_hook(
34             fetch => sub {
35 7     7   48731 my($orig, $build, $url) = @_;
36 7         18 my $local_file;
37              
38 7   66     35 my $cache_url = $url // $build->meta_prop->{start_url};
39              
40 7 50 33     90 if($cache_url && $cache_url !~ m!^/! && $cache_url !~ m!^file:!)
      33        
41             {
42 7         77 my $uri = URI->new($cache_url);
43 7         9130 $local_file = _local_file($uri);
44 7 100       1788 if(-r $local_file)
45             {
46 4         122 $build->log("using cached response for $uri");
47 4         1846 return decode_sereal($local_file->slurp_raw);
48             }
49             }
50 3         103 my $res = $orig->($build, $url);
51              
52 3 50       87 if(defined $local_file)
53             {
54 3         18 $local_file->parent->mkpath;
55 3 100       1480 if($res->{type} eq 'file')
    50          
56             {
57 2         52 my $md5 = Digest::MD5->new;
58              
59 2 100       9 if($res->{content})
60             {
61 1         8 $md5->add($res->{content});
62             }
63             else
64             {
65 1         42 open my $fh, '<', $res->{path};
66 1         77 $md5->addfile($fh);
67 1         42 close $fh;
68             }
69              
70             my $data = Path::Tiny->new(bsd_glob '~/.alienbuild/plugin_fetch_cache/payload')
71             ->child($md5->hexdigest)
72 2         58 ->child($res->{filename});
73 2         174 $data->parent->mkpath;
74              
75             my $res2 = {
76             type => 'file',
77             filename => $res->{filename},
78             path => $data->stringify,
79             protocol => $res->{protocol},
80 2         476 };
81 2 100       20 if($res->{content})
    50          
82             {
83 1         6 $data->spew_raw($res->{content});
84             }
85             elsif($res->{path})
86             {
87 1         6 Path::Tiny->new($res->{path})->copy($data);
88             }
89             else
90             {
91 0         0 die "got a file without contant or path";
92             }
93 2         4255 $local_file->spew_raw( encode_sereal $res2 );
94             }
95             elsif($res->{type} =~ /^(list|html|dir_listing)$/)
96             {
97 1         42 $local_file->spew_raw( encode_sereal $res );
98             }
99             }
100              
101 3         1561 $res;
102             }
103 1         12 );
104              
105 1 50       15 if($ENV{ALIEN_BUILD_PLUGIN_FETCH_CACHE_PRECACHE})
106             {
107             $meta->around_hook(
108             prefer => sub {
109 0     0     my($orig, $build, @rest) = @_;
110 0           my $ret = $orig->($build, @rest);
111              
112 0 0         if($ret->{type} eq 'list')
113             {
114 0           foreach my $file (@{ $ret->{list} })
  0            
115             {
116 0           my $url = $file->{url};
117 0 0 0       if($url && $url !~ m!^/! && $url !~ m!^file:!)
      0        
118             {
119 0           my $local_file = _local_file(URI->new($url));
120 0 0         next if -f $local_file;
121 0           $build->log("precacheing $url");
122 0           $build->fetch($url);
123             }
124             }
125             }
126 0           $ret;
127             },
128 0           );
129             }
130             }
131              
132              
133             1;
134              
135             __END__