File Coverage

blib/lib/Module/Packaged/Report.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Module::Packaged::Report;
2 1     1   1216 use strict;
  1         4  
  1         45  
3 1     1   6 use warnings;
  1         2  
  1         38  
4              
5 1     1   711 use Module::Packaged qw();
  0            
  0            
6             use Module::Packaged::Generate qw();
7             use HTML::Template qw();
8             use File::Spec qw();
9             use File::Path qw(mkpath);
10             use Parse::CPAN::Packages qw();
11             use App::Cache qw();
12             use YAML qw(Load);
13             #use Data::Dumper qw(Dumper);
14              
15             our $VERSION = '0.04';
16              
17             my @letters = ('A'..'Z');
18             my @distributions;
19             my $yml = <<'END_YAML';
20             ---
21             - name: debian
22             real: Debian Unstable
23             source: debian_unstable
24             title: Debian
25             - name: debian
26             real: Debian Stable
27             source: debian_stable
28             title: ''
29             - name: debian
30             real: Debian Testing
31             source: debian_testing
32             title: ''
33             - name: ubuntu
34             real: Ubuntu Gutsy Gibbon 7.10 main
35             source: ubuntu_gutsy_main
36             title: ''
37             - name: ubuntu
38             real: Ubuntu Gutsy Gibbon 7.10 universe
39             source: ubuntu_gutsy_universe
40             title: ''
41             - name: ubuntu
42             real: Ubuntu Feisty Fawn 7.04 main
43             source: ubuntu_feisty_main
44             title: Ubuntu
45             - name: ubuntu
46             real: Ubuntu Feisty Fawn 7.04 universe
47             source: ubuntu_feisty_universe
48             title: ''
49             - name: ubuntu
50             real: Ubuntu Edgy Eft 6.10 main
51             source: ubuntu_edgy_main
52             title: ''
53             - name: ubuntu
54             real: Ubuntu Edgy Eft 6.10 universe
55             source: ubuntu_edgy_universe
56             title: ''
57             - name: ubuntu
58             real: Ubuntu Dapper Drake 6.06 main
59             source: ubuntu_dapper_main
60             title: ''
61             - name: ubuntu
62             real: Ubuntu Dapper Drake 6.06 universe
63             source: ubuntu_dapper_universe
64             title: ''
65             - name: ubuntu
66             real: Ubuntu Breezy Badger 5.10
67             source: ubuntu_breezy_main
68             title: ''
69             - name: ubuntu
70             real: Ubuntu Hoary Hedgehog 5.04
71             source: ubuntu_hoary_main
72             title: ''
73             - name: ubuntu
74             real: Ubuntu Warty Warthog 4.10
75             source: ubuntu_warty_main
76             title: ''
77             - name: fedora
78             real: Fedora FC2
79             source: fedora
80             title: Fedora
81             - name: freebsd
82             real: FreeBSD
83             source: freebsd
84             title: FreeBSD
85             - name: mandriva
86             real: Mandriva
87             source: mandriva
88             title: Mandriva
89             - name: openbsd
90             real: OpenBSD
91             source: openbsd
92             title: OpenBSD
93             - name: suse
94             real: Suse
95             source: suse
96             title: Suse
97             - name: gentoo
98             real: Gentoo
99             source: gentoo
100             title: Gentoo
101             - name: activeperl_8xx_windows
102             real: ActivePerl 8xx Windows
103             source: activeperl_8xx_windows
104             title: ActivePerl 8xx Windows
105             - name: activeperl_8xx_solaris
106             real: ActivePerl 8xx Solaris
107             source: activeperl_8xx_solaris
108             title: ''
109             - name: activeperl_8xx_linux
110             real: ActivePerl 8xx Linux
111             source: activeperl_8xx_linux
112             title: ''
113             - name: activeperl_8xx_hp-ux
114             real: ActivePerl 8xx HP-UX
115             source: activeperl_8xx_hp-ux
116             title: ''
117             - name: activeperl_8xx_darwin
118             real: ActivePerl 8xx Darwin
119             source: activeperl_8xx_darwin
120             title: ''
121             END_YAML
122              
123              
124             sub new {
125             my ($class, %opts) = @_;
126             usage() if $opts{help};
127             usage() if not ($opts{test} xor $opts{real});
128              
129             @distributions = @{ Load($yml) };
130              
131             my $self = bless {}, $class;
132             $self->{opts} = \%opts;
133             #$self->{p} = Module::Packaged->new();
134             $self->{_timestamp} = time;
135              
136             my $cache = App::Cache->new({ ttl => 60 * 60 * 24 *7 });
137             my $data = $cache->get_url('http://www.cpan.org/modules/02packages.details.txt.gz');
138             $self->{pcp} = Parse::CPAN::Packages->new($data);
139             $self->{count} = {};
140              
141             return $self;
142             }
143              
144             sub collect_data {
145             my ($self) = @_;
146             $self->{p} = Module::Packaged::Generate->new;
147             $self->{p}->fetch_all;
148             }
149              
150             sub _timestamp {
151             my ($self) = @_;
152             return scalar localtime $self->{_timestamp};
153             }
154              
155             sub _list_packages {
156             my ($self) = @_;
157             if ($self->{opts}{test}) {
158             return qw(AcePerl Acme-Buffy CGI DBD-Pg DBI Spreadsheet-ParseExcel);
159             } else {
160             return sort keys %{ $self->{p}{data} };
161             }
162             }
163              
164             sub generate_html_report {
165             my ($self) = @_;
166              
167             my $dir = $self->_dir;
168             mkpath (File::Spec->catfile($dir, 'letters'));
169             mkpath (File::Spec->catfile($dir, 'distros'));
170             mkpath (File::Spec->catfile($dir, 'authors'));
171             mkpath (File::Spec->catfile($dir, 'missing'));
172              
173             $self->_save_style;
174              
175             $self->_process_data;
176              
177             $self->_generate_report_for_letters;
178             $self->_generate_per_distribution_reports;
179             $self->_generate_per_author_report;
180              
181             $self->_generate_missing_reports;
182             $self->_generate_main_index;
183             }
184              
185             sub _process_data {
186             my ($self) = @_;
187              
188             foreach my $dash_name ($self->_list_packages) {
189             my $dists = $self->{p}->check($dash_name);
190             my $name = $dash_name;
191             $name =~ s/-/::/g;
192              
193             $self->{count}{cpan}++;
194             next if 1 >= keys %$dists; # skip modules that are only on CPAN
195              
196             # collect data for list of modules in a single distro
197             foreach my $distro (keys %$dists) {
198             next if $distro eq 'cpan';
199             $self->{count}{$distro}++;
200             push @{ $self->{distros}{$distro} }, {
201             name => $name,
202             version => $dists->{$distro},
203             cpan => $dists->{cpan},
204             };
205             }
206              
207             # collect data for modules by each author
208             my $m = $self->{pcp}->package($name);
209             $dists->{name} = $name;
210             if ($m) {
211             my $d = $m->distribution;
212             push @{ $self->{authors}{uc $d->cpanid} }, $dists;
213             } else {
214             #warn "No package for '$name'\n";
215             }
216             }
217             }
218              
219              
220              
221             sub _generate_main_index {
222             my ($self) = @_;
223             my @letters_hashes = map {{letter => $_}} @letters;
224             my @distros;
225             foreach my $d (@distributions) {
226             push @distros, {
227             title => $d->{real},
228             name => $d->{source},
229             count => $self->{count}{ $d->{source} },
230             };
231             }
232              
233             $self->create_file(
234             template => $self->_index_tmpl(),
235             filename => File::Spec->catfile($self->_dir, "index.html"),
236             params => {
237             letters => \@letters_hashes,
238             footer => $self->_footer(),
239             cpan => $self->{count}{cpan},
240             distros => \@distros,
241             },
242             );
243             }
244              
245             sub _generate_per_distribution_reports {
246             my ($self) = @_;
247             foreach my $distro (keys %{ $self->{distros} }) {
248             #print "$distro\n";
249             my $name = $distro eq 'mandrake' ? 'mandriva' : $distro;
250              
251             $self->create_file(
252             template => $self->_modules_in_distro_report_tmpl,
253             filename => File::Spec->catfile($self->_dir, 'distros', "$name.html"),
254             params => {
255             distro => ucfirst($name),
256             modules => $self->{distros}{$distro},
257             },
258             );
259             }
260             }
261              
262             sub _generate_per_author_report {
263             my ($self) = @_;
264              
265             foreach my $cpanid (keys %{ $self->{authors} }) {
266             my @modules;
267             foreach my $module (@{ $self->{authors}{$cpanid}}) {
268             my @dists;
269             foreach my $d (@distributions) {
270             push @dists, {version => $module->{ $d->{source} } || ''}
271             }
272             push @modules, {
273             name => $module->{name},
274             cpan => $module->{cpan},
275             distros => \@dists,
276             };
277             }
278              
279             $self->create_file(
280             template => $self->_per_author_report_tmpl,
281             filename => File::Spec->catfile($self->_dir, 'authors', "$cpanid.html"),
282             params => {
283             modules => \@modules,
284             footer => $self->_footer(),
285             cpanid => $cpanid,
286             },
287             );
288             }
289             my @cpanids = map {{cpanid => $_}} sort keys %{ $self->{authors} };
290             $self->create_file(
291             template => $self->_authors_index_tmpl(),
292             filename => File::Spec->catfile($self->_dir, 'authors', "index.html"),
293             params => {
294             ids => \@cpanids,
295             footer => $self->_footer(),
296             },
297             );
298             }
299              
300             sub _generate_report_for_letters {
301             my ($self) = @_;
302             foreach my $letter (@letters) {
303             $self->_generate_report_for_letter($letter);
304             }
305             }
306             sub _generate_report_for_letter {
307             my ($self, $letter) = @_;
308              
309             my @module_names = grep {/^$letter/i} $self->_list_packages;
310             my @modules;
311             foreach my $dash_name (@module_names) {
312             my @dists;
313             my $dists = $self->{p}->check($dash_name);
314             my $name = $dash_name;
315             $name =~ s/-/::/g;
316             foreach my $d (@distributions) {
317             next if not $d->{title};
318             push @dists, {version => $dists->{ $d->{source} } || ''};
319             }
320              
321             push @modules, {
322             cpan => $dists->{cpan},
323             name => $name,
324             distros => \@dists,
325             };
326             }
327              
328             my @distribution_titles = map { {title => $_->{title} } }
329             grep { $_->{title} } @distributions;
330              
331             $self->create_file(
332             template => $self->_report_tmpl(),
333             filename => File::Spec->catfile($self->_dir, 'letters', "$letter.html"),
334             params => {
335             distributions => \@distribution_titles,
336             modules => \@modules,
337             footer => $self->_footer(),
338             },
339             );
340             }
341             sub _generate_missing_reports {
342             my ($self) = @_;
343             my @misses = (
344             [
345             'debian_unstable',
346             ['ubuntu_gutsy_main', 'ubuntu_gutsy_universe'],
347             "from_ubuntu.html",
348             "Available in Debian Unstable but missing from Ubuntu Gutsy (or different version)",
349             ],
350             [
351             'freebsd',
352             ['debian_unstable'],
353             "from_debian.html",
354             "Available in FreeBSD but missing from Debian Unstable",
355             ],
356             );
357              
358             foreach my $m (@misses) {
359             $self->_generate_missing_from(@$m);
360             }
361              
362             my @links = map { {title => $_->[3], file => $_->[2]} } @misses;
363              
364             $self->create_file(
365             template => $self->_missing_index_tmpl(),
366             filename => File::Spec->catfile($self->_dir, 'missing', "index.html"),
367             params => {
368             footer => $self->_footer(),
369             links => \@links,
370             },
371             );
372             }
373              
374             # List all the modules that are available in Debian unstable and not in Ubuntu Gutsy
375             sub _generate_missing_from {
376             my ($self, $distro_has, $distro_misses, $filename, $title) = @_;
377             my @missing;
378             MODULE:
379             foreach my $module (@{ $self->{distros}{$distro_has} }) {
380             (my $dash_name = $module->{name}) =~ s/::/-/g;
381             my $dists = $self->{p}->check($dash_name);
382             foreach my $misses (@$distro_misses) {
383             next MODULE if $dists->{$misses} and $dists->{$misses} eq $dists->{debian_unstable};
384             }
385             my $cpanid = '';
386             if (my $m = $self->{pcp}->package($module->{name})) {
387             if (my $d = $m->distribution) {
388             $cpanid = uc($d->cpanid);
389             }
390             } else {
391             warn "'$module->{name}' has no author!\n";
392             }
393            
394             push @missing, {
395             name => $module->{name},
396             url => ($cpanid ? "../authors/$cpanid.html" : ''),
397             };
398             }
399             $self->create_file(
400             template => $self->_missing_modules_tmpl(),
401             filename => File::Spec->catfile($self->_dir, 'missing', $filename),
402             params => {
403             title => $title,
404             modules => \@missing,
405             footer => $self->_footer(),
406             },
407             );
408              
409              
410             }
411              
412             sub create_file {
413             my ($self, %args) = @_;
414              
415             my $t = HTML::Template->new_scalar_ref(\$args{template}, die_on_bad_params => 1);
416             $t->param(%{ $args{params} });
417             open my $fh, '>', $args{filename} or die "Could not open '$args{filename}' $!";
418             print {$fh} $t->output;
419             }
420              
421             sub _footer {
422             my ($self) = @_;
423            
424             my $template = $self->_footer_tmpl();
425             my $t = HTML::Template->new_scalar_ref(\$template, die_on_bad_params => 1);
426             $t->param(timestamp => $self->_timestamp);
427             $t->param(mp_version => $Module::Packaged::VERSION);
428             $t->param(mpr_version => $VERSION);
429             return $t->output;
430             }
431              
432            
433             sub _dir {
434             my ($self) = @_;
435             return $self->{opts}{dir} || './report';
436             }
437              
438              
439             sub usage {
440             print <<"USAGE";
441             Usage: $0
442             --test test run using small number of modules
443             --real real run
444             You have to provide either test or real
445              
446             --dir DIR name of the directory where the reports are generated (defaults to ./report)
447              
448             --help this help
449             USAGE
450              
451             exit;
452             }
453              
454              
455              
456             ############################### Templates ########################
457             # for the time we might generate the column titles
458             #<tr>
459             # <td></td>
460             # <TMPL_LOOP packagers>
461             # <td><TMPL_VAR name></td>
462             # </TMPL_LOOP>
463             #</tr>
464              
465             sub _save_style {
466             my ($self) = @_;
467              
468             my $filename = File::Spec->catfile($self->_dir, "style.css");
469             open my $fh, '>', $filename or die $!;
470             print {$fh} <<'END_CSS';
471             <style type="text/css">
472            
473             first_one_is_not_seen_by_firefox {
474             }
475            
476             h1 {
477             color: #000000;
478             text-align: center;
479             }
480            
481             body {
482             background-color: #FFFFFF;
483             font-size: 12px;
484             }
485             table {
486             border-width: 1px;
487             border-style: solid;
488             }
489             td {
490             border-width: 1px;
491             border-style: solid;
492             text-align: center;
493             font-size: 12px;
494             }
495              
496             .internal {
497             border-style: none;
498             }
499              
500             .name {
501             text-align: left;
502             }
503             </style>
504              
505             END_CSS
506              
507             }
508              
509             sub _authors_index_tmpl {
510             return <<'END_TMPL';
511             <html>
512             <head>
513             <title>CPAN Modules in Distributions per author</title>
514             <link rel="stylesheet" type="text/css" href="../style.css" />
515             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
516             <meta http-equiv="Content-Style-Type" content="text/css" />
517             </head>
518             <body>
519             <center><h1>CPAN Modules in Distributions per author</h1></center>
520             <p>
521             <a href="../index.html">index</a>
522             <p>
523             <TMPL_LOOP ids>
524             <a href="<TMPL_VAR cpanid>.html"><TMPL_VAR cpanid></a><br />
525             </TMPL_LOOP>
526             <TMPL_VAR footer>
527             </body>
528             </html>
529             END_TMPL
530              
531             }
532             sub _index_tmpl {
533             return <<'END_TMPL';
534             <html>
535             <head>
536             <title>CPAN Modules in Distributions</title>
537             <link rel="stylesheet" type="text/css" href="style.css" />
538             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
539             <meta http-equiv="Content-Style-Type" content="text/css" />
540             </head>
541             <body>
542             <center><h1>CPAN Modules in Distributions</h1></center>
543             Modules starting with letter
544             <TMPL_LOOP letters>
545             <a href="letters/<TMPL_VAR letter>.html"><TMPL_VAR letter></a>&nbsp;
546             </TMPL_LOOP>
547             <p>
548             <a href="authors/">Authors</a>
549             <p>
550             <a href="missing/">Missing reports</a>
551             <p>
552             Total number of modules in each distribution:
553             <table>
554             <tr><td class="name">CPAN</td><td><TMPL_VAR cpan></td></tr>
555             <TMPL_LOOP distros>
556             <tr><td class="name"><TMPL_VAR title></td><td><a href="distros/<TMPL_VAR name>.html"><TMPL_VAR count></a></td></tr>
557             </TMPL_LOOP>
558             </table>
559              
560             <p>
561             Wishes:
562             <ul>
563             <li>Include <strike>Ubuntu</strike>, RedHat, <strike>Gentoo</strike>, Sun Solaris, AIX, HP-UNIX etc</li>
564             <li><strike>Separate Debian stable and testing</strike></li>
565             <li>At least in Ubuntu separate the report for standard, universe and backport repositories</li>
566             <li><strike>Include ActiveState distributions</strike></li>
567             <li>Include ActiveState distributions for older Perl versions</li>
568             </ul>
569             </p>
570              
571             <TMPL_VAR footer>
572             </body>
573             </html>
574             END_TMPL
575              
576             }
577              
578             sub _modules_in_distro_report_tmpl {
579             return <<'END_TMPL';
580             <html>
581             <head>
582             <title>CPAN Modules in <TMPL_VAR distro></title>
583             <link rel="stylesheet" type="text/css" href="../style.css" />
584             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
585             <meta http-equiv="Content-Style-Type" content="text/css" />
586             </head>
587             <body>
588             <h1>CPAN Modules in <TMPL_VAR distro></h1>
589             <a href="../index.html">index</a>
590             <table>
591             <tr><td>Name</td>
592             <td>Version</td>
593             <td>Latest on CPAN</td>
594             <TMPL_LOOP modules><tr><td class="name"><TMPL_VAR name></td><td><TMPL_VAR version></td><td><TMPL_VAR cpan></td></tr>
595             </TMPL_LOOP>
596             </table>
597              
598             <TMPL_VAR footer>
599              
600             </body>
601             </html>
602             END_TMPL
603              
604             }
605              
606             sub _per_author_report_tmpl {
607             return <<'END_TMPL';
608             <html>
609             <head>
610             <title>CPAN Modules of <TMPL_VAR cpanid> in Distributions</title>
611             <link rel="stylesheet" type="text/css" href="../style.css" />
612             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
613             <meta http-equiv="Content-Style-Type" content="text/css" />
614             </head>
615             <body>
616             <h1>CPAN Modules of <TMPL_VAR cpanid> in Distributions</h1>
617             <a href="../index.html">index</a>
618             <table>
619             <tr><td rowspan="2"></td>
620             <td rowspan="2">CPAN</td>
621              
622             <td colspan="3">Debian</td>
623             <td colspan="11">Ubuntu</td>
624              
625             <td rowspan="2">Fedora</td>
626             <td rowspan="2">FreeBSD</td>
627             <td rowspan="2">Mandriva</td>
628             <td rowspan="2">OpenBSD</td>
629             <td rowspan="2">Suse</td>
630             <td rowspan="2">Gentoo</td>
631              
632             <td colspan="5">ActivePerl 8xx</td>
633             </tr>
634              
635             <tr>
636             <td class="internal">Testing</td>
637             <td class="internal">Unstable</td>
638             <td class="internal">Stable</td>
639              
640             <td class="internal">Gutsy Gibbon 7.10 main</td>
641             <td class="internal">Gutsy Gibbon 7.10 universe</td>
642             <td class="internal">Feisty Fawn 7.04 main</td>
643             <td class="internal">Feisty Fawn 7.04 universe</td>
644             <td class="internal">Edgy Eft 6.10 main</td>
645             <td class="internal">Edgy Eft 6.10 universe</td>
646             <td class="internal">Dapper Drake 6.06 main</td>
647             <td class="internal">Dapper Drake 6.06 universe</td>
648             <td class="internal">Breezy Badger 5.10</td>
649             <td class="internal">Hoary Hedgehog 5.04</td>
650             <td class="internal">Warty Warthog 4.10</td>
651              
652             <td class="internal">Windows</td>
653             <td class="internal">Solaris</td>
654             <td class="internal">Linux</td>
655             <td class="internal">HP-UX</td>
656             <td class="internal">Darwin</td>
657             </tr>
658             <TMPL_LOOP modules>
659             <tr>
660             <td class="name"><TMPL_VAR name></td>
661             <td><TMPL_VAR cpan></td>
662             <TMPL_LOOP distros>
663             <td><TMPL_VAR version></td>
664             </TMPL_LOOP>
665             </tr>
666             </TMPL_LOOP>
667             </table>
668              
669             <TMPL_VAR footer>
670              
671             </body>
672             </html>
673             END_TMPL
674              
675             }
676              
677              
678             sub _report_tmpl {
679             return <<'END_TMPL';
680             <html>
681             <head>
682             <title>CPAN Modules in Distributions</title>
683             <link rel="stylesheet" type="text/css" href="../style.css" />
684             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
685             <meta http-equiv="Content-Style-Type" content="text/css" />
686             </head>
687             <body>
688             <h1>CPAN Modules in Distributions</h1>
689             <a href="../index.html">index</a>
690             <table>
691             <tr><td></td>
692             <td>CPAN</td>
693             <TMPL_LOOP distributions>
694             <td><TMPL_VAR title></td>
695             </TMPL_LOOP>
696             <TMPL_LOOP modules>
697              
698             <tr>
699             <td class="name"><TMPL_VAR name></td>
700             <td><TMPL_VAR cpan></td>
701             <TMPL_LOOP distros>
702             <td><TMPL_VAR version></td>
703             </TMPL_LOOP>
704             </tr>
705              
706             </TMPL_LOOP>
707             </table>
708              
709             <TMPL_VAR footer>
710              
711             </body>
712             </html>
713             END_TMPL
714              
715             }
716              
717             sub _footer_tmpl {
718             return <<'END_TMPL';
719             <p>
720             Report generated on <TMPL_VAR timestamp>
721             using <a href="http://search.cpan.org/dist/Module-Packaged-Report">Module::Packaged::Report</a>
722             version <TMPL_VAR mpr_version>
723             and <a href="http://search.cpan.org/dist/Module-Packaged">Module::Packaged</a> version <TMPL_VAR mp_version>.
724             Patches to both modules are welcome by the respective authors. Subversion repository of
725             <a href="http://svn1.hostlocal.com/szabgab/trunk/Module-Packaged-Report/">Module-Packaged-Report</a>
726             and the Subversion repository of the patched version of
727             <a href="http://svn1.hostlocal.com/szabgab/trunk/Module-Packaged-0.86/">Module-Packaged</a> where you
728             can see how the data is being collected.
729             </p>
730             END_TMPL
731              
732             }
733              
734             sub _missing_index_tmpl {
735             return <<'END_TMPL';
736             <html>
737             <head>
738             <title>CPAN Modules in Distributions - Missing reports</title>
739             <link rel="stylesheet" type="text/css" href="../style.css" />
740             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
741             <meta http-equiv="Content-Style-Type" content="text/css" />
742             </head>
743             <body>
744             <center><h1>CPAN Modules in Distributions - missing reports</h1></center>
745             <p>
746             <a href="../index.html">index</a>
747             <p>
748             <i>"Missing file cannot be found"</i>
749             </p>
750             <p>
751             <TMPL_LOOP links>
752             <a href="<TMPL_VAR file>"><TMPL_VAR title></a><br />
753             </TMPL_LOOP>
754             </p>
755             <TMPL_VAR footer>
756             </body>
757             </html>
758             END_TMPL
759              
760             }
761              
762             sub _missing_modules_tmpl {
763             return <<'END_TMPL';
764             <html>
765             <head>
766             <title><TMPL_VAR title></title>
767             <link rel="stylesheet" type="text/css" href="../style.css" />
768             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
769             <meta http-equiv="Content-Style-Type" content="text/css" />
770             </head>
771             <body>
772             <center><h1><TMPL_VAR title></h1></center>
773             <p>
774             <a href="../index.html">index</a>
775             <p>
776             <i>"Missing file cannot be found"</i>
777             </p>
778             <p>
779             <ul>
780             <TMPL_LOOP modules>
781             <TMPL_IF url>
782             <li><a href="<TMPL_VAR url>"><TMPL_VAR name></a></li>
783             <TMPL_ELSE>
784             <li><TMPL_VAR name></li>
785             </TMPL_IF>
786             </TMPL_LOOP>
787             </ul>
788             </p>
789             <TMPL_VAR footer>
790             </body>
791             </html>
792             END_TMPL
793              
794             }
795              
796              
797             =head1 NAME
798              
799             Module::Packaged::Report - Generate report upon packages of CPAN distributions
800              
801             =head1 SYNOPSIS
802              
803             Run the create_package_report.pl script that comes with the module.
804              
805             =head1 DESCRIPTION
806              
807             Using L<Module::Packaged> to fetch the collected data.
808              
809             Create table of CPAN modules vs. Distributions (e.g. Linux distributions, Solaris compiled packages etc)
810             that will show for each module and distro which version (if any) of the CPAN module is available
811             for that distro in it standard packaging system.
812              
813             =head1 METHODS
814              
815             =head2 new
816              
817             my $mpr = Module::Packaged::Report->new(%OPTIONS);
818              
819             %OPTIONS can be
820              
821             test => 1 or real => 1
822              
823             help => 1 to get help
824              
825             dir => /path/to/dir
826              
827            
828             =head2 generate_html_report;
829              
830             $mpr->generate_html_report;
831              
832              
833             =head1 TODO
834              
835             Add more distributions.
836              
837             Coloring, so it will be obvious which distribution carries the latest version and
838             which one has a huge? gap.
839              
840             Explain this!
841             Total number of modules on cpan is reported as 12422 while www.cpan.org reports 11563.
842              
843             Generate SQLite database of all the raw data to be queried?
844              
845             =head1 See also
846              
847             L<Module::Packaged> and L<Module::Packaged::Generate>
848              
849             L<Parse::Debian::Packages> L<Debian::Package::HTML>
850              
851             =head1 COPYRIGHT
852              
853             Copyright (c) 2007 Gabor Szabo. All rights reserved. This program is
854             free software; you can redistribute it and/or modify it under the same
855             terms as Perl itself.
856              
857             =head1 AUTHOR
858              
859             Gabor Szabo <gabor@pti.co.il>
860              
861             =cut
862              
863             1;
864              
865