File Coverage

blib/lib/CPAN/MirrorMerger/Index.pm
Criterion Covered Total %
statement 52 54 96.3
branch 8 12 66.6
condition n/a
subroutine 9 9 100.0
pod 0 2 0.0
total 69 77 89.6


line stmt bran cond sub pod time code
1             package CPAN::MirrorMerger::Index;
2 2     2   11 use strict;
  2         3  
  2         48  
3 2     2   8 use warnings;
  2         3  
  2         53  
4              
5 2     2   8 use Class::Accessor::Lite ro => [qw/headers packages/], new => 1;
  2         2  
  2         10  
6              
7 2     2   855 use CPAN::MirrorMerger::PackageInfo;
  2         4  
  2         52  
8              
9 2     2   1003 use IO::Compress::Gzip;
  2         69593  
  2         171  
10 2     2   949 use IO::Uncompress::Gunzip;
  2         24914  
  2         968  
11              
12             my @WELLKNOWN_HEADERS = qw/
13             File
14             URL
15             Description
16             Columns
17             Intended-For
18             Written-By
19             Line-Count
20             Last-Updated
21             /;
22              
23             sub parse {
24 4     4 0 49 my ($class, $index_path, $mirror) = @_;
25              
26 4         13 my $fh = IO::Uncompress::Gunzip->new($index_path->openr_raw);
27              
28 4         7551 my %headers;
29             my @packages;
30              
31 4         9 my $context = 'header';
32 4         18 while (defined(my $line = <$fh>)) {
33 41         2226 chomp $line;
34 41 100       70 if ($line eq '') {
35 4         5 $context = 'index';
36 4         20 next;
37             }
38              
39 37 100       58 if ($context eq 'header') {
    50          
40 32         135 my ($key, $value) = split /\s*:\s*/, $line;
41 32         110 $headers{$key} = $value;
42             } elsif ($context eq 'index') {
43 5         23 my ($module, $version, $path) = split /\s+/, $line;
44              
45 5         30 push @packages => CPAN::MirrorMerger::PackageInfo->new(
46             mirror => $mirror,
47             module => $module,
48             version => $version,
49             path => $path,
50             );
51             }
52             }
53              
54 4         84 return $class->new(
55             headers => \%headers,
56             packages => \@packages,
57             );
58             }
59              
60             sub save {
61 1     1 0 3 my ($self, $storage) = @_;
62              
63 1         5 my $tempfile = Path::Tiny->tempfile(UNKINK => 1);
64              
65             # write index
66 1         599 my $fh = $tempfile->openw_raw();
67 1         118 $self->_write_to($fh);
68 1 50       407 close $fh or die "$!: $tempfile";
69              
70 1         7 $storage->copy($tempfile, 'modules/02packages.details.txt.gz');
71             }
72              
73             sub _write_to {
74 1     1   4 my ($self, $raw_fh) = @_;
75 1 50       8 my $fh = IO::Compress::Gzip->new($raw_fh)
76             or die $IO::Compress::Gzip::GzipError;
77              
78 1         1417 my %header = %{ $self->headers };
  1         8  
79 1         15 for my $name (@WELLKNOWN_HEADERS) {
80 8         432 my $value = delete $header{$name};
81 8         25 printf $fh "%-14s%s\n", "$name:", $value;
82             }
83 1         52 for my $name (sort keys %header) {
84 0         0 my $value = $header{$name};
85 0         0 printf $fh "%-14s%s\n", "$name:", $value;
86             }
87 1         7 print $fh "\n";
88              
89 1         55 for my $package_info (@{ $self->packages }) {
  1         6  
90 2         67 printf $fh "%-35s %6s %s\n", $package_info->module, $package_info->version, $package_info->path;
91             }
92              
93 1 50       61 close $fh
94             or die $IO::Compress::Gzip::GzipError;
95             }
96              
97             1;
98             __END__