File Coverage

blib/lib/CPAN/Repository/Packages.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package CPAN::Repository::Packages;
2             our $AUTHORITY = 'cpan:GETTY';
3             # ABSTRACT: 02packages
4             $CPAN::Repository::Packages::VERSION = '0.009';
5 2     2   7 use Moo;
  2         2  
  2         9  
6              
7             with qw(
8             CPAN::Repository::Role::File
9             );
10              
11 2     2   1534 use Dist::Data;
  0            
  0            
12             use File::Spec::Functions ':ALL';
13             use IO::File;
14             use DateTime::Format::RFC3339;
15             use DateTime::Format::Epoch::Unix;
16              
17             sub file_parts { 'modules', '02packages.details.txt' }
18             sub file_parts_stamp { 'modules', '02STAMP' }
19              
20             has modules => (
21             is => 'ro',
22             lazy => 1,
23             builder => '_build_modules',
24             );
25              
26             sub _build_modules {
27             my ( $self ) = @_;
28             return {} unless $self->exist;
29             my @lines = $self->get_file_lines;
30             my %modules;
31             for (@lines) {
32             chomp($_);
33             next if ($_ =~ /[^:]:[ \t]/);
34             if ($_ =~ m/^([^ \t]+)[ \t]+([^ \t]+)[ \t]+([^ \t]+)$/) {
35             # $1 = module
36             # $2 = version
37             # $3 = path (inside repository)
38             $modules{$1} = [ $2, $3 ];
39             }
40             }
41             return \%modules;
42             }
43              
44             has authorbase_path_parts => (
45             is => 'ro',
46             required => 1,
47             );
48              
49             has url => (
50             is => 'ro',
51             required => 1,
52             );
53              
54             has written_by => (
55             is => 'ro',
56             required => 1,
57             );
58              
59             sub get_module {
60             my ( $self, $module ) = @_;
61             return defined $self->modules->{$module}
62             ? $self->modules->{$module}->[1]
63             : ();
64             }
65              
66             sub get_module_version {
67             my ( $self, $module ) = @_;
68             return defined $self->modules->{$module}
69             ? $self->modules->{$module}->[0]
70             : ();
71             }
72              
73             sub set_module {
74             my ( $self, $module, $version, $path ) = @_;
75             return $self->modules->{$module} = [ $version, $path ];
76             }
77              
78             sub add_distribution {
79             my ( $self, $author_distribution_path ) = @_;
80             my $filename = catfile( $self->repository_root, @{$self->authorbase_path_parts}, splitdir( $author_distribution_path ) );
81             my $dist = Dist::Data->new( $filename );
82             for (keys %{$dist->packages}) {
83             $self->set_module($_, $dist->packages->{$_}->{version}, $author_distribution_path);
84             }
85             return $self;
86             }
87              
88             sub stamp_filename {
89             my ( $self ) = @_;
90             catfile( $self->repository_root, $self->file_parts_stamp );
91             }
92              
93             after save => sub {
94             my ( $self ) = @_;
95             my $stamp = IO::File->new($self->stamp_filename, "w") or die "cant write to ".$self->stamp_filename;
96             my $now = DateTime->now;
97             print $stamp (DateTime::Format::Epoch::Unix->format_datetime($now).' '.DateTime::Format::RFC3339->new->format_datetime($now)."\n");
98             $stamp->close;
99             };
100              
101             sub timestamp {
102             my ( $self ) = @_;
103             my $stamp = IO::File->new($self->stamp_filename, "r") or die "cant read ".$self->stamp_filename;
104             my ( $line ) = <$stamp>;
105             chomp($line);
106             if ($line =~ /^(\d+) /) {
107             return DateTime::Format::Epoch::Unix->parse_datetime($1);
108             } else {
109             die "cant find unix timestamp from ".$self->stamp_filename;
110             }
111             }
112              
113             sub generate_content {
114             my ( $self ) = @_;
115             my @file_parts = $self->file_parts;
116             my $content = "";
117             $content .= $self->generate_header_line('File:',(pop @file_parts));
118             $content .= $self->generate_header_line('URL:',$self->url.$self->path_inside_root);
119             $content .= $self->generate_header_line('Description:','Package names found in directory $CPAN/authors/id/');
120             $content .= $self->generate_header_line('Columns:','package name, version, path');
121             $content .= $self->generate_header_line('Intended-For:','Automated fetch routines, namespace documentation.');
122             $content .= $self->generate_header_line('Written-By:',$self->written_by);
123             $content .= $self->generate_header_line('Line-Count:',scalar keys %{$self->modules});
124             $content .= $self->generate_header_line('Last-Updated:',DateTime->now->strftime('%a, %e %b %y %T %Z'));
125             $content .= "\n";
126             for (sort { $a cmp $b } keys %{$self->modules}) {
127             $content .= sprintf("%-60s %-20s %s\n",$_,$self->modules->{$_}->[0] ? $self->modules->{$_}->[0] : 'undef',$self->modules->{$_}->[1]);
128             }
129             return $content;
130             }
131              
132             sub generate_header_line {
133             my ( $self, $key, $value ) = @_;
134             return sprintf("%-13s %s\n",$key,$value);
135             }
136              
137             1;
138              
139             __END__