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   14 use strict;
  2         3  
  2         59  
3 2     2   9 use warnings;
  2         5  
  2         66  
4              
5 2     2   10 use Class::Accessor::Lite ro => [qw/headers packages/], new => 1;
  2         4  
  2         15  
6              
7 2     2   1024 use CPAN::MirrorMerger::PackageInfo;
  2         6  
  2         62  
8              
9 2     2   1197 use IO::Compress::Gzip;
  2         86010  
  2         130  
10 2     2   1244 use IO::Uncompress::Gunzip;
  2         30892  
  2         1201  
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 65 my ($class, $index_path, $mirror) = @_;
25              
26 4         21 my $fh = IO::Uncompress::Gunzip->new($index_path->openr_raw);
27              
28 4         9590 my %headers;
29             my @packages;
30              
31 4         12 my $context = 'header';
32 4         23 while (defined(my $line = <$fh>)) {
33 41         2669 chomp $line;
34 41 100       81 if ($line eq '') {
35 4         8 $context = 'index';
36 4         16 next;
37             }
38              
39 37 100       76 if ($context eq 'header') {
    50          
40 32         161 my ($key, $value) = split /\s*:\s*/, $line;
41 32         127 $headers{$key} = $value;
42             } elsif ($context eq 'index') {
43 5         29 my ($module, $version, $path) = split /\s+/, $line;
44              
45 5         43 push @packages => CPAN::MirrorMerger::PackageInfo->new(
46             mirror => $mirror,
47             module => $module,
48             version => $version,
49             path => $path,
50             );
51             }
52             }
53              
54 4         118 return $class->new(
55             headers => \%headers,
56             packages => \@packages,
57             );
58             }
59              
60             sub save {
61 1     1 0 5 my ($self, $storage) = @_;
62              
63 1         8 my $tempfile = Path::Tiny->tempfile(UNKINK => 1);
64              
65             # write index
66 1         726 my $fh = $tempfile->openw_raw();
67 1         152 $self->_write_to($fh);
68 1 50       463 close $fh or die "$!: $tempfile";
69              
70 1         66 $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       11 my $fh = IO::Compress::Gzip->new($raw_fh)
76             or die $IO::Compress::Gzip::GzipError;
77              
78 1         1811 my %header = %{ $self->headers };
  1         11  
79 1         20 for my $name (@WELLKNOWN_HEADERS) {
80 8         555 my $value = delete $header{$name};
81 8         31 printf $fh "%-14s%s\n", "$name:", $value;
82             }
83 1         64 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         9 print $fh "\n";
88              
89 1         66 for my $package_info (@{ $self->packages }) {
  1         8  
90 2         81 printf $fh "%-35s %6s %s\n", $package_info->module, $package_info->version, $package_info->path;
91             }
92              
93 1 50       73 close $fh
94             or die $IO::Compress::Gzip::GzipError;
95             }
96              
97             1;
98             __END__