line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package CPAN::Mini::ProjectDocs ; |
3
|
|
|
|
|
|
|
|
4
|
2
|
|
|
2
|
|
74127
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
61
|
|
5
|
2
|
|
|
2
|
|
9
|
use warnings ; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
54
|
|
6
|
2
|
|
|
2
|
|
9
|
use Carp qw(carp croak confess) ; |
|
2
|
|
|
|
|
9
|
|
|
2
|
|
|
|
|
172
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
BEGIN |
9
|
|
|
|
|
|
|
{ |
10
|
2
|
|
|
|
|
27
|
use Sub::Exporter -setup => |
11
|
|
|
|
|
|
|
{ |
12
|
|
|
|
|
|
|
exports => [ qw(generate_html get_module_distribution generate_cache search_modules) ], |
13
|
|
|
|
|
|
|
groups => |
14
|
|
|
|
|
|
|
{ |
15
|
|
|
|
|
|
|
all => [ qw() ], |
16
|
|
|
|
|
|
|
} |
17
|
2
|
|
|
2
|
|
1839
|
}; |
|
2
|
|
|
|
|
26872
|
|
18
|
|
|
|
|
|
|
|
19
|
2
|
|
|
2
|
|
941
|
use vars qw ($VERSION); |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
93
|
|
20
|
2
|
|
|
2
|
|
40
|
$VERSION = '0.03'; |
21
|
|
|
|
|
|
|
} |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
24
|
|
|
|
|
|
|
|
25
|
2
|
|
|
2
|
|
7798
|
use English qw( -no_match_vars ) ; |
|
2
|
|
|
|
|
10006
|
|
|
2
|
|
|
|
|
12
|
|
26
|
|
|
|
|
|
|
|
27
|
2
|
|
|
2
|
|
2788
|
use Readonly ; |
|
2
|
|
|
|
|
6314
|
|
|
2
|
|
|
|
|
113
|
|
28
|
|
|
|
|
|
|
Readonly my $EMPTY_STRING => q{} ; |
29
|
|
|
|
|
|
|
|
30
|
2
|
|
|
2
|
|
1766
|
use CPAN::PackageDetails ; |
|
2
|
|
|
|
|
38002
|
|
|
2
|
|
|
|
|
86
|
|
31
|
2
|
|
|
2
|
|
22
|
use Digest::MD5; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
82
|
|
32
|
2
|
|
|
2
|
|
2245
|
use File::Slurp ; |
|
2
|
|
|
|
|
30725
|
|
|
2
|
|
|
|
|
166
|
|
33
|
2
|
|
|
2
|
|
21
|
use Data::Dumper ; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
87
|
|
34
|
2
|
|
|
2
|
|
2605
|
use Archive::Tar ; |
|
2
|
|
|
|
|
249271
|
|
|
2
|
|
|
|
|
177
|
|
35
|
2
|
|
|
2
|
|
2067
|
use Pod::ProjectDocs; |
|
2
|
|
|
|
|
215264
|
|
|
2
|
|
|
|
|
35
|
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 NAME |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
CPAN::Mini::ProjectDocs - mini CPAN documentation browser |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 SYNOPSIS |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
see the B command for a full example. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head1 DESCRIPTION |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
This module and associated script B let you search and display documentation for the modules in you CPAN mini. |
50
|
|
|
|
|
|
|
The documentation is displayed in your browser (text mode browsers supported) |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 DOCUMENTATION |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
You most probably want to run the B script, use the I<--help> option for help. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 SUBROUTINES/METHODS |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=cut |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub get_mcd_paths |
63
|
|
|
|
|
|
|
{ |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=head2 get_mcd_paths($cpan_mini, $mcd_cache) |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
Given a CPAN mini location and a cache location, computes a list containing the paths used by CPAN::Mini::ProjectDocs. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
I |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=over 2 |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item $cpan_mini - Location of the CPAN::MINI repository |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=item $mcd_cache - Location of the cache maintained by CPAN::Mini::ProjectDocs |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=back |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
I - A list containing the paths used by CPAN::Mini::ProjectDocs |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
I - None |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
0
|
|
|
0
|
1
|
|
my ($cpan_mini, $mcd_cache) = @_ ; |
86
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
|
my $modules_details_file = "$cpan_mini/modules/02packages.details.txt.gz" ; |
88
|
0
|
|
|
|
|
|
my $modules_details_txt_md5_file = "$mcd_cache/packages.details.md5.txt" ; |
89
|
0
|
|
|
|
|
|
my $modules_details_cache_file = "$mcd_cache/packages.details.cache" ; |
90
|
0
|
|
|
|
|
|
my $modules_details_cache_all_names = "${modules_details_cache_file}_all_names.txt" ; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
return |
93
|
|
|
|
|
|
|
( |
94
|
0
|
|
|
|
|
|
$modules_details_file, |
95
|
|
|
|
|
|
|
$modules_details_txt_md5_file, |
96
|
|
|
|
|
|
|
$modules_details_cache_file, |
97
|
|
|
|
|
|
|
$modules_details_cache_all_names |
98
|
|
|
|
|
|
|
) ; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub generate_html |
104
|
|
|
|
|
|
|
{ |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 generate_html($cpan_mini, $mcd_cache, $distribution, $html_index) |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
Generates the HTML documentation for $distribution. The generation is performed only if the |
109
|
|
|
|
|
|
|
documentation does not exist in the cache. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
I |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=over 2 |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=item $cpan_mini - Location of the CPAN::MINI repository |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=item $mcd_cache - Location of the cache maintained by CPAN::Mini::ProjectDocs |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=item $distribution - Location of the distribution containing the module to display |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=item $html_index - Boolean - generate a pure HTML index for text based browser |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=back |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
I - $html_documentation_location |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
I - problems with the distribution extraction, write errors on the file system, ... |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=cut |
130
|
|
|
|
|
|
|
|
131
|
0
|
|
|
0
|
1
|
|
my ($cpan_mini, $mcd_cache, $distribution, $html_index) = @_ ; |
132
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
my ($module_directory) = $distribution =~ /([^\/]+)\.tar.gz$/ ; |
134
|
0
|
|
|
|
|
|
my $html_directory = "$mcd_cache/generated_html/$module_directory" ; |
135
|
0
|
|
|
|
|
|
my $html_directory_md5 = "$html_directory/md5.txt" ; |
136
|
|
|
|
|
|
|
|
137
|
0
|
|
|
|
|
|
my $regenerate_html = 0 ; |
138
|
|
|
|
|
|
|
|
139
|
0
|
|
|
|
|
|
my ($modules_details_file) = get_mcd_paths($cpan_mini, $mcd_cache) ; |
140
|
0
|
|
|
|
|
|
my $modules_details_txt_md5 = get_file_MD5($modules_details_file) ; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
#check if the html was already generated |
143
|
0
|
0
|
|
|
|
|
if(-e $html_directory) |
144
|
|
|
|
|
|
|
{ |
145
|
|
|
|
|
|
|
eval |
146
|
0
|
|
|
|
|
|
{ |
147
|
0
|
|
|
|
|
|
my $mcd_cache_md5 = read_file($html_directory_md5) ; |
148
|
0
|
0
|
|
|
|
|
$regenerate_html++ if $mcd_cache_md5 ne $modules_details_txt_md5 ; |
149
|
|
|
|
|
|
|
} ; |
150
|
|
|
|
|
|
|
|
151
|
0
|
0
|
|
|
|
|
$regenerate_html++ if $@ ; # file not found |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
else |
154
|
|
|
|
|
|
|
{ |
155
|
0
|
|
|
|
|
|
$regenerate_html++ ; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
0
|
0
|
|
|
|
|
if($regenerate_html) |
159
|
|
|
|
|
|
|
{ |
160
|
0
|
|
|
|
|
|
my $tar = Archive::Tar->new($distribution) ; |
161
|
0
|
|
|
|
|
|
$tar->setcwd($mcd_cache); |
162
|
0
|
|
|
|
|
|
$tar->extract() ; |
163
|
|
|
|
|
|
|
|
164
|
0
|
|
|
|
|
|
mkdir "$mcd_cache/generated_html/" ; |
165
|
0
|
|
|
|
|
|
mkdir $html_directory ; |
166
|
|
|
|
|
|
|
|
167
|
0
|
0
|
|
|
|
|
Pod::ProjectDocs->new |
168
|
|
|
|
|
|
|
( |
169
|
|
|
|
|
|
|
outroot => $html_directory, |
170
|
|
|
|
|
|
|
libroot => -e "$mcd_cache/$module_directory/lib" ? "$mcd_cache/$module_directory/lib" : "$mcd_cache/$module_directory", |
171
|
|
|
|
|
|
|
title => $distribution, |
172
|
|
|
|
|
|
|
)->gen() ; |
173
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
|
write_file($html_directory_md5, $modules_details_txt_md5) ; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
|
my $html_documentation_location = "$mcd_cache/generated_html/$module_directory/index.html" ; |
178
|
|
|
|
|
|
|
|
179
|
0
|
0
|
|
|
|
|
if($html_index) |
180
|
|
|
|
|
|
|
{ |
181
|
0
|
|
|
|
|
|
$html_documentation_location = generate_pure_html_index("$mcd_cache/generated_html/$module_directory/", 'index.html') ; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
0
|
|
|
|
|
|
return $html_documentation_location; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub generate_pure_html_index |
190
|
|
|
|
|
|
|
{ |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head2 generate_pure_html_index($path, $file) |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Generate a pure HTML index for text based browsers. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
I |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=over 2 |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=item $path - path to the POD::ProjDocs generated index file |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=item $file - POD::ProjDocs generated index file |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=back |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
I - The location of the pure HTML index |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
I - None |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=cut |
211
|
|
|
|
|
|
|
|
212
|
0
|
|
|
0
|
1
|
|
my ($path, $file) = @_ ; |
213
|
|
|
|
|
|
|
|
214
|
0
|
|
|
|
|
|
my $index = read_file("$path/$file") ; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# convert JS data structure to Perl data structure |
217
|
0
|
|
|
|
|
|
my ($data) = $index =~ m/var managers = (.*?)function render\(pattern\)/sm ; |
218
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
my $perl_data_structure = '' ; |
220
|
0
|
|
|
|
|
|
my $in_string = 0 ; |
221
|
|
|
|
|
|
|
|
222
|
0
|
|
|
|
|
|
for my $character (split //, $data) |
223
|
|
|
|
|
|
|
{ |
224
|
0
|
0
|
|
|
|
|
if($in_string) |
225
|
|
|
|
|
|
|
{ |
226
|
0
|
|
|
|
|
|
$perl_data_structure .= $character ; |
227
|
0
|
0
|
|
|
|
|
$in_string = 0 if $character eq q{"} ; |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
else |
230
|
|
|
|
|
|
|
{ |
231
|
0
|
0
|
|
|
|
|
$in_string = 1 if $character eq q{"} ; |
232
|
|
|
|
|
|
|
|
233
|
0
|
0
|
|
|
|
|
if($character eq q{:}) |
234
|
|
|
|
|
|
|
{ |
235
|
0
|
|
|
|
|
|
$perl_data_structure .= q{=>} ; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
else |
238
|
|
|
|
|
|
|
{ |
239
|
0
|
|
|
|
|
|
$perl_data_structure .= $character ; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
0
|
|
|
|
|
|
$data = eval $perl_data_structure ; |
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
|
|
|
my $html = '' ; |
247
|
|
|
|
|
|
|
|
248
|
0
|
|
|
|
|
|
for my $section (@{$data}) |
|
0
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
{ |
250
|
0
|
|
|
|
|
|
$html .= <
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
$section->{desc} |
253
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
EOH |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# remove all trace of javascript |
292
|
0
|
|
|
|
|
|
$index =~ s{}{}sm ; |
293
|
0
|
|
|
|
|
|
$index =~ s{\Q}{}sm ; |
294
|
|
|
|
|
|
|
|
295
|
0
|
|
|
|
|
|
$index =~ s{( .*? )}{}sm ; |
296
|
0
|
|
|
|
|
|
my $title = '' ; #$1 ; |
297
|
|
|
|
|
|
|
|
298
|
0
|
|
|
|
|
|
$index =~ s{ .*? }{}sm ; |
299
|
|
|
|
|
|
|
|
300
|
0
|
|
|
|
|
|
$index =~ s{()}{$1\n$title\n$html}sm ; |
301
|
|
|
|
|
|
|
|
302
|
0
|
|
|
|
|
|
my $pure_html_index_location = "$path/pure_html_index.html" ; |
303
|
|
|
|
|
|
|
|
304
|
0
|
|
|
|
|
|
write_file $pure_html_index_location, $index ; |
305
|
|
|
|
|
|
|
|
306
|
0
|
|
|
|
|
|
return $pure_html_index_location ; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub get_module_distribution |
312
|
|
|
|
|
|
|
{ |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=head2 get_module_distribution($cpan_mini, $mcd_cache, $module) |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Finds the distribution containing the module. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
my $distribution = get_module_distribution($cpan_mini, $mcd_cache, $module) ; |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
I |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=over 2 |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=item $cpan_mini - Location of the CPAN::MINI repository |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=item $mcd_cache - Location of the cache maintained by CPAN::Mini::ProjectDocs |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=item $module - Name of the module to display |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=back |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
I - The location of the distribution containing the module to display |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
I - read error if the cache is not already generated |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=cut |
337
|
|
|
|
|
|
|
|
338
|
0
|
|
|
0
|
1
|
|
my ($cpan_mini, $mcd_cache, $module) = @_ ; |
339
|
|
|
|
|
|
|
|
340
|
0
|
|
|
|
|
|
my (undef, undef, $modules_details_cache_file) = get_mcd_paths($cpan_mini, $mcd_cache) ; |
341
|
0
|
|
|
|
|
|
my $first_letter = substr($module, 0, 1) ; |
342
|
0
|
|
|
|
|
|
my $cache_file = "${modules_details_cache_file}_$first_letter.txt" ; |
343
|
|
|
|
|
|
|
|
344
|
0
|
0
|
|
|
|
|
my $module_details = do $cache_file or carp "Error: Invalid '$cache_file'\n" ;; |
345
|
|
|
|
|
|
|
|
346
|
0
|
|
|
|
|
|
my $distribution ; |
347
|
|
|
|
|
|
|
|
348
|
0
|
|
|
|
|
|
for my $record ( @{$module_details->{entries}{entries}}) |
|
0
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
{ |
350
|
0
|
0
|
|
|
|
|
if($record->{'package name'} eq $module) |
351
|
|
|
|
|
|
|
{ |
352
|
0
|
|
|
|
|
|
$distribution = "$cpan_mini/authors/id/$record->{'path'}" ; |
353
|
0
|
|
|
|
|
|
last ; |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
0
|
|
|
|
|
|
return $distribution ; |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
sub generate_cache |
363
|
|
|
|
|
|
|
{ |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=head2 generate_cache($cpan_mini, $mcd_cache) |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
Checks the state of the B cache and regenerates it if necessary. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
I |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=over 2 |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=item $cpan_mini - Location of the CPAN::MINI repository |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=item $mcd_cache - Location of the cache maintained by CPAN::Mini::ProjectDocs |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=back |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
I - Nothing |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
I - None |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=cut |
384
|
|
|
|
|
|
|
|
385
|
0
|
|
|
0
|
1
|
|
my ($cpan_mini, $mcd_cache) = @_ ; |
386
|
|
|
|
|
|
|
|
387
|
0
|
|
|
|
|
|
my ($modules_details_file, $modules_details_txt_md5_file, $modules_details_cache_file) = get_mcd_paths($cpan_mini, $mcd_cache) ; |
388
|
0
|
|
|
|
|
|
my $modules_details_txt_md5 = get_file_MD5($modules_details_file) ; |
389
|
|
|
|
|
|
|
|
390
|
0
|
0
|
|
|
|
|
if(-e $modules_details_txt_md5_file) |
391
|
|
|
|
|
|
|
{ |
392
|
0
|
|
|
|
|
|
my $mcd_cache_md5 = read_file($modules_details_txt_md5_file) ; |
393
|
|
|
|
|
|
|
|
394
|
0
|
0
|
|
|
|
|
if($mcd_cache_md5 ne $modules_details_txt_md5) |
395
|
|
|
|
|
|
|
{ |
396
|
0
|
|
|
|
|
|
regenerate_cache($cpan_mini, $mcd_cache) ; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
else |
400
|
|
|
|
|
|
|
{ |
401
|
0
|
|
|
|
|
|
regenerate_cache($cpan_mini, $mcd_cache) ; |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
|
404
|
0
|
|
|
|
|
|
return ; |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
sub regenerate_cache |
410
|
|
|
|
|
|
|
{ |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
=head2 regenerate_cache($cpan_mini, $mcd_cache) |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
Generates the B cache. |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
I |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=over 2 |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=item $cpan_mini - Location of the CPAN::MINI repository |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=item $mcd_cache - Location of the cache maintained by CPAN::Mini::ProjectDocs |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=back |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
I - Nothing |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
I - File sytem related errors if any |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=cut |
431
|
|
|
|
|
|
|
|
432
|
0
|
|
|
0
|
1
|
|
my ($cpan_mini, $mcd_cache) = @_ ; |
433
|
|
|
|
|
|
|
|
434
|
0
|
|
|
|
|
|
warn "Generating cache.\n" ; |
435
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
my ($modules_details_file, $modules_details_txt_md5_file, $modules_details_cache_file, $modules_details_cache_all_names) |
437
|
|
|
|
|
|
|
= get_mcd_paths($cpan_mini, $mcd_cache) ; |
438
|
|
|
|
|
|
|
|
439
|
0
|
|
|
|
|
|
my $modules_details_txt_md5 = get_file_MD5($modules_details_file) ; |
440
|
|
|
|
|
|
|
|
441
|
0
|
|
|
|
|
|
my $module_details = CPAN::PackageDetails->read( $modules_details_file ); |
442
|
|
|
|
|
|
|
|
443
|
0
|
|
|
|
|
|
my $count = $module_details->count; |
444
|
0
|
|
|
|
|
|
warn "$count records found.\n" ; |
445
|
|
|
|
|
|
|
|
446
|
0
|
|
|
|
|
|
my $entries_lookup = {} ; |
447
|
0
|
|
|
|
|
|
my @modules ; |
448
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
|
my $entries = $module_details->{entries}; |
450
|
0
|
|
|
|
|
|
my $records = $entries->{entries}; |
451
|
0
|
|
|
|
|
|
for my $record ( @{$records}) |
|
0
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
{ |
453
|
0
|
|
|
|
|
|
push @modules, $record->{'package name'} ; |
454
|
|
|
|
|
|
|
|
455
|
0
|
|
|
|
|
|
my $first_letter = substr($record->{'package name'}, 0, 1) ; |
456
|
0
|
|
|
|
|
|
push @{$entries_lookup->{$first_letter}}, $record ; |
|
0
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
#---------------------------------- |
460
|
|
|
|
|
|
|
|
461
|
0
|
|
|
|
|
|
local $Data::Dumper::Purity = 1 ; |
462
|
0
|
|
|
|
|
|
local $Data::Dumper::Indent = 0 ; |
463
|
|
|
|
|
|
|
|
464
|
0
|
|
|
|
|
|
for(keys %{$entries_lookup}) |
|
0
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
{ |
466
|
0
|
|
|
|
|
|
$module_details->{entries}{entries} = $entries_lookup->{$_} ; |
467
|
0
|
|
|
|
|
|
write_file "${modules_details_cache_file}_$_.txt", Dumper($module_details) , "\n\$VAR1 ;\n" ; |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
|
470
|
0
|
|
|
|
|
|
write_file $modules_details_cache_all_names, Dumper(\@modules), "\n\$VAR1 ;\n" ; |
471
|
0
|
|
|
|
|
|
write_file($modules_details_txt_md5_file, $modules_details_txt_md5) ; |
472
|
|
|
|
|
|
|
|
473
|
0
|
|
|
|
|
|
return ; |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
sub search_modules |
479
|
|
|
|
|
|
|
{ |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=head2 search_modules($cpan_mini, $mcd_cache, $module) |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
Matches I<$module> to all the modules in the CPAN mini repository and displays the match results. |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
I |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=over 2 |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=item $cpan_mini - Location of the CPAN::MINI repository |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=item $mcd_cache - Location of the cache maintained by CPAN::Mini::ProjectDocs |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item $module - Name of the module to match |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=back |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
I - Nothing |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
I |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=cut |
502
|
|
|
|
|
|
|
|
503
|
0
|
|
|
0
|
1
|
|
my ($cpan_mini, $mcd_cache, $module) = @_ ; |
504
|
|
|
|
|
|
|
|
505
|
0
|
|
|
|
|
|
my ($modules_details_file, $modules_details_txt_md5_file, $modules_details_cache_file, $modules_details_cache_all_names) |
506
|
|
|
|
|
|
|
= get_mcd_paths($cpan_mini, $mcd_cache) ; |
507
|
|
|
|
|
|
|
|
508
|
0
|
0
|
|
|
|
|
my $modules = do $modules_details_cache_all_names or carp "Error: Invalid '$modules_details_cache_all_names'!\n"; |
509
|
|
|
|
|
|
|
|
510
|
0
|
|
|
|
|
|
for (@{$modules}) |
|
0
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
{ |
512
|
0
|
0
|
|
|
|
|
print "$_\n" if(/$module/i) ; |
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
#~ use Text::Soundex ; |
516
|
|
|
|
|
|
|
#~ my $soundex = soundex($module) ; |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
#~ for(@{$module_details->{entries}{entries}}) |
519
|
|
|
|
|
|
|
#~ { |
520
|
|
|
|
|
|
|
#~ my $possible_package_soundex = soundex($_->{'package name'}) ; |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
#~ print "\t$_->{'package name'}\n" if $soundex eq $possible_package_soundex ; |
523
|
|
|
|
|
|
|
#~ } |
524
|
|
|
|
|
|
|
|
525
|
0
|
|
|
|
|
|
return ; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------- |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
sub get_file_MD5 |
531
|
|
|
|
|
|
|
{ |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=head2 get_file_MD5($file) |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
Returns the MD5 of the I<$file> argument. |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
I |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=over 2 |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
=item $file - The location of the file to compute an MD5 for |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
=back |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
I - A string containing the file md5 |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
I - fails if the file can't be open |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
=cut |
550
|
|
|
|
|
|
|
|
551
|
0
|
|
|
0
|
1
|
|
my ($file) = @_ ; |
552
|
0
|
0
|
|
|
|
|
open(FILE, $file) or croak "Can't open '$file': $!"; |
553
|
0
|
|
|
|
|
|
binmode(FILE); |
554
|
0
|
|
|
|
|
|
return Digest::MD5->new->addfile(*FILE)->hexdigest ; |
555
|
|
|
|
|
|
|
} |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
1 ; |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=head1 BUGS AND LIMITATIONS |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
None so far. |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
=head1 AUTHOR |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
Nadim ibn hamouda el Khemir |
568
|
|
|
|
|
|
|
CPAN ID: NH |
569
|
|
|
|
|
|
|
mailto: nadim@cpan.org |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
This program is free software; you can redistribute |
574
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=head1 SUPPORT |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
perldoc CPAN::Mini::ProjectDocs |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
You can also look for information at: |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
=over 4 |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
L |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
Please report any bugs or feature requests to L . |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
We will be notified, and then you'll automatically be notified of progress on |
595
|
|
|
|
|
|
|
your bug as we make changes. |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=item * Search CPAN |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
L |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=back |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=head1 SEE ALSO |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
L, elinks |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=cut |