File Coverage

blib/lib/Version/Util.pm
Criterion Covered Total %
statement 130 134 97.0
branch 56 84 66.6
condition 16 23 69.5
subroutine 20 20 100.0
pod 13 13 100.0
total 235 274 85.7


line stmt bran cond sub pod time code
1             package Version::Util;
2              
3 1     1   63743 use 5.010001;
  1         12  
4 1     1   4 use strict;
  1         2  
  1         32  
5 1     1   382 use version 0.77;
  1         1616  
  1         5  
6 1     1   93 use warnings;
  1         2  
  1         52  
7              
8             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
9             our $DATE = '2022-09-22'; # DATE
10             our $DIST = 'Version-Util'; # DIST
11             our $VERSION = '0.732'; # VERSION
12              
13 1     1   4 use Exporter qw(import);
  1         2  
  1         1419  
14             our @EXPORT_OK = qw(
15             cmp_version
16             version_eq version_ne
17             version_lt version_le version_gt version_ge
18             version_between version_in
19              
20             min_version max_version
21              
22             add_version subtract_version
23             );
24              
25             sub cmp_version {
26 3 50   3 1 1072 my $res; eval { $res = version->parse($_[0]) <=> version->parse($_[1]) }; die "Can't cmp_version $_[0] & $_[1]: $@" if $@; $res;
  3         3  
  3         37  
  3         11  
  3         12  
27             }
28              
29             sub version_eq {
30 3 50   3 1 2138 my $res; eval { $res = version->parse($_[0]) == version->parse($_[1]) }; die "Can't version_eq $_[0] & $_[1]: $@" if $@; $res;
  3         3  
  3         32  
  3         12  
  3         11  
31             }
32              
33             sub version_ne {
34 3 50   3 1 1701 my $res; eval { $res = version->parse($_[0]) != version->parse($_[1]) }; die "Can't version_ne $_[0] & $_[1]: $@" if $@; $res;
  3         12  
  3         34  
  3         13  
  3         8  
35             }
36              
37             sub version_lt {
38 3 50   3 1 1802 my $res; eval { $res = version->parse($_[0]) < version->parse($_[1]) }; die "Can't version_lt $_[0] & $_[1]: $@" if $@; $res;
  3         4  
  3         31  
  3         12  
  3         10  
39             }
40              
41             sub version_le {
42 3 50   3 1 1768 my $res; eval { $res = version->parse($_[0]) <= version->parse($_[1]) }; die "Can't version_le $_[0] & $_[1]: $@" if $@; $res;
  3         4  
  3         30  
  3         14  
  3         10  
43             }
44              
45             sub version_gt {
46 3 50   3 1 1757 my $res; eval { $res = version->parse($_[0]) > version->parse($_[1]) }; die "Can't version_gt $_[0] & $_[1]: $@" if $@; $res;
  3         4  
  3         29  
  3         11  
  3         10  
47             }
48              
49             sub version_ge {
50 3 50   3 1 1689 my $res; eval { $res = version->parse($_[0]) >= version->parse($_[1]) }; die "Can't version_ge $_[0] & $_[1]: $@" if $@; $res;
  3         4  
  3         28  
  3         13  
  3         13  
51             }
52              
53             sub version_between {
54 5     5 1 1825 my $v0 = shift;
55 5         6 my $v; eval { $v = version->parse($v0) };
  5         8  
  5         25  
56 5 50       11 die "Can't version_between for $v0: $@" if $@;
57 5         13 while (@_) {
58 7         8 my $v1 = shift;
59 7         9 my $v2 = shift;
60 7 100 100     8 my $return; eval { $return++ if $v >= version->parse($v1) && $v <= version->parse($v2) };
  7         8  
  7         62  
61 7 100       29 return 1 if $return;
62 4 50       10 die "Can't version_between $v1 <= $v0 <= $v2: $@" if $@;
63             }
64 2         7 0;
65             }
66              
67             sub version_in {
68 3     3 1 1798 my $v0 = shift;
69 3         4 my $v; eval { $v = version->parse($v0) };
  3         5  
  3         16  
70 3 50       9 die "Can't version_in for $v0: $@" if $@;
71 3         5 for (@_) {
72 5 100       7 my $return; eval { $return++ if $v == version->parse($_) };
  5         5  
  5         29  
73 5 100       18 return 1 if $return;
74 3 50       7 die "Can't version_in: $v0 == $_: $@" if $@;
75             }
76 1         4 0;
77             }
78              
79             sub _max2 {
80 28 100   28   47 $_[0] > $_[1] ? $_[0] : $_[1];
81             }
82              
83             sub min_version {
84             my @v = sort {
85 1     1 1 1795 my $res; eval { $res = version->parse($a) <=> version->parse($b) };
  3         4  
  3         4  
  3         22  
86 3 50       10 die "Can't min_version: Can't sort $a vs $b: $@" if $@;
87             $res;
88             } @_;
89 1 50       6 @v ? $v[0] : undef;
90             }
91              
92             sub max_version {
93             my @v = sort {
94 1     1 1 2045 my $res; eval { $res = version->parse($a) <=> version->parse($b) };
  3         4  
  3         4  
  3         21  
95 3 50       10 die "Can't max_version: Can't sort $a vs $b: $@" if $@;
96             $res;
97             } @_;
98 1 50       5 @v ? $v[-1] : undef;
99             }
100              
101             sub _add_or_subtract_version {
102 14     14   31 my ($which, $v, $inc) = @_;
103              
104 14         23 state $re = qr/\Av?(\d{1,15})(?:\.(\d{1,3}))?(?:\.(\d{1,3}))?\z/;
105              
106 14 50       140 $v =~ $re or die "Invalid version '$v', must match $re";
107 14         47 my ($v_maj, $v_min, $v_pl) = ($1, $2, $3);
108 14   100     27 $v_min //= '';
109 14   100     45 $v_pl //= '';
110              
111 14 50       62 $inc =~ $re or die "Invalid increment '$inc', must match $re";
112 14         31 my ($inc_maj, $inc_min, $inc_pl) = ($1, $2, $3);
113 14   50     27 $inc_min //= '';
114 14   100     36 $inc_pl //= '';
115              
116 14         28 my $width_min = _max2(length($v_min), length($inc_min));
117 14         23 my $width_pl = _max2(length($v_pl ), length($inc_pl ));
118              
119 14 50       36 $v_min .= "0" x ($width_min-length($v_min)) if $width_min;
120 14 100       24 $v_pl .= "0" x ($width_pl -length($v_pl )) if $width_pl;
121 14 50       25 $inc_min .= "0" x ($width_min-length($inc_min)) if $width_min;
122 14 100       20 $inc_pl .= "0" x ($width_pl -length($inc_pl )) if $width_pl;
123              
124 14 100       26 if ($which eq 'subtract') {
125 4 50       24 $inc_min = "-$inc_min" if length($inc_min);
126 4 100       29 $inc_pl = "-$inc_pl" if length($inc_pl );
127              
128             }
129 14 50 33     32 $v_min = 0 if !length($v_min) && $width_min;
130 14 50 66     34 $v_pl = 0 if !length($v_pl) && $width_pl;
131 14 50 33     23 $inc_min = 0 if !length($inc_min) && $width_min;
132 14 50 66     32 $inc_pl = 0 if !length($inc_pl) && $width_pl;
133              
134 14 100       23 if ($width_pl) {
135 4         6 my $limit = "1" . ("0" x $width_pl);
136 4         6 $v_pl += $inc_pl;
137 4 50       14 if ($v_pl < 0) {
    50          
138 0         0 $v_pl += $limit;
139 0         0 $v_min--;
140             } elsif ($v_pl >= $limit) {
141 0         0 $v_pl -= $limit;
142 0         0 $v_min++;
143             }
144 4         9 $v_pl = ("0" x ($width_pl -length($v_pl))) . $v_pl
145             }
146 14 50       20 if ($width_min) {
147 14         24 my $limit = "1" . ("0" x $width_min);
148 14         23 $v_min += $inc_min;
149 14 100       31 if ($v_min < 0) {
    100          
150 3         5 $v_min += $limit;
151 3         4 $v_maj--;
152             } elsif ($v_min >= $limit) {
153 3         4 $v_min -= $limit;
154 3         7 $v_maj++;
155             }
156 14         27 $v_min = ("0" x ($width_min -length($v_min))) . $v_min;
157             }
158 14         23 $v_maj += $inc_maj;
159 14 100       36 die "Version subtraction results in negative version ($v - $inc)"
160             if $v_maj < 0;
161              
162 13 50       70 $v_maj . ($width_min ? ".$v_min" : '') . ($width_pl ? ".$v_pl" : "");
    100          
163             }
164              
165             sub add_version {
166 10     10 1 2006 _add_or_subtract_version('add', @_);
167             }
168              
169             sub subtract_version {
170 4     4 1 2052 _add_or_subtract_version('subtract', @_);
171             }
172              
173             1;
174             # ABSTRACT: Version-number utilities
175              
176             __END__