File Coverage

blib/lib/Shipwright/Source/CPAN.pm
Criterion Covered Total %
statement 56 118 47.4
branch 6 38 15.7
condition 1 15 6.6
subroutine 12 14 85.7
pod 2 2 100.0
total 77 187 41.1


line stmt bran cond sub pod time code
1             package Shipwright::Source::CPAN;
2              
3 3     3   1055 use warnings;
  3         7  
  3         105  
4 3     3   15 use strict;
  3         5  
  3         54  
5 3     3   13 use Shipwright::Util;
  3         25  
  3         251  
6 3     3   17 use File::Spec::Functions qw/catfile catdir rootdir/;
  3         6  
  3         134  
7 3     3   243 use Shipwright::Source::Compressed;
  3         6  
  3         32  
8 3     3   1867 use CPAN;
  3         347912  
  3         780  
9 3     3   1523 use Data::Dumper;
  3         14787  
  3         196  
10 3     3   22 use File::Temp qw/tempdir/;
  3         9  
  3         137  
11 3     3   19 use File::Slurp;
  3         8  
  3         217  
12 3     3   540 use CPAN::DistnameInfo;
  3         1520  
  3         49  
13              
14 3     3   90 use base qw/Shipwright::Source::Base/;
  3         8  
  3         2941  
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         26 my $self = $class->SUPER::new(@_);
32              
33 3         311 require Module::Info;
34 3 50       3293 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         544 unshift @INC, catdir( $ENV{'HOME'}, '.cpan' );
41 3 50       14 if ( Module::Info->new_from_module('CPAN::MyConfig') ) {
42              
43             # keep user's CPAN::MyConfig too
44 3         995 require CPAN::MyConfig;
45             }
46 3         27 shift @INC;
47              
48              
49 3         151 mkdir catdir( $cpan_dir, 'CPAN' );
50 3         19 my $config_file = catfile( $cpan_dir, 'CPAN', 'MyConfig.pm' );
51              
52 3 100       31 unless ( -f $config_file ) {
53              
54             # hack $CPAN::Config, mostly to make cpan stuff temporary
55 2         9 $CPAN::Config->{cpan_home} = catdir($cpan_dir);
56 2         9 $CPAN::Config->{build_dir} = catdir( $cpan_dir, 'build' );
57 2         9 $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             $CPAN::Config->{keep_source_where} =
62 2         23 catdir( $self->download_directory, 'cpan' );
63 2         8 $CPAN::Config->{prefs_dir} = catdir( $cpan_dir, 'prefs' );
64 2         6 $CPAN::Config->{prerequisites_policy} = 'follow';
65 2 50 33     9 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       12 if ( $ENV{SHIPWRIGHT_CPAN_MIRROR} ) {
70 0         0 unshift @{$CPAN::Config->{urllist}}, $ENV{SHIPWRIGHT_CPAN_MIRROR};
  0         0  
71             }
72              
73 2         12 write_file( $config_file,
74             Data::Dumper->Dump( [$CPAN::Config], ['$CPAN::Config'] ) );
75              
76             }
77 3         862 require CPAN::MyConfig;
78 3         23 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 0         if ( Module::CoreList->is_core( $self->source )) {
97 0           $self->log->info("skipping dual lifed " . $self->source . " because can't find it on cpan any more");
98 0           return;
99             }
100 0           my $error = q{invalid source: can't find '} . $self->source . q{'};
101 0 0         if ( $self->version ) {
102 0           $error .= ' version ' . $self->version;
103             }
104 0           $error .= ' in your CPAN mirror(s)' . " [@{$CPAN::Config->{urllist}}].";
  0            
105 0           chdir rootdir(); #< chdir to root dir in case CPAN has chdir'd
106             #into one of the temp dirs, preventing its
107             #deletion
108 0           confess_or_die $error;
109             } else {
110 0           $self->log->warn("removing source ".$self->source);
111 0           return;
112             }
113             }
114              
115             sub _run {
116 0     0     my $self = shift;
117 0 0         return if $self->source eq 'perl'; # don't expand perl itself;
118              
119 0           my ( $source, $distribution );
120              
121 0           select_fh('cpan');
122              
123 0 0         if ( $self->source =~ /\.tar\.gz$/ ) {
124              
125             # it's a disribution
126 0           $distribution = CPAN::Shell->expand( 'Distribution', $self->source );
127              
128 0 0         unless ($distribution) {
129 0           $self->log->warn( "can't find "
130             . $self->source
131             . ' on CPAN, assuming you will manually fix it. good luck!' );
132 0           return;
133             }
134              
135             # distribution source isn't good for shipwright, convert it to a
136             # module name it contains
137 0           $self->source( ( $distribution->containsmods )[0] );
138              
139 0           $source = $distribution->{ID};
140             }
141             else {
142              
143             # it's a module
144 0 0         my $type = $self->source =~ /^Bundle/ ? 'Bundle' : 'Module';
145 0           my $module = CPAN::Shell->expand( $type, $self->source );
146              
147 0 0         unless ($module) {
148 0           $self->log->warn( "can't find "
149             . $self->source
150             . ' on CPAN, assuming you will manually fix it. good luck!' );
151 0           return;
152             }
153              
154 0           $source = $module->cpan_file;
155              
156 0           $distribution = $module->distribution;
157              
158 0           my $info = CPAN::DistnameInfo->new( $module->cpan_file );
159              
160 0 0         if ( $self->version ) {
161 0           my $latest_version = $info->version;
162 0           my $version = $self->version;
163 0 0 0       if ( $latest_version =~ /^v/ && $version !~ /^v/ ) {
164 0           $version = 'v' . $version;
165             }
166 0           $distribution->{ID} =~ s/$latest_version/$version/;
167 0           $source =~ s/$latest_version/$version/;
168             }
169             }
170              
171 0           my $name = CPAN::DistnameInfo->new( $distribution->{ID} )->dist;
172              
173 0 0         if (!$name ) {
    0          
174 0           $self->log->warn("skipping " . $self->source . " because it's not on CPAN");
175 0           return -1;
176             }
177             elsif ( $name eq 'perl' ) {
178 0           $self->log->warn(
179             'skipping ' . $self->source . " because it's in core" );
180 0           return -1;
181             }
182              
183 0           select_fh('stdout');
184              
185 0           $self->name( 'cpan-' . $name );
186 0           $self->_update_map( $self->source, 'cpan-' . $name );
187              
188             my ($file) = catfile( $CPAN::Config->{keep_source_where},
189 0           "authors", "id", split /\//, $distribution->id );
190              
191 0 0 0       if ( -e $file && -s $file ) {
192 0           $self->source($file);
193             }
194             else {
195 0           $self->source($distribution->get_file_onto_local_disk);
196             }
197 0           return 1;
198             }
199              
200             1;
201              
202             __END__