line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package CPAN::Inject; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=pod |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
CPAN::Inject - Base class for injecting distributions into CPAN sources |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 SYNOPSIS |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# Create the injector |
12
|
|
|
|
|
|
|
my $cpan = CPAN::Inject->new( |
13
|
|
|
|
|
|
|
sources => '/root/.cpan/sources', # Required field |
14
|
|
|
|
|
|
|
author => 'LOCAL', # The default |
15
|
|
|
|
|
|
|
); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# Add a file to the user |
18
|
|
|
|
|
|
|
$cpan->add( file => 'some/random/Perl-Tarball-1.02.tar.gz' ); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# What would have have to use when installing |
21
|
|
|
|
|
|
|
# $path = 'LOCAL/Perl-Tarball-1.02.tar.gz'; |
22
|
|
|
|
|
|
|
my $path = $cpan->install_path( 'some/random/Perl-Tarball-1.02.tar.gz' ); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 DESCRIPTION |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
Following the release of L, the L module |
27
|
|
|
|
|
|
|
was created to add additional distributions into a minicpan mirror. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
While it was created for use with a minicpan mirror, similar |
30
|
|
|
|
|
|
|
functionality can be reused in other situations. |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
B replicates the basics of this functionality. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Specifically, it takes an arbitrary tarball and adds it to the CPAN |
35
|
|
|
|
|
|
|
sources directory for a particular author, and then add the new file |
36
|
|
|
|
|
|
|
to the F file. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
It does not reimplement the logic to add files to the indexes. |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
The initial use this module was created for was to inject tarballs into |
41
|
|
|
|
|
|
|
the CPAN sources directory for the reserved LOCAL user, so that the can be |
42
|
|
|
|
|
|
|
installed via the CPAN shell, with automated recursion to CPAN dependencies. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
But although the number of functions is limited (current only C exists, |
45
|
|
|
|
|
|
|
with the others to be added as needed) the implementation is very generic |
46
|
|
|
|
|
|
|
and sub-classable, so that it can be reused in other situations. |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 METHODS |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=cut |
51
|
|
|
|
|
|
|
|
52
|
2
|
|
|
2
|
|
25333
|
use 5.006; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
70
|
|
53
|
2
|
|
|
2
|
|
10
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
65
|
|
54
|
2
|
|
|
2
|
|
1894
|
use Params::Util (); |
|
2
|
|
|
|
|
7733
|
|
|
2
|
|
|
|
|
42
|
|
55
|
2
|
|
|
2
|
|
1692
|
use File::stat (); |
|
2
|
|
|
|
|
95476
|
|
|
2
|
|
|
|
|
47
|
|
56
|
2
|
|
|
2
|
|
1748
|
use File::chmod (); |
|
2
|
|
|
|
|
5355
|
|
|
2
|
|
|
|
|
39
|
|
57
|
2
|
|
|
2
|
|
12
|
use File::Spec (); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
24
|
|
58
|
2
|
|
|
2
|
|
10
|
use File::Path (); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
23
|
|
59
|
2
|
|
|
2
|
|
1762
|
use File::Copy (); |
|
2
|
|
|
|
|
4654
|
|
|
2
|
|
|
|
|
45
|
|
60
|
2
|
|
|
2
|
|
11
|
use File::Basename (); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
23
|
|
61
|
2
|
|
|
2
|
|
1639
|
use CPAN::Checksums (); |
|
2
|
|
|
|
|
281279
|
|
|
2
|
|
|
|
|
67
|
|
62
|
|
|
|
|
|
|
|
63
|
2
|
|
|
2
|
|
19
|
use vars qw{$VERSION $CHECK_OWNER}; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
330
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
BEGIN { |
66
|
2
|
|
|
2
|
|
5
|
$VERSION = '1.14'; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# Attempt to determine whether or not we are capable |
69
|
|
|
|
|
|
|
# of finding the owner of a directory. |
70
|
|
|
|
|
|
|
# Unless someone set it to a hard-coded value before we |
71
|
|
|
|
|
|
|
# started to load this module. |
72
|
2
|
50
|
|
|
|
10
|
unless ( defined $CHECK_OWNER ) { |
73
|
|
|
|
|
|
|
# Take a directory we know should exist... |
74
|
2
|
|
|
|
|
27
|
my $root = File::Spec->rootdir(); |
75
|
2
|
50
|
|
|
|
66
|
unless ( -d $root ) { |
76
|
0
|
|
|
|
|
0
|
die "Cannot determine if CPAN::Inject can operate on this platform"; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# ... find the owner for it... |
80
|
2
|
|
|
|
|
14
|
my $owner = File::stat::stat($root)->uid; |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# ... and if it works, check again in the future. |
83
|
|
|
|
|
|
|
# Unless someone set it already, in which case |
84
|
2
|
50
|
|
|
|
441
|
$CHECK_OWNER = defined $owner ? 1 : ''; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# And boolify the value, just to be a little safer |
88
|
2
|
|
|
|
|
2683
|
$CHECK_OWNER = !! $CHECK_OWNER; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
##################################################################### |
96
|
|
|
|
|
|
|
# Constructor and Accessors |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=pod |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 new |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# Create the injector for the default LOCAL author |
103
|
|
|
|
|
|
|
$cpan = CPAN::Inject->new( |
104
|
|
|
|
|
|
|
sources => '/root/.cpan/sources', |
105
|
|
|
|
|
|
|
); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Create the injector for a specific author |
108
|
|
|
|
|
|
|
$cpan = CPAN::Inject->new( |
109
|
|
|
|
|
|
|
sources => '/root/.cpan/sources', |
110
|
|
|
|
|
|
|
author => 'ADAMK', |
111
|
|
|
|
|
|
|
); |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
The C constructor takes a set of named params and create a cpan |
114
|
|
|
|
|
|
|
injection object. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
* B - The compulsory C param should be the path to a |
117
|
|
|
|
|
|
|
directory that is the root of a mirror (or a partial mirror such as a |
118
|
|
|
|
|
|
|
L or a L). |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
To retain the permissions and ownership integrity of the sources tree, |
121
|
|
|
|
|
|
|
you must be the owner of the C directory in order to inject the |
122
|
|
|
|
|
|
|
distribution tarballs. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
* B - The optional C param should be the CPAN id of an |
125
|
|
|
|
|
|
|
author. By default, the reserved local CPAN id "LOCAL" will be used. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
The author provided will be used as a default in all further actions. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
Returns a C object, or throws an exception on error. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=cut |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub new { |
134
|
5
|
|
|
5
|
1
|
1812
|
my $class = shift; |
135
|
5
|
|
|
|
|
28
|
my $self = bless {@_}, $class; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# Check where we are going to write to |
138
|
5
|
|
|
|
|
18
|
my $sources = $self->sources; |
139
|
5
|
50
|
|
|
|
33
|
unless ( Params::Util::_STRING($sources) ) { |
140
|
0
|
|
|
|
|
0
|
Carp::croak("Did not probide a sources param, or not a string"); |
141
|
|
|
|
|
|
|
} |
142
|
5
|
50
|
|
|
|
92
|
unless ( -d $sources ) { |
143
|
|
|
|
|
|
|
# The sources directory may actually exist, but we cannot |
144
|
|
|
|
|
|
|
# see it because we do not have execute permissions to the |
145
|
|
|
|
|
|
|
# parent directory tree. |
146
|
|
|
|
|
|
|
# For example, if it is at /root/.cpan/source and we do not |
147
|
|
|
|
|
|
|
# have -x permissions to /root |
148
|
0
|
|
|
|
|
0
|
my ($v, $d) = File::Spec->splitpath( $sources, 'nofile' ); |
149
|
0
|
|
|
|
|
0
|
my @dirs = File::Spec->splitdir( $d ); |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# Ignore the last directory, since that is what we -d tested |
152
|
0
|
|
|
|
|
0
|
pop @dirs; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Check for the existance and rx status of each parent |
155
|
0
|
|
|
|
|
0
|
foreach my $i ( 0 .. $#dirs ) { |
156
|
0
|
|
|
|
|
0
|
my $parent = File::Spec->catpath( |
157
|
|
|
|
|
|
|
$v, |
158
|
|
|
|
|
|
|
File::Spec->catdir( @dirs[0..$i] ), |
159
|
|
|
|
|
|
|
'', # No file (returns just the dir) |
160
|
|
|
|
|
|
|
); |
161
|
0
|
0
|
|
|
|
0
|
unless ( -d $parent ) { |
162
|
0
|
|
|
|
|
0
|
Carp::croak("The directory '$sources' does not exist"); |
163
|
|
|
|
|
|
|
} |
164
|
0
|
0
|
0
|
|
|
0
|
unless ( -r $parent and -x $parent ) { |
165
|
|
|
|
|
|
|
# Assume that it does exist, but that we can't see it |
166
|
0
|
|
|
|
|
0
|
Carp::croak("The sources directory is not owned by the current user"); |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
} |
169
|
0
|
|
|
|
|
0
|
Carp::croak("The directory '$sources' does not exist"); |
170
|
|
|
|
|
|
|
} |
171
|
5
|
50
|
|
|
|
40
|
unless ( $< == File::stat::stat($sources)->uid ) { |
172
|
0
|
|
|
|
|
0
|
Carp::croak("The sources directory is not owned by the current user"); |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# Check for a default author name |
176
|
5
|
100
|
|
|
|
903
|
$self->{author} = 'LOCAL' unless $self->author; |
177
|
5
|
50
|
|
|
|
12
|
unless ( _AUTHOR( $self->author ) ) { |
178
|
0
|
|
|
|
|
0
|
Carp::croak( "The author name '" |
179
|
|
|
|
|
|
|
. $self->author |
180
|
|
|
|
|
|
|
. "' is not a valid author string" |
181
|
|
|
|
|
|
|
); |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
5
|
|
|
|
|
16
|
$self; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=pod |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=head2 from_cpan_config |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
The C constructor loads the CPAN.pm configuration file, and |
192
|
|
|
|
|
|
|
uses the data contained within to specific the sources path for the |
193
|
|
|
|
|
|
|
object. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
This constructor is otherwise the same. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Returns a B object on success, or throws an exception on |
198
|
|
|
|
|
|
|
error. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=cut |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub from_cpan_config { |
203
|
1
|
|
|
1
|
1
|
373
|
my $class = shift; |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Load the CPAN module |
206
|
1
|
|
|
|
|
1611
|
require CPAN; |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Support for different mechanisms depending on the version |
209
|
|
|
|
|
|
|
# of CPAN that is in use. |
210
|
1
|
50
|
|
|
|
297793
|
if ( defined $CPAN::HandleConfig::VERSION ) { |
211
|
1
|
|
|
|
|
30
|
CPAN::HandleConfig->load; |
212
|
|
|
|
|
|
|
} else { |
213
|
0
|
|
|
|
|
0
|
CPAN::Config->load; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# Get the sources directory |
217
|
1
|
|
|
|
|
429
|
my $sources = undef; |
218
|
1
|
50
|
|
|
|
6
|
if ( defined $CPAN::Config->{keep_source_where} ) { |
|
|
0
|
|
|
|
|
|
219
|
1
|
|
|
|
|
4
|
$sources = $CPAN::Config->{keep_source_where}; |
220
|
|
|
|
|
|
|
} elsif ( defined $CPAN::Config->{cpan_home} ) { |
221
|
0
|
|
|
|
|
0
|
$sources = File::Spec->catdir( $CPAN::Config->{cpan_home}, 'sources' ); |
222
|
|
|
|
|
|
|
} else { |
223
|
0
|
|
|
|
|
0
|
Carp::croak("Failed to find sources directory in CPAN::Config"); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# Hand off to the main constructor |
227
|
1
|
|
|
|
|
26
|
return $class->new( |
228
|
|
|
|
|
|
|
sources => $sources, |
229
|
|
|
|
|
|
|
@_, |
230
|
|
|
|
|
|
|
); |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=pod |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=head2 sources |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
The C accessor returns the path to the root of the directory tree. |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
=cut |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
sub sources { |
242
|
11
|
|
|
11
|
1
|
733
|
$_[0]->{sources}; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=pod |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=head2 author |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
The C accessor returns the CPAN id for the default author which |
250
|
|
|
|
|
|
|
will be "LOCAL" if you did not provide an alternative param to the the |
251
|
|
|
|
|
|
|
C constructor. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=cut |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub author { |
256
|
21
|
|
|
21
|
1
|
909
|
$_[0]->{author}; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
##################################################################### |
264
|
|
|
|
|
|
|
# Main methods |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=pod |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=head2 add |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# Add a file to the constructor/default author |
271
|
|
|
|
|
|
|
$cpan->add( file => 'any/arbitrary/Perl-Tarball-1.01.tar.gz' ); |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
The C method takes a Perl distribution tarball from an arbitrary |
274
|
|
|
|
|
|
|
path, and adds it to the sources path. |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
The specific location the tarball is copied to will be in the root |
277
|
|
|
|
|
|
|
directory for the author provided to the constructor. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
Returns the install_path value as a convenience, or throws an exception |
280
|
|
|
|
|
|
|
on error. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=cut |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub add { |
285
|
1
|
|
|
1
|
1
|
624
|
my $self = shift; |
286
|
1
|
|
|
|
|
9
|
my %params = @_; |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# Check the file source path |
289
|
1
|
|
|
|
|
3
|
my $from_file = $params{file}; |
290
|
1
|
50
|
33
|
|
|
53
|
unless ( $from_file and -f $from_file and -r $from_file ) { |
|
|
|
33
|
|
|
|
|
291
|
0
|
|
|
|
|
0
|
Carp::croak("Did not provide a file name, or does not exist"); |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# Get the file name |
295
|
1
|
50
|
|
|
|
68
|
my $name = File::Basename::fileparse($from_file) |
296
|
|
|
|
|
|
|
or die "Failed to get filename"; |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# Find the location to copy it to |
299
|
1
|
|
|
|
|
7
|
my $to_file = $self->file_path($name); |
300
|
1
|
|
|
|
|
65
|
my $to_dir = File::Basename::dirname($to_file); |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
# Make the path for the file |
303
|
1
|
|
|
|
|
6
|
SCOPE: { |
304
|
1
|
|
|
|
|
3
|
local $@; |
305
|
1
|
|
|
|
|
9
|
eval { |
306
|
1
|
|
|
|
|
757
|
File::Path::mkpath($to_dir); |
307
|
|
|
|
|
|
|
}; |
308
|
1
|
50
|
|
|
|
9
|
if ( my $e = $@ ) { |
309
|
0
|
|
|
|
|
0
|
Carp::croak("Failed to create $to_dir: $e"); |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
# Copy the file to the directory, and ensure writable |
314
|
1
|
50
|
|
|
|
17
|
File::Copy::copy( $from_file => $to_file ) |
315
|
|
|
|
|
|
|
or Carp::croak("Failed to copy $from_file to $to_file"); |
316
|
1
|
50
|
|
|
|
660
|
chmod( 0644, $to_file ) |
317
|
|
|
|
|
|
|
or Carp::croak("Failed to correct permissions for $to_file"); |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
# Update the checksums file, and ensure writable |
320
|
1
|
|
|
|
|
2
|
SCOPE: { |
321
|
1
|
|
|
|
|
3
|
local $@; |
322
|
1
|
|
|
|
|
2
|
eval { |
323
|
1
|
|
|
|
|
14
|
CPAN::Checksums::updatedir($to_dir); |
324
|
|
|
|
|
|
|
}; |
325
|
1
|
50
|
|
|
|
24250
|
if ( my $e = $@ ) { |
326
|
0
|
|
|
|
|
0
|
Carp::croak("Failed to update CHECKSUMS after insertion: $e"); |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
} |
329
|
1
|
50
|
|
|
|
38
|
chmod( 0644, File::Spec->catfile( $to_dir, 'CHECKSUMS' ) ) |
330
|
|
|
|
|
|
|
or Carp::croak("Failed to correct permissions for CHECKSUMS"); |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# Return the install_path as a convenience |
333
|
1
|
|
|
|
|
8
|
$self->install_path($name); |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=pod |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head2 remove |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
# Remove a distribution from the repository |
341
|
|
|
|
|
|
|
$cpan->remove( dist => 'LOCAL/Perl-Tarball-1.01.tar.gz' ); |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
The C method takes a distribution path and removes it from the |
344
|
|
|
|
|
|
|
sources path. The file is also removed. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
Does not return anything useful and throws an exception on error. |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=cut |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub remove { |
351
|
1
|
|
|
1
|
1
|
254
|
my $self = shift; |
352
|
1
|
|
|
|
|
7
|
my %params = @_; |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
# Get the file name |
355
|
1
|
50
|
|
|
|
24
|
my $name = File::Basename::fileparse($params{dist}) |
356
|
|
|
|
|
|
|
or die "Failed to get filename"; |
357
|
|
|
|
|
|
|
|
358
|
1
|
|
|
|
|
6
|
my $file_path = $self->file_path($name); |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
# Remove the file from CPAN. |
361
|
1
|
|
|
|
|
148
|
unlink $file_path while -e $file_path; |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
# Update the checksums file |
364
|
1
|
|
|
|
|
5
|
my $to_file = $self->file_path($name); |
365
|
1
|
|
|
|
|
42
|
my $to_dir = File::Basename::dirname($to_file); |
366
|
1
|
|
|
|
|
2
|
SCOPE: { |
367
|
1
|
|
|
|
|
3
|
local $@; |
368
|
1
|
|
|
|
|
1
|
eval { |
369
|
1
|
|
|
|
|
5
|
CPAN::Checksums::updatedir($to_dir); |
370
|
|
|
|
|
|
|
}; |
371
|
1
|
50
|
|
|
|
2043
|
if ( my $e = $@ ) { |
372
|
0
|
|
|
|
|
0
|
Carp::croak("Failed to update CHECKSUMS after removal: $e"); |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
|
376
|
1
|
|
|
|
|
4
|
return 1; |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=pod |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=head2 author_subpath |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
# $path = 'authors/id/L/LO/LOCAL' |
384
|
|
|
|
|
|
|
$path = $cpan->author_subpath; |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
The C method takes a CPAN author id (or uses the CPAN |
387
|
|
|
|
|
|
|
author id originally provided to the constructor) and returns the |
388
|
|
|
|
|
|
|
relative subpath for the AUTHOR within the sources tree. |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
Returns the subpath as a string. |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=cut |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
sub author_subpath { |
395
|
5
|
|
|
5
|
1
|
12
|
my $author = $_[0]->author; |
396
|
5
|
|
|
|
|
104
|
File::Spec->catdir( |
397
|
|
|
|
|
|
|
'authors', 'id', |
398
|
|
|
|
|
|
|
substr( $author, 0, 1 ), |
399
|
|
|
|
|
|
|
substr( $author, 0, 2 ), $author, |
400
|
|
|
|
|
|
|
); |
401
|
|
|
|
|
|
|
} |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=pod |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=head2 author_path |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# $path = '/root/.cpan/sources/authors/id/L/LO/LOCAL' |
408
|
|
|
|
|
|
|
$path = $cpan->author_subpath; |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
The C method finds the full path for the root directory for |
411
|
|
|
|
|
|
|
the named author. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
Returns the path as a string. |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=cut |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
sub author_path { |
418
|
1
|
|
|
1
|
1
|
24
|
File::Spec->catdir( $_[0]->sources, $_[0]->author_subpath, ); |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=pod |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=head2 file_path |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
# $path = '/root/.cpan/sources/authors/id/L/LO/LOCAL/Perl-Tarball-1.02.tar.gz' |
426
|
|
|
|
|
|
|
$path = $cpan->file_path( 'Perl-Tarball-1.02.tar.gz' ); |
427
|
|
|
|
|
|
|
$path = $cpan->file_path( '/some/random/place/Perl-Tarball-1.02.tar.gz' ); |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
The C method takes the name of a tarball (either just the name |
430
|
|
|
|
|
|
|
or a full path) and calculates the location that the file will end up at. |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
When files are copied into the sources directory, they are always copied |
433
|
|
|
|
|
|
|
to the top level of the author root. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
Returns the path as a string. |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=cut |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
sub file_path { |
440
|
3
|
|
|
3
|
1
|
11
|
File::Spec->catfile( $_[0]->sources, $_[0]->author_subpath, $_[1], ); |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=pod |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
=head2 install_path |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
# $path = 'LOCAL/Perl-Tarball-1.01.tar.gz'; |
448
|
|
|
|
|
|
|
$path = $cpan->install_path( 'Perl-Tarball-1.01.tar.gz' ); |
449
|
|
|
|
|
|
|
$path = $cpan->install_path( '/some/random/place/Perl-Tarball-1.02.tar.gz' ); |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
The C method returns the path for the distribution as the |
452
|
|
|
|
|
|
|
CPAN shell understands it. |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
Using this path, the CPAN shell can expand it to locate the |
455
|
|
|
|
|
|
|
distribution, and then can install it. |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Returns the path as a string. |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=cut |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
sub install_path { |
462
|
3
|
|
|
3
|
1
|
6
|
my $self = shift; |
463
|
3
|
50
|
|
|
|
80
|
my $file = File::Basename::fileparse(shift) |
464
|
|
|
|
|
|
|
or Carp::croak("Failed to get filename"); |
465
|
3
|
|
|
|
|
12
|
join( '/', $self->author, $file ); |
466
|
|
|
|
|
|
|
} |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
##################################################################### |
473
|
|
|
|
|
|
|
# Support Functions |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub _AUTHOR { |
476
|
5
|
50
|
33
|
5
|
|
74
|
( Params::Util::_STRING( $_[0] ) and $_[0] =~ /^[A-Z]{2,}$/ ) ? $_[0] : undef; |
477
|
|
|
|
|
|
|
} |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
1; |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=pod |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=head1 SUPPORT |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
This module is stored in an Open Repository at the following address. |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
L |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Write access to the repository is made available automatically to any |
490
|
|
|
|
|
|
|
published CPAN author, and to most other volunteers on request. |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
If you are able to submit your bug report in the form of new (failing) |
493
|
|
|
|
|
|
|
unit tests, or can apply your fix directly instead of submitting a patch, |
494
|
|
|
|
|
|
|
you are B encouraged to do so as the author currently maintains |
495
|
|
|
|
|
|
|
over 100 modules and it can take some time to deal with non-Critcal bug |
496
|
|
|
|
|
|
|
reports or patches. |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
This will guarentee that your issue will be addressed in the next |
499
|
|
|
|
|
|
|
release of the module. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
If you cannot provide a direct test or fix, or don't have time to do so, |
502
|
|
|
|
|
|
|
then regular bug reports are still accepted and appreciated via the CPAN |
503
|
|
|
|
|
|
|
bug tracker. |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
L |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
For other issues, for commercial enhancement or support, or to have your |
508
|
|
|
|
|
|
|
write access enabled for the repository, contact the author at the email |
509
|
|
|
|
|
|
|
address above. |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=head1 AUTHOR |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Adam Kennedy Eadamk@cpan.orgE |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=head1 SEE ALSO |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
L |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=head1 COPYRIGHT |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Copyright 2006 - 2011 Adam Kennedy. |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
This program is free software; you can redistribute |
524
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
The full text of the license can be found in the |
527
|
|
|
|
|
|
|
LICENSE file included with this module. |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
=cut |