File Coverage

blib/lib/Module/AutoLoad.pm
Criterion Covered Total %
statement 92 114 80.7
branch 31 70 44.2
condition 3 10 30.0
subroutine 10 10 100.0
pod 0 5 0.0
total 136 209 65.0


line stmt bran cond sub pod time code
1             package Module::AutoLoad;
2              
3 2     2   1432057 use strict;
  2         13  
  2         51  
4 2     2   9 use warnings;
  2         3  
  2         48  
5 2     2   10 use base qw(Exporter);
  2         3  
  2         3669  
6              
7             our $VERSION = '0.06';
8              
9             our $last_fetched = "";
10             our $lib = "lib";
11              
12             sub import {
13 2 50   2   55 warn "Congratulations! Module::AutoLoad has been loaded.\n" if $ENV{AUTOLOAD_DEBUG};
14 2 50       6 $lib = $ENV{AUTOLOAD_LIB} if $ENV{AUTOLOAD_LIB};
15 2 50       9 if ($lib =~ m{^[^/]}) {
16 2         7 eval {
17 2         11 require Cwd;
18 2         48 $lib = Cwd::abs_path($lib);
19             };
20             }
21 2         32 push @INC, $lib, \&inc;
22             }
23              
24             sub mkbase {
25 3     3 0 7 my $path = shift;
26 3 50       26 if ($path =~ s{/+[^/]*$ }{}x) {
27 3 100       52 return 1 if -d $path;
28             }
29 1 50       9 die "$path: Not a directory\n" if lstat $path;
30 1 50       4 if (mkbase($path)) {
31 1 50       4 warn "DEBUG: mkbase: Creating [$path] ...\n" if $ENV{AUTOLOAD_DEBUG};
32 1         91 return mkdir $path, 0755;
33             }
34 0         0 return 0;
35             }
36              
37             sub fetch {
38 3     3 0 7 my $url = shift;
39 3   50     16 my $recurse = shift || {};
40 3 50       17 $url = full($url) unless $url =~ m{^\w+://};
41 3         98 my $contents = get url $url;
42 3         119990 $last_fetched = $url;
43 3 50       39 if ($contents =~ m{The document has moved }) {
44 0         0 my $bounce = $1;
45 0 0 0     0 if ($recurse->{$bounce} && $recurse->{$bounce} > 2) {
46 0         0 return $contents;
47             }
48 0         0 $recurse->{$bounce}++;
49 0 0       0 return fetch($bounce, $recurse) if $recurse->{total}++<20;
50             }
51 3         25 return $contents;
52             }
53              
54             # full
55             # Turn a relative URL into a full URL
56             sub full {
57 2     2 0 8 my $rel = shift;
58 2 50 33     27 if ($rel =~ m{http://} || $last_fetched !~ m{^(http://[^/]+)(/?.*)}) {
59 0         0 return $rel;
60             }
61 2         8 my $h = $1;
62 2         9 my $p = $2;
63 2 100       11 if ($rel =~ m{^/}) {
64 1         4 return "$h$rel";
65             }
66 1         15 $p =~ s{[^/]*$ }{}x;
67 1         6 return "$h$p$rel";
68             }
69              
70             # fly
71             # Create a stub module to load the real file on-the-fly if needed.
72             sub fly {
73 1     1 0 4 my $inc = shift;
74 1         3 my $url = shift;
75 1         3 my $write = shift;
76 1 50       7 warn "DEBUG: Creating stub for [$inc] in order to download [$url] later if needed.\n" if $ENV{AUTOLOAD_DEBUG};
77 1         3 my $contents = q{
78             my $url = q{$URL};
79             my $myself = $INC{"$inc"} || __FILE__;
80             warn "DEBUG: Downloading [$url] right now ...\n" if $ENV{AUTOLOAD_DEBUG};
81             my $m = Module::AutoLoad::fetch($url);
82             if ($m =~ /package/) {
83             warn "DEBUG: Contents appear fine. Commencing BRICK OVER ...\n" if $ENV{AUTOLOAD_DEBUG};
84             if (open my $fh, ">", $myself) {
85             print $fh $m;
86             close $fh;
87             }
88             else {
89             warn "$myself: WARNING: Unable to repair! $!\n";
90             }
91             warn "DEBUG: Forcing re-evaluation of fresh module contents ...\n" if $ENV{AUTOLOAD_DEBUG};
92             my $e = eval $m;
93             if ($e) {
94             $INC{"$inc"} = $url;
95             $e;
96             }
97             else {
98             die "$url: $@\n";
99             }
100             }
101             else {
102             die "$url: STANKY! $m\n";
103             }
104             };
105 1         57 $contents =~ s/\s+/ /g;
106 1         41 $contents =~ s/([\;\{]+)\s+/$1\n/g;
107 1         9 $contents =~ s/^\s+//;
108 1         83 $contents =~ s/\s*$/\n/;
109             # Fake interpolation
110 1         9 $contents =~ s/\$URL/$url/g;
111 1         8 $contents =~ s/\$inc/$inc/g;
112 1 50       7 if ($write) {
113 1         6 mkbase($write);
114 1         18 $contents =~ s/(\$myself)\s*=.*?;/$1 = "$write";/;
115 1 50       125 open my $fh, ">", $write or die "$write: open: OUCH! $!";
116 1         10 print $fh $contents;
117 1         62 close $fh;
118             }
119 1         11 return $contents;
120             }
121              
122             sub inc {
123 1     1 0 450 my $i = shift;
124 1         2 my $f = shift;
125 1         2 my $cache_file = "$lib/$f";
126 1 50       10 if (-f $cache_file) {
127 0         0 warn "$cache_file: Broken module. Can't continue.\n";
128 0         0 return ();
129             }
130 1 50       4 mkbase($cache_file) or die "$cache_file: Unable to create! $!\n";
131 1 50       6 pop @INC if $INC[-1] eq \&botstrap::inc;
132              
133 1 50       6 if ($f =~ m{^([\w/]+)\.pm}) {
134 1         4 my $dist = $1;
135 1         2 my $mod = $1;
136 1         3 $f = "$1.pm";
137 1         3 $dist =~ s{/+}{-}g;
138 1         3 $mod =~ s{/+}{::}g;
139              
140 1   50     6 my $mapper = $ENV{AUTOLOAD_SRC} || "http://fastapi.metacpan.org/v1/release";
141 1         4 my $search = fetch("$mapper/$dist/");
142 1 50       10 warn "DEBUG: Probed: $last_fetched\n" if $ENV{AUTOLOAD_DEBUG};
143 1 50       23 if ($search =~ m{download_url.*?(\w+/[\w\d\-\.]+)\.tar.gz}) {
144 1         11 my $src = full("/source/$1/");
145 1 50       5 if (my $MANIFEST = fetch "$src/MANIFEST") {
146 1 50       17 $src = $1 if $last_fetched =~ m{^(.*?)/+MANIFEST};
147 1 50       9 if ($MANIFEST =~ m{^lib/}m) {
148 1 50       33 warn "DEBUG: YEY! Found a lib/ somewhere!\n" if $ENV{AUTOLOAD_DEBUG};
149 1         18 while ($MANIFEST =~ s{^lib/(\S+\.pm)}{ }m) {
150 1         5 my $remote = $1;
151 1 50       6 warn "DEBUG: MATCH [lib/$remote] RIPPED OUT\n" if $ENV{AUTOLOAD_DEBUG};
152 1         6 $last_fetched = "$src/MANIFEST";
153 1         6 my $cache = "$lib/$remote";
154 1 50       62 if (!-f $cache) {
155 1         9 my $full = full("lib/$remote");
156 1         6 fly($remote,$full,$cache);
157             }
158             }
159             }
160             else {
161 0 0       0 warn "DEBUG: Oh, too bad there is no magic lib folder in the MANIFEST [$MANIFEST]\n" if $ENV{AUTOLOAD_DEBUG};
162             }
163 1 50       26 if (!-f $cache_file) {
164             # Old versions of h2xs used to toss the end module right into the base folder?
165 0 0       0 if ($f =~ m{(\w+\.pm)}) {
166 0         0 my $stub = $1;
167 0 0       0 if ($MANIFEST =~ /^(.*$stub)$/m) {
168 0         0 my $stab = $1;
169 0         0 $last_fetched = "$src/MANIFEST";
170 0         0 $stab = full($stab);
171 0         0 fly($f, $stab, $cache_file);
172             }
173             else {
174 0 0       0 warn "WARNING: No [$stub] in $src/MANIFEST? [$MANIFEST]" if $ENV{AUTOLOAD_DEBUG};
175 0         0 die "No [$stub] in $src/MANIFEST";
176             }
177             }
178             else {
179 0         0 warn "WARNING: Unable to extract stub from file [$f] ??\n";
180             }
181             }
182             }
183             else {
184 0         0 warn "$src: Incomplete distribution! Broken MANIFEST file?\n";
185             }
186             }
187             }
188              
189 1 50       52 if (open my $fh, "<", $cache_file) {
190 1         8 $INC{$f} = $cache_file;
191 1         769 return $fh;
192             }
193              
194 0           return ();
195             }
196              
197             $INC{"Module/AutoLoad.pm"} ||= __FILE__;
198             # Dummy AutoLoad wrapper module for RCX Framework.
199             package AutoLoad;
200 2     2   14 use base qw(Module::AutoLoad);
  2         3  
  2         243  
201              
202             $INC{"AutoLoad.pm"} ||= __FILE__;
203              
204             1;
205             __END__