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   12 use strict;
  2         5  
  2         50  
3 2     2   8 use warnings;
  2         5  
  2         113  
4 2     2   14 use feature qw/fc/;
  2         4  
  2         171  
5              
6 2     2   11 use Class::Accessor::Lite ro => [qw/mirror_cache logger/];
  2         4  
  2         10  
7              
8 2     2   1067 use List::UtilsBy qw/rev_nsort_by sort_by/;
  2         3413  
  2         118  
9 2     2   14 use Time::Moment;
  2         3  
  2         41  
10 2     2   727 use CPAN::MirrorMerger::Index::Merged;
  2         5  
  2         54  
11 2     2   11 use CPAN::MirrorMerger::Logger::Null;
  2         3  
  2         467  
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         8 return bless \%args => $class;
17             }
18              
19             sub merge {
20 1     1 0 10 my ($self, @mirrors) = @_;
21 1         20 my $now = Time::Moment->now_utc();
22              
23 1         3 my %multiplex_index = ();
24 1         3 for my $mirror (@mirrors) {
25 3         10 my $index = $self->mirror_cache->get_or_fetch_index($mirror);
26 3         5 for my $package_info (@{ $index->packages }) {
  3         9  
27 3         22 $self->logger->debug("add package @{[ $package_info->path ]} from @{[ $mirror->name ]}");
  3         18  
  3         24  
28              
29 3   100     24 my $candidates = ($multiplex_index{$package_info->module} ||= []);
30 3 100       29 if (@$candidates == 0) {
31 2         6 push @$candidates => $package_info;
32 2         5 next;
33             }
34              
35             # optimize for performance
36 1 50       5 if ($candidates->[0]->compareble_version <= $package_info->compareble_version) {
    0          
37 1         4 unshift @$candidates => $package_info;
38 1         3 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   1007 use sort 'stable';
  2         1010  
  2         11  
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   43 my @packages = map { $multiplex_index{$_}[0] } sort_by { fc } keys %multiplex_index;
  2         14  
  2         14  
61              
62 1         7 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__