File Coverage

blib/lib/AnyPAN/Merger/Algorithm/PreferLatestVersion.pm
Criterion Covered Total %
statement 49 54 90.7
branch 3 6 50.0
condition 3 5 60.0
subroutine 11 12 91.6
pod 0 2 0.0
total 66 79 83.5


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