File Coverage

blib/lib/Shipwright/Source/CPAN.pm
Criterion Covered Total %
statement 56 115 48.7
branch 6 36 16.6
condition 1 15 6.6
subroutine 12 14 85.7
pod 2 2 100.0
total 77 182 42.3


line stmt bran cond sub pod time code
1             package Shipwright::Source::CPAN;
2              
3 3     3   1088 use warnings;
  3         4  
  3         103  
4 3     3   13 use strict;
  3         5  
  3         72  
5 3     3   11 use Shipwright::Util;
  3         5  
  3         255  
6 3     3   14 use File::Spec::Functions qw/catfile catdir rootdir/;
  3         6  
  3         190  
7 3     3   845 use Shipwright::Source::Compressed;
  3         7  
  3         47  
8 3     3   6964 use CPAN;
  3         413578  
  3         862  
9 3     3   4025 use Data::Dumper;
  3         16322  
  3         257  
10 3     3   27 use File::Temp qw/tempdir/;
  3         6  
  3         206  
11 3     3   17 use File::Slurp;
  3         7  
  3         212  
12 3     3   1257 use CPAN::DistnameInfo;
  3         1611  
  3         137  
13              
14 3     3   130 use base qw/Shipwright::Source::Base/;
  3         6  
  3         3257  
