File Coverage

blib/lib/CPAN/MirrorMerger/Algorithm/PreferLatestVersion.pm
Criterion Covered Total %
statement 52 57 91.2
branch 3 6 50.0
condition 3 5 60.0
subroutine 12 13 92.3
pod 0 2 0.0
total 70 83 84.3


line stmt bran cond sub pod time code
1             package CPAN::MirrorMerger::Algorithm::PreferLatestVersion;
2 2     2   14 use strict;
  2         6  
  2         76  
3 2     2   12 use warnings;
  2         6  
  2         115  
4 2     2   15 use feature qw/fc/;
  2         2  
  2         197  
5              
6 2     2   13 use Class::Accessor::Lite ro => [qw/mirror_cache logger/];
  2         4  
  2         14  
7              
8 2     2   1307 use List::UtilsBy qw/rev_nsort_by sort_by/;
  2         4010  
  2         159  
9 2     2   17 use Time::Moment;
  2         4  
  2         51  
10 2     2   941 use CPAN::MirrorMerger::Index::Merged;
  2         6  
  2         68  
11 2     2   14 use CPAN::MirrorMerger::Logger::Null;
  2         8  
  2         582  
12              
13             sub new {
14 1     1 0 5 my ($class, %args) = @_;
15 1   33     5 $args{logger} ||= CPAN::MirrorMerger::Logger::Null->instance();
16 1         9 return bless \%args => $class;
17             }
18              
19             sub merge {
20 1     1 0 13 my ($self, @mirrors) = @_;
21 1         28 my $now = Time::Moment->now_utc();
22              
23 1         4 my %multiplex_index = ();
24 1         3 for my $mirror (@mirrors) {
25 3         13 my $index = $self->mirror_cache->get_or_fetch_index($mirror);
26 3         8 for my $package_info (@{ $index->packages }) {
  3         12  
27 3         30 $self->logger->debug("add package @{[ $package_info->path ]} from @{[ $mirror->name ]}");
  3         22  
  3         31  
28              
29 3   100     29 my $candidates = ($multiplex_index{$package_info->module} ||= []);
30 3 100       36 if (@$candidates == 0) {
31 2         6 push @$candidates => $package_info;
32 2         7 next;
33             }
34              
35             # optimize for performance
36 1 50       7 if ($candidates->[0]->compareble_version <= $package_info->compareble_version) {
    0          
37 1         4 unshift @$candidates => $package_info;
38 1         4 next;
39             } elsif ($candidates->[-1]->compareble_version >= $package_info->compareble_version) {
40 0         0 push @$candidates => $package_info;
41 0         0 next;
42             }
43              
44 2     2   1177 use sort 'stable';
  2         1226  
  2         12  
45 0         0 push @$candidates => $package_info;
46 0     0   0 @$candidates = rev_nsort_by { $_->compareble_version } @$candidates;
  0         0  
47             }
48             }
49              
50 1         5 my %headers = (
51             File => '02packages.details.txt',
52             URL => '/modules/02packages.details.txt',
53             Description => 'Merged CPAN Mirrors ('.(join ', ', sort map $_->name, @mirrors).')',
54             Columns => 'package name, version, path',
55             'Intended-For' => 'Automated fetch routines, namespace documentation.',
56             'Written-By' => 'CPAN::MirrorMerger',
57             'Line-Count' => scalar keys %multiplex_index,
58             'Last-Updated' => $now->strftime('%a, %d %b %Y %H:%M:%S %Z'),
59             );
60 1     2   64 my @packages = map { $multiplex_index{$_}[0] } sort_by { fc } keys %multiplex_index;
  2         18  
  2         18  
61              
62 1         11 return CPAN::MirrorMerger::Index::Merged->new(
63             headers => \%headers,
64             packages => \@packages,
65             mirrors => \@mirrors,
66             mirror_cache => $self->mirror_cache,
67             multiplex_index => \%multiplex_index,
68             logger => $self->logger,
69             );
70             }
71              
72              
73             1;
74             __END__