File Coverage

lib/App/Perlbrew/Util.pm
Criterion Covered Total %
statement 60 61 98.3
branch 18 20 90.0
condition 6 8 75.0
subroutine 10 10 100.0
pod 0 6 0.0
total 94 105 89.5


line stmt bran cond sub pod time code
1             package App::Perlbrew::Util;
2 62     62   201673 use strict;
  62         169  
  62         2458  
3 62     62   327 use warnings;
  62         145  
  62         1604  
4 62     62   1069 use 5.008;
  62         223  
5              
6 62     62   352 use Exporter 'import';
  62         166  
  62         52875  
7             our @EXPORT = qw( uniq min editdist files_are_the_same perl_version_to_integer );
8             our @EXPORT_OK = qw( find_similar_tokens );
9              
10             sub uniq {
11 31     31 0 47 my %seen;
12 31         74 grep { !$seen{$_}++ } @_;
  0         0  
13             }
14              
15             sub min(@) {
16 17884     17884 0 21722 my $m = $_[0];
17 17884         24870 for(@_) {
18 53652 100       87001 $m = $_ if $_ < $m;
19             }
20 17884         29049 return $m;
21             }
22              
23             # straight copy of Wikipedia's "Levenshtein Distance"
24             sub editdist {
25 184     184 0 630 my @a = split //, shift;
26 184         447 my @b = split //, shift;
27              
28             # There is an extra row and column in the matrix. This is the
29             # distance from the empty string to a substring of the target.
30 184         233 my @d;
31 184         1122 $d[$_][0] = $_ for (0 .. @a);
32 184         836 $d[0][$_] = $_ for (0 .. @b);
33              
34 184         348 for my $i (1 .. @a) {
35 1931         3143 for my $j (1 .. @b) {
36 19163 100       41107 $d[$i][$j] = ($a[$i-1] eq $b[$j-1] ? $d[$i-1][$j-1]
37             : 1 + min($d[$i-1][$j], $d[$i][$j-1], $d[$i-1][$j-1]));
38             }
39             }
40              
41 184         943 return $d[@a][@b];
42             }
43              
44             sub files_are_the_same {
45             ## Check dev and inode num. Not useful on Win32.
46             ## The for loop should always return false on Win32, as a result.
47              
48 25     25 0 5615 my @files = @_;
49 25         55 my @stats = map {[ stat($_) ]} @files;
  50         715  
50              
51 25         62 my $stats0 = join " ", @{$stats[0]}[0,1];
  25         85  
52 25         58 for (@stats) {
53 50 100 66     211 return 0 if ((! defined($_->[1])) || $_->[1] == 0);
54 49 100       138 unless ($stats0 eq join(" ", $_->[0], $_->[1])) {
55 14         66 return 0;
56             }
57             }
58 10         38 return 1
59             }
60              
61             sub perl_version_to_integer {
62 209     209 0 48595 my $version = shift;
63              
64 209         292 my @v;
65 209 100       372 if ($version eq 'blead') {
66 1         3 @v = (999,999,999);
67             } else {
68 208         776 @v = split(/[\.\-_]/, $version);
69             }
70 209 50       439 return undef if @v < 2;
71              
72 209 100       451 if ($v[1] <= 5) {
73 24   100     55 $v[2] ||= 0;
74 24         36 $v[3] = 0;
75             }
76             else {
77 185 50 66     641 $v[3] ||= $v[1] >= 6 ? 9 : 0;
78 185         414 $v[3] =~ s/[^0-9]//g;
79             }
80              
81 209         583 return $v[1]*1000000 + $v[2]*1000 + $v[3];
82             }
83              
84             sub find_similar_tokens {
85 7     7 0 8730 my ($token, $tokens) = @_;
86 7         12 my $SIMILAR_DISTANCE = 6;
87              
88 51         101 my @similar_tokens = sort { $a->[1] <=> $b->[1] } map {
89 7         17 my $d = editdist( $_, $token );
  178         302  
90 178 100       448 ( ( $d < $SIMILAR_DISTANCE ) ? [$_, $d] : () )
91             } @$tokens;
92              
93 7 100       21 if (@similar_tokens) {
94 6         13 my $best_score = $similar_tokens[0][1];
95 6         12 @similar_tokens = map { $_->[0] } grep { $_->[1] == $best_score } @similar_tokens;
  8         30  
  32         93  
96             }
97              
98 7         72 return \@similar_tokens;
99             }
100              
101             1;