|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package lib::archive;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
342567
 | 
 use strict;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
    | 
| 
4
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
14
 | 
 use warnings;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
46
 | 
 use 5.010001;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
13
 | 
 use Carp qw(croak);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
175
 | 
    | 
| 
9
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1834
 | 
 use Archive::Tar;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
262024
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
233
 | 
    | 
| 
10
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1690
 | 
 use File::Spec::Functions qw(file_name_is_absolute rel2abs);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2234
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185
 | 
    | 
| 
11
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
19
 | 
 use File::Basename qw(dirname fileparse);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2925
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = "0.7";  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 lib::archive - load pure-Perl modules directly from TAR archives  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use lib::archive ("../external/*.tgz", "lib/extra.tar");  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use MyModule; # the given tar archives will be searched first  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use lib::archive qw(  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     https://www.cpan.org/modules/by-module/JSON/JSON-PP-2.97001.tar.gz  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     CPAN://YAML-PP-0.007.tar.gz  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use JSON::PP;  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use YAML::PP;  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Specify TAR archives to directly load modules from. The TAR files will be  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 searched like include dirs. Globs are expanded, so you can use wildcards  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (not for URLs). If modules are present in more than one TAR archive, the  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 first one will be used.  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Relative paths will be interpreted as relative to the directory the  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 calling script or module resides in. So don't do a chdir() before using  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 lib::archive when you call your script with a relative path B use releative  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 paths for lib::archive.  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 B
 | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 extracted on the fly>.  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can use every file format Archive::Tar supports.  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If the archive contains a toplevel directory 'lib' the module search path  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will start there. Otherwise it will start from the root of the archive.  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If the archive is a gzipped TAR archive with the extension '.tar.gz' and the  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 archive contains a toplevel directory matching the archive name without the  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 extension the module search path starts with this directory. The above  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 rule for the subdirectory 'lib' applies from there. This means that e.g. for  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 'JSON-PP-2.97001.tar.gz' the modules will only be included from  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 'JSON-PP-2.97001/lib'.  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can use URLs for loading modules directly from CPAN. Either specify the  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 complete URL like:  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use lib::archive 'https://www.cpan.org/modules/by-module/JSON/JSON-PP-2.97001.tar.gz';  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or use a shortcut like:  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   use lib::archive 'CPAN://JSON-PP-2.97001.tar.gz';  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 which will do exactly the same thing (at least in most cases: there seem to  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 be modules without an entry under 'modules/by-module/'; in that  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 case you have to use an URL pointing to the file under 'authors/id').  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If the environment variable CPAN_MIRROR is set, it will be used instead of  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 'https://www.cpan.org'.  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 WHY  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 There are two use cases that motivated the creation of this module:  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item 1. bundling various self written modules as a versioned release  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item 2. quickly switching between different versions of a module for debugging purposes  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Thomas Kratz Etomk@cpan.orgE  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $cpan   = $ENV{CPAN_MIRROR} || 'https://www.cpan.org';  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $is_url = qr!^(?:CPAN|https?)://!;  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $tar    = Archive::Tar->new();  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub import {  | 
| 
103
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
26
 | 
     my $class = shift;  | 
| 
104
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     my %cache;  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     ( my $acdir = dirname( rel2abs( (caller)[1] ) ) ) =~ s!\\!/!g;  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
108
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
316
 | 
     for my $entry (@_) {  | 
| 
109
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
         my $is_url = $entry =~ /$is_url/;  | 
| 
110
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         my $arcs = $is_url ? _get_url($entry) : _get_files( $entry, $acdir );  | 
| 
111
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         for my $arc (@$arcs) {  | 
| 
112
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
247
 | 
             my $path = $is_url ? $entry : $arc->[0];  | 
| 
113
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
             my %tmp;  | 
| 
114
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             my $mod = 0;  | 
| 
115
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             my $lib = 0;  | 
| 
116
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
             for my $f ( $tar->read( $arc->[0] ) ) {  | 
| 
117
 | 
43
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
39286
 | 
                 next unless ( my $full = $f->full_path ) =~ /\.pm$/;  | 
| 
118
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
368
 | 
                 my @parts = split( '/', $full );  | 
| 
119
 | 
15
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
40
 | 
                 ++$mod && shift @parts if $parts[0] eq $arc->[1];  | 
| 
120
 | 
15
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
36
 | 
                 ++$lib && shift @parts if $parts[0] eq 'lib';  | 
| 
121
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
                 my $rel = join( '/', @parts );  | 
| 
122
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
                 $tmp{$rel}{$full} = $f->get_content_by_ref;  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
124
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
             for my $rel ( keys %tmp ) {  | 
| 
125
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
                 my $full = join( '/', $mod ? $arc->[1] : (), $lib ? 'lib' : (), $rel );  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
126
 | 
10
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
80
 | 
                 $cache{$rel} //= { path => "$path/$full", content => $tmp{$rel}{$full} };  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unshift @INC, sub {  | 
| 
131
 | 
28
 | 
 
 | 
 
 | 
  
28
  
 | 
 
 | 
196559
 | 
         my ( $cref, $rel ) = @_;  | 
| 
132
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10977
 | 
         return unless my $rec = $cache{$rel};  | 
| 
133
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
         $INC{$rel} = $rec->{path};  | 
| 
134
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
18
 | 
         open(my $fh, '<', $rec->{content});  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
    | 
| 
135
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2612
 | 
         return $fh;  | 
| 
136
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1705
 | 
     };  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_files {  | 
| 
141
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
6
 | 
     my ( $glob, $cdir ) = @_;  | 
| 
142
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     ( my $glob_ux = $glob ) =~ s!\\!/!g;  | 
| 
143
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     $glob_ux = "$cdir/$glob_ux" unless file_name_is_absolute($glob_ux);  | 
| 
144
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     my @files;  | 
| 
145
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
174
 | 
     for my $f ( sort glob($glob_ux) ) {  | 
| 
146
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
         my ( $module, $dirs, $suffix ) = fileparse( $f, qr/\.tar\.gz/ );  | 
| 
147
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
         push @files, [ $f, $module ];  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
149
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     return \@files;  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_url {  | 
| 
154
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
4
 | 
     my ($url) = @_;  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my ($module) = $url =~ m!/([^/]+)\.tar\.gz$!;  | 
| 
157
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my ($top) = split( /-/, $module );  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $url =~ s!^CPAN://!$cpan/modules/by-module/$top/!;  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     require HTTP::Tiny;  | 
| 
162
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     require IO::Uncompress::Gunzip;  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     my $rp = HTTP::Tiny->new->get($url);  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
166
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156948
 | 
     my @zips;  | 
| 
167
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
895
 | 
     if ( $rp->{success} ) {  | 
| 
168
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
         my $z = IO::Uncompress::Gunzip->new( \$rp->{content} );  | 
| 
169
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5966
 | 
         push @zips, [ $z, $module ];  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
172
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         croak "GET '$url' failed with status:", $rp->{status};  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
174
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     return \@zips;  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |