File Coverage

blib/lib/Perl/Dist/Util/Toolchain.pm
Criterion Covered Total %
statement 51 130 39.2
branch 7 34 20.5
condition 1 12 8.3
subroutine 14 22 63.6
pod 4 9 44.4
total 77 207 37.2


line stmt bran cond sub pod time code
1             package Perl::Dist::Util::Toolchain;
2              
3 2     2   700926 use 5.005;
  2         8  
  2         81  
4 2     2   12 use strict;
  2         5  
  2         58  
5 2     2   9 use Carp ();
  2         4  
  2         38  
6 2     2   919 use Params::Util qw{ _HASH _ARRAY };
  2         3684  
  2         151  
7 2     2   9513 use Module::CoreList ();
  2         259457  
  2         1184  
8 2     2   2378 use IO::Capture::Stdout ();
  2         5414  
  2         52  
9 2     2   60363 use IO::Capture::Stderr ();
  2         1602  
  2         51  
10 2     2   1960 use Process::Delegatable ();
  2         52715  
  2         47  
11 2     2   19 use Process::Storable ();
  2         5  
  2         30  
12 2     2   128434 use Process ();
  2         560  
  2         64  
13              
14 2     2   13 use vars qw{$VERSION @ISA @DELEGATE};
  2         3  
  2         286  
