File Coverage

lib/Haul.pm
Criterion Covered Total %
statement 85 145 58.6
branch 14 38 36.8
condition 2 14 14.2
subroutine 17 20 85.0
pod 5 7 71.4
total 123 224 54.9


line stmt bran cond sub pod time code
1             package Haul;
2 1     1   538 use strict;
  1         2  
  1         34  
3 1     1   5 use Cwd;
  1         3  
  1         57  
4 1     1   758 use CPAN::DistnameInfo;
  1         1046  
  1         31  
5 1     1   5 use File::Basename;
  1         1  
  1         62  
6 1     1   746 use File::Copy;
  1         2215  
  1         44  
7 1     1   5 use File::Path;
  1         1  
  1         47  
8 1     1   723 use IPC::Run3;
  1         42314  
  1         85  
9 1     1   1022 use Module::Depends::Intrusive;
  1         148114  
  1         18  
10 1     1   42 use vars qw($VERSION);
  1         3  
  1         1194  
11             $VERSION = '2.24';
12              
13             sub new {
14 1     1 1 778 my $class = shift;
15 1         2 my $self = {};
16 1         3 bless $self, $class;
17 1         5 $self->_init(@_);
18 1         24 return $self;
19             }
20              
21             sub fetch {
22 3     3 1 944 my $self = shift;
23 3         9 my $what = shift;
24 3         4 my $prefix;
25 3 50       12 if (exists $self->{modules}->{$what}) {
26 3         8 $prefix = $self->{modules}->{$what};
27             # } elsif (exists $self->{distributions}->{$what}) {
28             # $prefix = $self->{distributions}->{$what};
29             } else {
30 0         0 die "Could not find $what";
31             }
32 3         7 my $path = "authors/id/" . $prefix;
33 3         8 my $filename = $self->_fetch($path);
34 3         6 return $filename;
35             }
36              
37             sub extract {
38 2     2 1 2823 my $self = shift;
39 2         15 my $what = shift;
40 2         41 my $filename = $self->fetch($what);
41              
42 2         18 my $d = CPAN::DistnameInfo->new($filename);
43 2         144 my $dir = $d->distvname;
44              
45 2 50       51 return $dir if -d $dir;
46              
47 0 0 0     0 if ($filename =~ /\.tar\.gz$/ || $filename =~ /\.tgz$/) {
48 0         0 $self->_extract_aux("tar xzf ../$filename", $dir);
49             }
50              
51 0 0       0 die "failed to extract" unless -d $dir;
52 0         0 return $dir;
53             }
54              
55             sub _extract_aux {
56 0     0   0 my $self = shift;
57 0         0 my $command = shift;
58 0         0 my $dir = shift;
59              
60 0         0 mkdir "test";
61 0         0 chdir "test";
62 0         0 system($command);
63              
64 0         0 my @dirs = grep { -d $_ } <*>;
  0         0  
65 0         0 my @files = grep { -f $_ } <*>;
  0         0  
66 0 0       0 if (@files) {
67 0         0 chdir "..";
68 0         0 move("test", $dir);
69 0         0 return;
70             }
71 0 0       0 if (scalar(@dirs) == 1) {
72 0         0 move($dirs[0], "../$dir");
73 0         0 rmdir "test";
74 0         0 chdir "..";
75 0         0 return;
76             } else {
77 0         0 chdir "..";
78 0         0 move("test", $dir);
79 0         0 return;
80             }
81             }
82              
83             sub install {
84 0     0 1 0 my $self = shift;
85 0         0 my $what = shift;
86 0         0 my $dir = $self->extract($what);
87 0         0 my $perl = $self->perl;
88              
89 0         0 my $deps = Module::Depends::Intrusive->new->dist_dir($dir)->find_modules;
90 0         0 my $requires = $deps->requires;
91              
92 0         0 foreach my $module (keys %$requires) {
93 0         0 my $version = $requires->{$module};
94 0         0 my $installed = $self->installed($module);
95 0 0 0     0 next if defined $installed && $version <= $installed;
96             # warn "need to install $module ($version > $installed)";
97 0         0 $self->install($module);
98 0         0 $installed = $self->installed($module);
99 0 0 0     0 next if defined $installed && $version <= $installed;
100 0         0 die "failed to install $module";
101             }
102              
103 0         0 my $cwd = cwd;
104 0         0 chdir $dir;
105 0 0       0 if (-f "Makefile.PL") {
106 0         0 $self->run($perl, "Makefile.PL");
107 0         0 $self->run("make");
108 0         0 $self->run("make", "test");
109 0         0 $self->run("make", "install");
110 0         0 my $installed = $self->installed($what);
111 0 0       0 die "$what failed to install" unless $installed;
112             } else {
113 0         0 die "need code here to install $dir";
114             }
115 0         0 chdir $cwd;
116             }
117              
118             sub run {
119 0     0 0 0 my $self = shift;
120 0         0 my @commands = @_;
121 0         0 my($out, $err);
122             # warn "(@commands)\n";
123 0         0 run3 [@commands], \undef, \$out, \$err;
124             #warn "[STDERR: $err]\n";
125 0         0 return($out, $err);
126             }
127              
128             sub installed {
129 2     2 1 1360 my $self = shift;
130 2         7 my $module = shift;
131 2         8 my $perl = $self->perl;
132              
133 2         4 my $code;
134              
135 2 50       6 if ($module eq 'perl') {
136 0         0 $code = qq(print "VERSION IS $]\n");
137             } else {
138 2         8 $code = qq(use $module; print 'VERSION IS ' . \$${module}::VERSION . "\n");
139             }
140              
141 2         6 my $command = "$perl -e '$code'";
142              
143 2         3 my($in, $out, $err);
144 2         25 run3 [$perl, '-e', $code], \$in, \$out, \$err;
145              
146 2 100       54105 return if $err;
147 1         27 my($version) = $out =~ /VERSION IS (.+)\n/;
148 1   50     48 return $version || "0E0";
149             }
150              
151             sub _init {
152 1     1   2 my($self, %conf) = @_;
153              
154 1   33     8 $self->perl($conf{perl} || $^X);
155 1         3 $self->_parse_packages_details;
156             }
157              
158             sub perl {
159 3     3 0 24 my($self, $perl) = @_;
160 3 100       12 if (defined $perl) {
161 1 50       58 die "perl not at $perl" unless -f $perl;
162 1         6 $self->{perl} = $perl;
163             } else {
164 2         7 return $self->{perl};
165             }
166             }
167              
168             sub _parse_packages_details {
169 1     1   1 my $self = shift;
170 1         3 my $filename = $self->_fetch("modules/02packages.details.txt.gz");
171 1         14059 open(IN, "zcat $filename |");
172             # skip the header
173 1         11744 while(my $line = ) {
174 9 100       49 last if $line eq "\n";
175             }
176 1         24 while(my $line = ) {
177 146222         172548 chomp $line;
178 146222         372562 my($module, $moduleversion, $prefix) = split ' ', $line;
179 146222 50       254478 die "$line = $module/$moduleversion/$prefix" unless defined $prefix;
180 146222         872175 $self->{modules}->{$module} = $prefix;
181             # my $d = CPAN::DistnameInfo->new($prefix);
182             # my $dist = $d->dist;
183             # my $distversion = $d->version;
184             # my $distvname = $d->distvname;
185             # next unless $dist;
186             # next unless $distversion; # ignore stupid packages
187             # $self->{distributions}->{$dist} = $prefix;
188             }
189 1         45 close(IN);
190             }
191              
192             sub _fetch {
193 4     4   8 my $self = shift;
194 4         7 my $path = shift;
195 4         200 my $basename = basename($path);
196 4         8 my $url = "http://www.cpan.org/$path";
197              
198 4 50       15 if ($path =~ m{/perl-5\.}) {
199 0         0 die "do not install perl";
200             }
201              
202 4 50       62 unless (-f $basename) {
203 0         0 system("wget -N $url");
204             }
205 4 50       46 die "Error fetching $url" unless -f $basename;
206 4         10 return $basename;
207             }
208              
209             1;
210              
211             __END__