15              
16             my $cpan_dir = tempdir( 'shipwright_cpan_XXXXXX', CLEANUP => 1, TMPDIR => 1 );
17             unshift @INC, $cpan_dir;
18              
19             =head1 NAME
20              
21             Shipwright::Source::CPAN - CPAN source
22              
23             =head1 DESCRIPTION
24              
25             =head2 new
26              
27             =cut
28              
29             sub new {
30 3     3 1 7 my $class = shift;
31 3         27 my $self = $class->SUPER::new(@_);
32              
33 3         553 require Module::Info;
34 3 50       3276 if ( Module::Info->new_from_module('CPAN::Config') ) {
35              
36             # keep original CPAN::Config info
37 0         0 require CPAN::Config;
38             }
39              
40 3         688 unshift @INC, catdir( $ENV{'HOME'}, '.cpan' );
41 3 50       10 if ( Module::Info->new_from_module('CPAN::MyConfig') ) {
42              
43             # keep user's CPAN::MyConfig too
44 3         1175 require CPAN::MyConfig;
45             }
46 3         22 shift @INC;
47              
48              
49 3         113 mkdir catdir( $cpan_dir, 'CPAN' );
50 3         15 my $config_file = catfile( $cpan_dir, 'CPAN', 'MyConfig.pm' );
51              
52 3 100       50 unless ( -f $config_file ) {
53              
54             # hack $CPAN::Config, mostly to make cpan stuff temporary
55 2         10 $CPAN::Config->{cpan_home} = catdir($cpan_dir);
56 2         7 $CPAN::Config->{build_dir} = catdir( $cpan_dir, 'build' );
57 2         6 $CPAN::Config->{histfile} = catfile( $cpan_dir, 'histfile' );
58              
59             # be careful, if you use minicpan, then the source won't be copied to
60             # $CPAN::Config->{keep_source_where}
61 2         23 $CPAN::Config->{keep_source_where} =
62             catdir( $self->download_directory, 'cpan' );
63 2         9 $CPAN::Config->{prefs_dir} = catdir( $cpan_dir, 'prefs' );
64 2         3 $CPAN::Config->{prerequisites_policy} = 'follow';
65 2 50 33     11 unless ( $CPAN::Config->{urllist} && @{ $CPAN::Config->{urllist} } ) {
  2         10  
66 0         0 $CPAN::Config->{urllist} = [ 'http://search.cpan.org/CPAN' ];
67             }
68              
69 2 50       18 if ( $ENV{SHIPWRIGHT_CPAN_MIRROR} ) {
70 0         0 unshift @{$CPAN::Config->{urllist}}, $ENV{SHIPWRIGHT_CPAN_MIRROR};
  0         0  
71             }
72              
73 2         14 write_file( $config_file,
74             Data::Dumper->Dump( [$CPAN::Config], ['$CPAN::Config'] ) );
75              
76             }
77 3         947 require CPAN::MyConfig;
78 3         34 return $self;
79             }
80              
81             =head2 run
82              
83             =cut
84              
85             sub run {
86 0     0 1   my $self = shift;
87 0           $self->log->info( "preparing to run source: " . $self->source );
88              
89 0           my $result = $self->_run;
90 0 0 0       if ( $result && $result == 1) {
    0 0        
91 0           my $compressed =
92             Shipwright::Source::Compressed->new( %$self, _no_update_url => 1 );
93 0           $compressed->run(@_);
94             }
95             elsif ( !$result && $self->source =~ /\S/ ) {
96 0           my $error = q{invalid source: can't find '} . $self->source . q{'};
97 0 0         if ( $self->version ) {
98 0           $error .= ' version ' . $self->version;
99             }
100 0           $error .= ' in your CPAN mirror(s)' . " [@{$CPAN::Config->{urllist}}].";
  0            
101 0           chdir rootdir(); #< chdir to root dir in case CPAN has chdir'd
102             #into one of the temp dirs, preventing its
103             #deletion
104 0           confess_or_die $error;
105             } else {
106 0           $self->log->warn("removing source ".$self->source);
107 0           return;
108             }
109             }
110              
111             sub _run {
112 0     0     my $self = shift;
113 0 0         return if $self->source eq 'perl'; # don't expand perl itself;
114              
115 0           my ( $source, $distribution );
116              
117 0           select_fh('cpan');
118              
119 0 0         if ( $self->source =~ /\.tar\.gz$/ ) {
120              
121             # it's a disribution
122 0           $distribution = CPAN::Shell->expand( 'Distribution', $self->source );
123              
124 0 0         unless ($distribution) {
125 0           $self->log->warn( "can't find "
126             . $self->source
127             . ' on CPAN, assuming you will manually fix it. good luck!' );
128 0           return;
129             }
130              
131             # distribution source isn't good for shipwright, convert it to a
132             # module name it contains
133 0           $self->source( ( $distribution->containsmods )[0] );
134              
135 0           $source = $distribution->{ID};
136             }
137             else {
138              
139             # it's a module
140 0 0         my $type = $self->source =~ /^Bundle/ ? 'Bundle' : 'Module';
141 0           my $module = CPAN::Shell->expand( $type, $self->source );
142              
143 0 0         unless ($module) {
144 0           $self->log->warn( "can't find "
145             . $self->source
146             . ' on CPAN, assuming you will manually fix it. good luck!' );
147 0           return;
148             }
149              
150 0           $source = $module->cpan_file;
151              
152 0           $distribution = $module->distribution;
153              
154 0           my $info = CPAN::DistnameInfo->new( $module->cpan_file );
155              
156 0 0         if ( $self->version ) {
157 0           my $latest_version = $info->version;
158 0           my $version = $self->version;
159 0 0 0       if ( $latest_version =~ /^v/ && $version !~ /^v/ ) {
160 0           $version = 'v' . $version;
161             }
162 0           $distribution->{ID} =~ s/$latest_version/$version/;
163 0           $source =~ s/$latest_version/$version/;
164             }
165             }
166              
167 0           my $name = CPAN::DistnameInfo->new( $distribution->{ID} )->dist;
168              
169 0 0         if (!$name ) {
    0          
170 0           $self->log->warn("skipping " . $self->source . " because it's not on CPAN");
171 0           return -1;
172             }
173             elsif ( $name eq 'perl' ) {
174 0           $self->log->warn(
175             'skipping ' . $self->source . " because it's in core" );
176 0           return -1;
177             }
178              
179 0           select_fh('stdout');
180              
181 0           $self->name( 'cpan-' . $name );
182 0           $self->_update_map( $self->source, 'cpan-' . $name );
183              
184 0           my ($file) = catfile( $CPAN::Config->{keep_source_where},
185             "authors", "id", split /\//, $distribution->id );
186              
187 0 0 0       if ( -e $file && -s $file ) {
188 0           $self->source($file);
189             }
190             else {
191 0           $self->source($distribution->get_file_onto_local_disk);
192             }
193 0           return 1;
194             }
195              
196             1;
197              
198             __END__