File Coverage

blib/lib/Versioning/Scheme/Python.pm
Criterion Covered Total %
statement 67 84 79.7
branch 23 44 52.2
condition 15 19 78.9
subroutine 12 12 100.0
pod 5 5 100.0
total 122 164 74.3


line stmt bran cond sub pod time code
1             package Versioning::Scheme::Python;
2              
3             our $DATE = '2018-11-18'; # DATE
4             our $VERSION = '0.001'; # VERSION
5              
6 1     1   83876 use 5.010001;
  1         9  
7 1     1   4 use strict;
  1         2  
  1         16  
8 1     1   3 use warnings;
  1         2  
  1         28  
9              
10 1     1   454 use Role::Tiny;
  1         3453  
  1         4  
11 1     1   497 use Role::Tiny::With;
  1         224  
  1         69  
12             with 'Role::Versioning::Scheme';
13 1     1   354 use PerlX::Maybe;
  1         1970  
  1         3  
14 1     1   440 use Python::Version;
  1         4969  
  1         712  
15              
16             sub is_valid_version {
17 3     3 1 1166 my ($self, $v) = @_;
18 3         5 eval { Python::Version->parse($v) };
  3         12  
19 3 100       186 $@ ? 0:1;
20             }
21              
22             sub parse_version {
23 2     2 1 2769 my ($self, $v) = @_;
24              
25 2         4 my $vp;
26 2         3 eval { $vp = Python::Version->parse($v) };
  2         5  
27 2 100       77 return undef if $@;
28             +{
29             maybe epoch => $vp->{_epoch},
30             maybe base => $vp->{_base_version},
31             maybe prerelease => $vp->{_prerelease},
32             maybe postrelease => $vp->{_postrelease},
33             maybe devrelease => $vp->{_devrelease},
34             maybe local => $vp->{_local_version},
35 1         26 };
36             }
37              
38             sub normalize_version {
39 2     2 1 3102 my ($self, $v) = @_;
40 2         7 Python::Version->parse($v)->normal;
41             }
42              
43             sub cmp_version {
44 4     4 1 4219 my ($self, $v1, $v2) = @_;
45              
46 4         11 Python::Version->parse($v1) <=> Python::Version->parse($v2);
47             }
48              
49             sub bump_version {
50 14     14 1 9275 my ($self, $v, $opts) = @_;
51 14   100     56 $opts //= {};
52 14   100     40 $opts->{num} //= 1;
53 14   100     34 $opts->{part} //= -1;
54 14   100     42 $opts->{reset_smaller} //= 1;
55              
56 14         34 my $vp = Python::Version->parse($v);
57 13 100       826 die "Invalid 'num', must be non-zero" unless $opts->{num} != 0;
58              
59 12 100       53 if ($opts->{part} =~ /\A-?\d+\z/) {
    50          
    0          
    0          
    0          
60 1         11 die "Invalid 'part', must not be smaller than -".@{$vp->{_base_version}}
61 10 100       15 if $opts->{part} < -@{ $vp->{_base_version} };
  10         25  
62 0         0 die "Invalid 'part', must not be larger than ".$#{$vp->{_base_version}}
63 9 50       13 if $opts->{part} > $#{$vp->{_base_version}};
  9         19  
64              
65 9 100       15 my $idx = $opts->{part}; $idx = @{$vp->{_base_version}} + $idx if $idx < 0;
  9         15  
  8         13  
66             # for now, we do not allow decreasing that overflow to the next more
67             # significant part
68             die "Cannot decrease version, would result in a negative part"
69 9 100       26 if $vp->{_base_version}[$idx] + $opts->{num} < 0;
70 8         10 my $i = $idx;
71 8         12 my $left = $opts->{num};
72 8         8 while (1) {
73 8 50 66     35 if ($i == 0 || $vp->{_base_version}[$i]+$left < 1000) {
74 8         14 $vp->{_base_version}[$i] += $left;
75 8         9 $left = 0;
76 8         11 last;
77             } else {
78 0         0 my $tmp = $vp->{_base_version}[$i] + $left;
79 0         0 $vp->{_base_version}[$i] = $tmp % 1000;
80 0         0 $left = int($tmp / 1000);
81 0         0 $i--;
82 0         0 next;
83             }
84             }
85 8 100 100     25 if ($opts->{reset_smaller} && $opts->{num} > 0) {
86 4 50       8 $idx = @{$vp->{_base_version}} + $idx if $idx < 0;
  0         0  
87 4         5 for my $i ($idx+1 .. $#{$vp->{_base_version}}) {
  4         11  
88 3         6 $vp->{_base_version}[$i] = 0;
89             }
90             }
91             } elsif ($opts->{part} =~ /\A(a|b|rc)\z/) {
92             die "Can't bump version: no $opts->{part} part"
93 2 100 66     20 unless $vp->{_prerelease} && $vp->{_prerelease}[0] eq $opts->{part};
94             die "Cannot decrease version, would result in a negative $opts->{part} part"
95 1 50       4 if $vp->{_prerelease}[1] + $opts->{num} < 0;
96 1         3 $vp->{_prerelease}[1] += $opts->{num};
97             } elsif ($opts->{part} eq 'post') {
98             die "Can't bump version: no $opts->{part} part"
99 0 0       0 unless $vp->{_postrelease};
100             die "Cannot decrease version, would result in a negative $opts->{part} part"
101 0 0       0 if $vp->{_postrelease}[1] + $opts->{num} < 0;
102 0         0 $vp->{_postrelease}[1] += $opts->{num};
103             } elsif ($opts->{part} eq 'dev') {
104             die "Can't bump version: no $opts->{part} part"
105 0 0       0 unless $vp->{_devrelease};
106             die "Cannot decrease version, would result in a negative $opts->{part} part"
107 0 0       0 if $vp->{_devrelease}[1] + $opts->{num} < 0;
108 0         0 $vp->{_devrelease}[1] += $opts->{num};
109             } elsif ($opts->{part} eq 'epoch') {
110 0   0     0 $vp->{_epoch} //= 0;
111             die "Cannot decrease version, would result in a negative $opts->{part} part"
112 0 0       0 if $vp->{_epoch} + $opts->{num} < 0;
113 0         0 $vp->{_epoch} += $opts->{num};
114             } else {
115 0         0 die "Invalid part '$opts->{part}'";
116             }
117 9         21 $vp->normal;
118             }
119              
120             1;
121             # ABSTRACT: Python (PEP 440) version numbering
122              
123             __END__