15             BEGIN {
16 2     2   5 $VERSION = '1.16';
17 2         59 @ISA = qw{
18             Process::Delegatable
19             Process::Storable
20             Process
21             };
22 2         4 @DELEGATE = ();
23              
24             # Automatically handle delegation within the test suite
25 2 50       16 if ( $ENV{HARNESS_ACTIVE} ) {
26 2         12 require Probe::Perl;
27 2         17 @DELEGATE = (
28             Probe::Perl->find_perl_interpreter, '-Mblib',
29             );
30             }
31             }
32              
33             my %MODULES = (
34             '5.008008' => [ qw{
35             ExtUtils::MakeMaker
36             File::Path
37             ExtUtils::Command
38             Win32API::File
39             ExtUtils::Install
40             ExtUtils::Manifest
41             Test::Harness
42             Test::Simple
43             ExtUtils::CBuilder
44             ExtUtils::ParseXS
45             version
46             Scalar::Util
47             Compress::Raw::Zlib
48             Compress::Raw::Bzip2
49             IO::Compress::Base
50             Compress::Bzip2
51             IO::Zlib
52             File::Spec
53             File::Temp
54             Win32::WinError
55             Win32API::Registry
56             Win32::TieRegistry
57             File::HomeDir
58             File::Which
59             Archive::Zip
60             Package::Constants
61             IO::String
62             Archive::Tar
63             Compress::unLZMA
64             Parse::CPAN::Meta
65             YAML
66             Net::FTP
67             Digest::MD5
68             Digest::SHA1
69             Digest::SHA
70             Module::Build
71             Term::Cap
72             CPAN
73             Term::ReadKey
74             Term::ReadLine::Perl
75             Text::Glob
76             Data::Dumper
77             URI
78             HTML::Tagset
79             HTML::Parser
80             LWP::UserAgent
81             } ],
82             );
83             $MODULES{'5.010000'} = $MODULES{'5.008008'};
84             $MODULES{'5.008009'} = $MODULES{'5.008008'};
85              
86             my %CORELIST = (
87             '5.008008' => '5.008008',
88             '5.008009' => '5.008008',
89             '5.010000' => '5.010000',
90             );
91              
92              
93              
94              
95              
96             #####################################################################
97             # Constructor and Accessors
98              
99             sub new {
100 1     1 1 109 my $class = shift;
101 1         6 my $self = bless { @_ }, $class;
102              
103             # Check the Perl version
104 1 50       6 unless ( defined $self->perl_version ) {
105 0         0 Carp::croak("Did not provide a perl_version param");
106             }
107 1 50       6 unless ( defined $self->{cpan} ) {
108 0         0 Carp::croak("Did not provide a cpan param");
109             }
110 1 50       3 unless ( $MODULES{$self->perl_version} ) {
111 0         0 Carp::croak("Perl version '" . $self->perl_version . "' is not supported in $class");
112             }
113 1 50       4 unless ( $CORELIST{$self->perl_version} ) {
114 0         0 Carp::croak("Perl version '" . $self->perl_version . "' is not supported in $class");
115             }
116              
117             # Populate the modules array if needed
118 1 50       9 unless ( _ARRAY($self->{modules}) ) {
119 0         0 $self->{modules} = $MODULES{$self->perl_version};
120             }
121              
122             # Confirm we can find the corelist for the Perl version
123 1         4 my $corelist_version = $CORELIST{$self->perl_version};
124 1   33     8 $self->{corelist} = $Module::CoreList::version{$corelist_version}
125             || $Module::CoreList::version{$corelist_version+0};
126 1 50       9 unless ( _HASH($self->{corelist}) ) {
127 1         4 Carp::croak("Failed to find module core versions for Perl " . $self->perl_version);
128             }
129              
130             # Check forced dists, if applicable
131 0 0 0     0 if ( $self->{force} and ! _HASH($self->{force}) ) {
132 0         0 Carp::croak("The force param must be a HASH reference");
133             }
134              
135             # Create the distribution array
136 0         0 $self->{dists} = [];
137              
138 0         0 return $self;
139             }
140              
141             sub perl_version {
142 5     5 0 658 $_[0]->{perl_version};
143             }
144              
145             sub modules {
146 0     0 0   @{$_[0]->{modules}};
  0            
147             }
148              
149             sub dists {
150 0     0 0   @{$_[0]->{dists}};
  0            
151             }
152              
153             sub errstr {
154 0     0 0   $_[0]->{errstr};
155             }
156              
157             sub prepare {
158 0     0 1   my $self = shift;
159              
160             # Squash all output that CPAN might spew during this process
161 0           my $stdout = IO::Capture::Stdout->new;
162 0           my $stderr = IO::Capture::Stderr->new;
163 0           $stdout->start;
164 0           $stderr->start;
165              
166             # Load the CPAN client
167 0           require CPAN;
168 0           CPAN->import();
169              
170             # Load the latest index
171 0           eval {
172 0     0     local $SIG{__WARN__} = sub { 1 };
  0            
173 0 0         CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
174 0           $CPAN::Config->{'urllist'} = [ $self->{cpan} ];
175 0           $CPAN::Config->{'use_sqlite'} = q[0];
176 0           CPAN::Index->reload;
177             };
178              
179 0           $stdout->stop;
180 0           $stderr->stop;
181              
182 0 0         return $@ ? '' : 1;
183             }
184              
185             sub run {
186 0     0 1   my $self = shift;
187              
188             # Squash all output that CPAN might spew during this process
189 0           my $stdout = IO::Capture::Stdout->new;
190 0           my $stderr = IO::Capture::Stderr->new;
191            
192             # Find the module
193 0           my $core = delete $self->{corelist};
194            
195 0           $stdout->start; $stderr->start;
  0            
196 0 0         CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
197 0           $CPAN::Config->{'urllist'} = [ $self->{cpan} ];
198 0           $CPAN::Config->{'use_sqlite'} = q[0];
199 0           $stdout->stop; $stderr->stop;
  0            
200              
201 0           foreach my $name ( @{$self->{modules}} ) {
  0            
202             # Shortcut if forced
203 0 0         if ( $self->{force}->{$name} ) {
204 0           push @{$self->{dists}}, $self->{force}->{$name};
  0            
205 0           next;
206             }
207              
208             # Get the CPAN object for the module, covering any output.
209 0           $stdout->start; $stderr->start;
  0            
210 0           my $module = CPAN::Shell->expand('Module', $name);
211 0           $stdout->stop; $stderr->stop;
  0            
212 0 0         unless ( $module ) {
213 0           die "Failed to find '$name'";
214             }
215              
216             # Ignore modules that don't need to be updated
217 0           my $core_version = $core->{$name};
218 0 0 0       if ( defined $core_version and $core_version =~ /_/ ) {
219             # Sometimes, the core contains a developer
220             # version. For the purposes of this comparison
221             # it should be safe to "round down".
222 0           $core_version =~ s/_.+$//;
223             }
224 0           my $cpan_version = $module->cpan_version;
225 0 0         unless ( defined $cpan_version ) {
226 0           next;
227             }
228 0 0 0       if ( defined $core_version and $core_version >= $cpan_version ) {
229 0           next;
230             }
231              
232             # Filter out already seen dists
233 0           my $file = $module->cpan_file;
234 0           $file =~ s/^[A-Z]\/[A-Z][A-Z]\///;
235 0           push @{$self->{dists}}, $file;
  0            
236             }
237              
238             # Remove duplicates
239 0           my %seen = ();
240 0           @{$self->{dists}} = grep { ! $seen{$_}++ } @{$self->{dists}};
  0            
  0            
  0            
241              
242 0           return 1;
243             }
244              
245             sub delegate {
246 0     0 1   my $self = shift;
247 0 0         unless ( $self->{delegated} ) {
248 0           $self->SUPER::delegate( @DELEGATE );
249 0           $self->{delegated} = 1;
250             }
251 0           return 1;
252             }
253              
254             sub delegated {
255 0     0 0   $_[0]->{delegated};
256             }
257              
258             1;
259