diff -Nru libsemver-perl-0.7.0/Build.bat libsemver-perl-0.10.0/Build.bat --- libsemver-perl-0.7.0/Build.bat 2018-07-24 09:14:46.000000000 +0000 +++ libsemver-perl-0.10.0/Build.bat 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -@rem = '--*-Perl-*-- -@echo off -if "%OS%" == "Windows_NT" goto WinNT -perl -x -S "%0" --build_bat %1 %2 %3 %4 %5 %6 %7 %8 %9 -goto endofperl -:WinNT -perl -x -S %0 --build_bat %* -if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl -if %errorlevel% == 9009 echo You do not have Perl in your PATH. -if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul -goto endofperl -@rem '; -#!perl -#line 15 - -use strict; -use Cwd; -use File::Basename; -use File::Spec; - -sub magic_number_matches { - return 0 unless -e '_build\\magicnum'; - my $FH; - open $FH, '<','_build\\magicnum' or return 0; - my $filenum = <$FH>; - close $FH; - return $filenum == 291315; -} - -my $progname; -my $orig_dir; -BEGIN { - $^W = 1; # Use warnings - $progname = basename($0); - $orig_dir = Cwd::cwd(); - my $base_dir = 'D:\\Projects\\Perl\\JoK\\SemVer'; - if (!magic_number_matches()) { - unless (chdir($base_dir)) { - die ("Couldn't chdir($base_dir), aborting\n"); - } - unless (magic_number_matches()) { - die ("Configuration seems to be out of date, please re-run 'perl Build.PL' again.\n"); - } - } - unshift @INC, - ( - - ); - -} - -close(*DATA) unless eof(*DATA); # ensure no open handles to this script - -use Module::Build; -Module::Build->VERSION(q{0}); - -# Some platforms have problems setting $^X in shebang contexts, fix it up here -$^X = Module::Build->find_perl_interpreter; - -if (-e 'Build.PL' and not Module::Build->up_to_date('Build.PL', $progname)) { - warn "Warning: Build.PL has been altered. You may need to run 'perl Build.PL' again.\n"; -} - -# This should have just enough arguments to be able to bootstrap the rest. -my $build = Module::Build->resume ( - properties => { - config_dir => '_build', - orig_dir => $orig_dir, - }, -); - -$build->dispatch; - -__END__ -:endofperl diff -Nru libsemver-perl-0.7.0/Build.PL libsemver-perl-0.10.0/Build.PL --- libsemver-perl-0.7.0/Build.PL 2018-07-24 09:13:45.000000000 +0000 +++ libsemver-perl-0.10.0/Build.PL 2020-05-09 13:57:55.000000000 +0000 @@ -1,30 +1,30 @@ -use strict; -use warnings; -use Module::Build; - -Module::Build->new( - module_name => 'SemVer', - license => 'perl', - configure_requires => { - 'Module::Build' => '0.30', - }, - build_requires => { - 'Module::Build' => '0.30', - 'Test::More' => '0.88', - }, - requires => { - 'version' => 0.82, - 'perl' => 5.008001, - }, - recommends => { - 'Test::Pod' => '1.41', - 'Test::Pod::Coverage' => '1.06', - }, - meta_merge => { - resources => { - homepage => 'http://search.cpan.org/dist/SemVer/', - bugtracker => 'http://github.com/theory/semver/issues/', - repository => 'http://github.com/theory/semver', - } - }, -)->create_build_script; +use strict; +use warnings; +use Module::Build; + +Module::Build->new( + module_name => 'SemVer', + license => 'perl', + configure_requires => { + 'Module::Build' => '0.30', + }, + build_requires => { + 'Module::Build' => '0.30', + 'Test::More' => '0.88', + }, + requires => { + 'version' => 0.82, + 'perl' => 5.008001, + }, + recommends => { + 'Test::Pod' => '1.41', + 'Test::Pod::Coverage' => '1.06', + }, + meta_merge => { + resources => { + homepage => 'https://metacpan.org/release/SemVer', + bugtracker => 'https://github.com/theory/semver/issues/', + repository => 'https://github.com/theory/semver', + } + }, +)->create_build_script; diff -Nru libsemver-perl-0.7.0/Changes libsemver-perl-0.10.0/Changes --- libsemver-perl-0.7.0/Changes 2018-07-24 09:13:45.000000000 +0000 +++ libsemver-perl-0.10.0/Changes 2020-05-09 13:57:55.000000000 +0000 @@ -1,43 +1,61 @@ -Revision history for Perl extension SemVer. - -0.7.0 2018-07-24T11:09:17Z - - Implemented Semantic Versioning 2.0.0 specification - - Updated tests for Semantic Versioning 2.0.0 - - added testing for Perl 5.24, 5.26, 5.28 - -0.6.0 2015-01-23T05:07:58Z - - Removed tests that fail on version.pm 0.9910 and higher due to - trailing decimal sign. Thanks to Andreas Koenig for the report and - diagnosis. - - Fixed vstring warning on Perl 5.8. - - Now skip tests that fail with version::vpp. - - Now skip test on version.pm 0.9911 that fails with that version. - - Now skip failing tests on Perl 5.8 and version.pm less than 0.9909. - - Removed all Pod tests from the distribution. - -0.5.0 2013-04-02T06:57:06Z - - The `new()` now throws an exception when a version string has a - prerelease version with no preceding dash. This is keep its - requirement for strictness consistent. - - Fixed a bug where a SemVer object passed to `new()` did not properly - clone the dash preceding a prerelease version. - -0.4.0 2012-11-20T18:59:33Z - - Updated the parsers to support an optional dash before the prerelease - version, and `normal()` to always emit a dash for the prerelease - version. This brings it in line with the final semver 1.0.0 - specification. - -0.3.0 2011-05-26T04:54:50 - - Made leading zeros, such as the "04" in "1.04.3" illegal when parsing - via `new()`. - - Eliminted "Use of qw(...) as parentheses is deprecated" in the tests - when running on Perl 5.14. - -0.2.0 2010-09-17T17:59:57 - - Require Test::Pod 1.41 for testing POD because it supports - `L`. - -0.1.0 2010-09-16T19:07:04 - - Initial version, created with lots of help and feedback from - version.pm author John Peacock +Revision history for Perl extension SemVer. + +0.10.0 2020-05-09T13:58:26Z + - Adopted the official regular expression from the SemVer FAQ for strict + parsing by new(), as well as a modification of that regex for the more + lenient cases supported by declare() and new(). This results in the + following changes in the behavior of the parser: + + SemVers with build metadata but no prerelease are now valid, e.g. + `1.1.2+meta` + + SemVers with a numeric-only prerelease part are no longer valid + if that part has a leading zero, e.g., `1.2.3-123` is valid but + `1.2.3-0123` is not + + Restored support for prerelease and build metadata parts are in + declare() and parse() + - Added tests for the official SemVer test corpus as linked under the + FAQ about an official regular expression: + https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + - Added explicit boolean overloading to ensure consistent behavior + between different implementations of the version parent class. + +0.7.0 2018-07-24T11:09:17Z + - Implemented Semantic Versioning 2.0.0 specification + - Updated tests for Semantic Versioning 2.0.0 + - added testing for Perl 5.24, 5.26, 5.28 + +0.6.0 2015-01-23T05:07:58Z + - Removed tests that fail on version.pm 0.9910 and higher due to + trailing decimal sign. Thanks to Andreas Koenig for the report and + diagnosis. + - Fixed vstring warning on Perl 5.8. + - Now skip tests that fail with version::vpp. + - Now skip test on version.pm 0.9911 that fails with that version. + - Now skip failing tests on Perl 5.8 and version.pm less than 0.9909. + - Removed all Pod tests from the distribution. + +0.5.0 2013-04-02T06:57:06Z + - The `new()` now throws an exception when a version string has a + prerelease version with no preceding dash. This is keep its + requirement for strictness consistent. + - Fixed a bug where a SemVer object passed to `new()` did not properly + clone the dash preceding a prerelease version. + +0.4.0 2012-11-20T18:59:33Z + - Updated the parsers to support an optional dash before the prerelease + version, and `normal()` to always emit a dash for the prerelease + version. This brings it in line with the final semver 1.0.0 + specification. + +0.3.0 2011-05-26T04:54:50 + - Made leading zeros, such as the "04" in "1.04.3" illegal when parsing + via `new()`. + - Eliminated "Use of qw(...) as parentheses is deprecated" in the tests + when running on Perl 5.14. + +0.2.0 2010-09-17T17:59:57 + - Require Test::Pod 1.41 for testing POD because it supports + `L`. + +0.1.0 2010-09-16T19:07:04 + - Initial version, created with lots of help and feedback from + version.pm author John Peacock diff -Nru libsemver-perl-0.7.0/debian/changelog libsemver-perl-0.10.0/debian/changelog --- libsemver-perl-0.7.0/debian/changelog 2020-02-18 20:38:05.000000000 +0000 +++ libsemver-perl-0.10.0/debian/changelog 2020-05-13 16:05:00.000000000 +0000 @@ -1,3 +1,11 @@ +libsemver-perl (0.10.0-1) unstable; urgency=medium + + * Team upload. + * Import upstream version 0.10.0. + * Update years of upstream copyright. + + -- gregor herrmann Wed, 13 May 2020 18:05:00 +0200 + libsemver-perl (0.7.0-2) unstable; urgency=medium * Team upload. diff -Nru libsemver-perl-0.7.0/debian/copyright libsemver-perl-0.10.0/debian/copyright --- libsemver-perl-0.7.0/debian/copyright 2020-02-18 20:38:05.000000000 +0000 +++ libsemver-perl-0.10.0/debian/copyright 2020-05-13 16:05:00.000000000 +0000 @@ -4,7 +4,7 @@ Upstream-Name: SemVer Files: * -Copyright: 2010-2015, David E. Wheeler +Copyright: 2010-2020, David E. Wheeler License: Artistic or GPL-1+ Files: debian/* diff -Nru libsemver-perl-0.7.0/lib/SemVer.pm libsemver-perl-0.10.0/lib/SemVer.pm --- libsemver-perl-0.7.0/lib/SemVer.pm 2018-07-24 09:13:45.000000000 +0000 +++ libsemver-perl-0.10.0/lib/SemVer.pm 2020-05-09 13:57:55.000000000 +0000 @@ -1,459 +1,450 @@ -package SemVer; - -use 5.008001; -use strict; -use version 0.82; -use Scalar::Util (); - -use overload ( - '""' => 'stringify', - '<=>' => 'vcmp', - 'cmp' => 'vcmp', -); - -our @ISA = qw(version); -our $VERSION = '0.7.0'; # For Module::Build - -sub _die { require Carp; Carp::croak(@_) } - -# Prevent version.pm from mucking with our internals. -sub import {} - -# Adapted from version.pm. -my $STRICT_INTEGER_PART = qr/0|[1-9][0-9]*/; -my $DOT_SEPARATOR = qr/\./; -my $PLUS_SEPARATOR = qr/\+/; -my $DASH_SEPARATOR = qr/-/; -my $STRICT_DOTTED_INTEGER_PART = qr/$DOT_SEPARATOR$STRICT_INTEGER_PART/; -my $STRICT_DOTTED_INTEGER_VERSION = qr/ $STRICT_INTEGER_PART $STRICT_DOTTED_INTEGER_PART{2,} /x; -my $IDENTIFIER = qr/[-0-9A-Za-z]+/; -my $DOTTED_IDENTIFIER = qr/(?:$DOT_SEPARATOR$IDENTIFIER)*/; -my $PRERELEASE = qr/$IDENTIFIER$DOTTED_IDENTIFIER/; -my $METADATA = qr/$IDENTIFIER$DOTTED_IDENTIFIER/; - -my $OPTIONAL_EXTRA_PART = qr/$PRERELEASE($PLUS_SEPARATOR$METADATA)?/; - -sub new { - my ($class, $ival) = @_; - - # Handle vstring. - return $class->SUPER::new($ival) if Scalar::Util::isvstring($ival); - - # Let version handle cloning. - if (eval { $ival->isa('version') }) { - my $self = $class->SUPER::new($ival); - $self->{extra} = $ival->{extra}; - $self->{dash} = $ival->{dash}; - $self->_evalPreRelease($self->{extra}); - return $self; - } - - my ($val, $dash, $extra) = ( - $ival =~ /^v?($STRICT_DOTTED_INTEGER_VERSION)(?:($DASH_SEPARATOR)($OPTIONAL_EXTRA_PART))?$/ - ); - _die qq{Invalid semantic version string format: "$ival"} - unless defined $val; - - my $self = $class->SUPER::new($val); - $self->{dash} = $dash; - $self->{extra} = $extra; - $self->_evalPreRelease($self->{extra}); - - return $self; -} - -# Internal function to split up given string into prerelease- and patch-components -sub _evalPreRelease { - no warnings 'uninitialized'; - my $self = shift; - my $v = shift; - my ($preRelease, $plus, $patch) = ( - $v =~ /^($PRERELEASE)(?:($PLUS_SEPARATOR)($METADATA))?$/ - ); - @{$self->{prerelease}} = split $DOT_SEPARATOR,$preRelease; - $self->{plus} = $plus; - @{$self->{patch}} = (split $DOT_SEPARATOR, $patch || undef); - return; -} - -$VERSION = __PACKAGE__->new($VERSION); # For ourselves. - -sub declare { - my ($class, $ival) = @_; - return $class->new($ival) if Scalar::Util::isvstring($ival) - or eval { $ival->isa('version') }; - - (my $v = $ival) =~ s/^v?$STRICT_DOTTED_INTEGER_VERSION(?:($DASH_SEPARATOR)($OPTIONAL_EXTRA_PART))[[:space:]]*$//; - my $dash = $1; - my $extra = $2; - $v += 0 if $v =~ s/_//g; # ignore underscores. - my $self = $class->SUPER::declare($v); - $self->{dash} = $dash; - $self->{extra} = $extra; - $self->_evalPreRelease($self->{extra}); - return $self; -} - -sub parse { - my ($class, $ival) = @_; - return $class->new($ival) if Scalar::Util::isvstring($ival) - or eval { $ival->isa('version') }; - - (my $v = $ival) =~ s/^v?$STRICT_DOTTED_INTEGER_VERSION(?:($DASH_SEPARATOR)($OPTIONAL_EXTRA_PART))[[:space:]]*$//; - my $dash = $1; - my $extra = $2; - $v += 0 if $v =~ s/_//g; # ignore underscores. - my $self = $class->SUPER::parse($v); - $self->{dash} = $dash; - $self->{extra} = $extra; - $self->_evalPreRelease($self->{extra}); - return $self; -} - -sub stringify { - my $self = shift; - my $str = $self->SUPER::stringify; - # This is purely for SemVers constructed from version objects. - $str += 0 if $str =~ s/_//g; # ignore underscores. - return $str . ($self->{dash} || '') . ($self->{extra} || ''); -} - -sub normal { - my $self = shift; - (my $norm = $self->SUPER::normal) =~ s/^v//; - $norm =~ s/_/./g; - return $norm . ($self->{extra} ? "-$self->{extra}" : ''); -} - -sub numify { _die 'Semantic versions cannot be numified'; } -sub is_alpha { !!shift->{extra} } - - -# Sort Ordering: -# Precedence refers to how versions are compared to each other when ordered. Precedence MUST be calculated by -# separating the version into major, minor, patch and pre-release identifiers in that order (Build metadata does not figure into precedence). -# Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: -# 1. Major, minor, and patch versions are always compared numerically. Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. -# 2. When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. -# Example: 1.0.0-alpha < 1.0.0. -# 3. Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by -# comparing each dot separated identifier from left to right until a difference is found as follows: -# 3.a. identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are -# compared lexically in ASCII sort order. -# 3.b. Numeric identifiers always have lower precedence than non-numeric identifiers. -# 3.c. A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal. -# Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. -sub vcmp { - my $left = shift; - my $right = ref($left)->declare(shift); - - # Reverse? - ($left, $right) = shift() ? ($right, $left): ($left, $right); - - # Major and minor win. - case 1. - if (my $ret = $left->SUPER::vcmp($right, 0)) { - return $ret; - } else { #cases 2, 3 - my $lenLeft = 0; - my $lenRight = 0; - if (defined $left->{prerelease}) { - $lenLeft = scalar(@{$left->{prerelease}}); - } - if (defined $right->{prerelease}) { - $lenRight = scalar(@{$right->{prerelease}}); - } - my $lenMin = ($lenLeft, $lenRight)[$lenLeft > $lenRight]; - if ( $lenLeft == 0) { - if ($lenRight == 0) { - return 0; # Neither LEFT nor RIGHT have prerelease identifiers - versions are equal - } else { - # Case 2: When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. - return 1; # Only RIGHT has prelease - not LEFT -> LEFT wins - } - } else { - if ($lenRight == 0) { - # Case 2: When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. - return -1; # Only LEFT has prelease identifiers - not RIGHT -> RIGHT wins - } else { - # LEFT and RIGHT have prelease identifiers - compare each part separately - for (my $i = 0; $i < $lenMin; $i++) { - my $isNumLeft = Scalar::Util::looks_like_number($left->{prerelease}->[$i]); - my $isNumRight = Scalar::Util::looks_like_number($right->{prerelease}->[$i]); - # Case 3.b: Numeric identifiers always have lower precedence than non-numeric identifiers - if (!$isNumLeft && $isNumRight) { - return 1; # LEFT identifier is Non-numeric - RIGHT identifier is numeric -> LEFT wins - } elsif ($isNumLeft && !$isNumRight) { - return -1; # LEFT identifier is numeric - RIGHT identifier is non-numeric -> RIGHT wins - } elsif ($isNumLeft && $isNumRight) { - # Case 3.a.1: identifiers consisting of only digits are compared numerically - if ($left->{prerelease}->[$i] == $right->{prerelease}->[$i] ) { - next; # LEFT identifier and RIGHT identifier are equal - step to next part - } elsif ($left->{prerelease}->[$i] > $right->{prerelease}->[$i] ) { - return 1; # LEFT identifier is bigger than RIGHT identifier -> LEFT wins - } else { - return -1; return 1; # LEFT identifier is smaller than RIGHT identifier -> RIGHT wins - } - } else { - # Case 3.a.2: identifiers with letters or hyphens are compared lexically in ASCII sort order. - if (lc $left->{prerelease}->[$i] eq lc $right->{prerelease}->[$i] ) { - next; # LEFT identifier and RIGHT identifier are equal - step to next part - } elsif (lc $left->{prerelease}->[$i] gt lc $right->{prerelease}->[$i] ) { - return 1; # LEFT identifier is bigger than RIGHT identifier -> LEFT wins - } else { - return -1; return 1; # LEFT identifier is smaller than RIGHT identifier -> RIGHT wins - } - } - } - # Case 3.c: A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal - if ($lenLeft > $lenRight) { - return 1; # All existing identifiers are equal, but LEFT has more identifiers -> LEFT wins - } elsif ($lenLeft < $lenRight) { - return -1; # All existing identifiers are equal, but RIGHT has more identifiers -> RIGHT wins - } - # All identifiers are equal - return 0; - } - } - } -} - -1; -__END__ - -=head1 Name - -SemVer - Use semantic version numbers - -=head1 Synopsis - - use SemVer; our $VERSION = SemVer->new('1.2.0-b1'); - -=head1 Description - -This module subclasses L to create semantic versions, as defined by -the L. -The three salient points of the specification, for the purposes of version -formatting, are: - -=over - -=item 1. - -A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative -integers, and MUST NOT contain leading zeroes. X is the major version, Y is the -minor version, and Z is the patch version. Each element MUST increase numerically. -For instance: C<< 1.9.0 -> 1.10.0 -> 1.11.0 >>. - -=item 2. - -A pre-release version MAY be denoted by appending a hyphen and a series of dot -separated identifiers immediately following the patch version. Identifiers MUST -comprise only ASCII alphanumerics and hyphen C<[0-9A-Za-z-]>. Identifiers MUST NOT -be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions -have a lower precedence than the associated normal version. A pre-release version -indicates that the version is unstable and might not satisfy the intended -compatibility requirements as denoted by its associated normal version: -C<< 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92 >> - -=item 3. - -Build metadata MAY be denoted by appending a plus sign and a series of dot separated -identifiers immediately following the patch or pre-release version. Identifiers MUST -comprise only ASCII alphanumerics and hyphen C<[0-9A-Za-z-]>. Identifiers MUST NOT -be empty. Build metadata SHOULD be ignored when determining version precedence. Thus -two versions that differ only in the build metadata, have the same precedence. -Examples: C<< 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85 >>. - -=back - -=head2 Usage - -For strict parsing of semantic version numbers, use the C constructor. -If you need something more flexible, use C. And if you need -something more comparable with what L expects, try C. -Compare how these constructors deal with various version strings (with values -shown as returned by C: - - Argument | new | declare | parse - -------------+----------+--------------------------- - '1.0.0' | 1.0.0 | 1.0.0 | 1.0.0 - '5.5.2-b1' | 5.5.2-b1 | 5.5.2-b1 | 5.5.2-b1 - '1.05.0' | | 1.5.0 | 1.5.0 - '1.0' | | 1.0.0 | 1.0.0 - ' 012.2.2' | | 12.2.2 | 12.2.2 - '1.1' | | 1.1.0 | 1.100.0 - 1.1 | | 1.1.0 | 1.100.0 - '1.1.0b1' | | 1.1.0-b1 | 1.1.0-b1 - '1.1-b1' | | 1.1.0-b1 | 1.100.0-b1 - '1.2.b1' | | 1.2.0-b1 | 1.2.0-b1 - '9.0-beta4' | | 9.0.0-beta4 | 9.0.0-beta4 - '9' | | 9.0.0 | 9.0.0 - '1-b' | | 1.0.0-b | 1.0.0-b - 0 | | 0.0.0 | 0.0.0 - '0-rc1' | | 0.0.0-rc1 | 0.0.0-rc1 - '1.02_30' | | 1.23.0 | 1.23.0 - 1.02_30 | | 1.23.0 | 1.23.0 - -Note that, unlike in L, the C and C methods ignore -underscores. That is, version strings with underscores are treated as decimal -numbers. Hence, the last two examples yield exactly the same semantic -versions. - -As with L objects, the comparison and stringification operators are -all overloaded, so that you can compare semantic versions. You can also -compare semantic versions with version objects (but not the other way around, -alas). Boolean operators are also overloaded, such that all semantic version -objects except for those consisting only of zeros are considered true. - -=head1 Interface - -=head2 Constructors - -=head3 C - - my $semver = SemVer->new('1.2.2'); - -Performs a validating parse of the version string and returns a new semantic -version object. If the version string does not adhere to the semantic version -specification an exception will be thrown. See C and C for -more forgiving constructors. - -=head3 C - - my $semver = SemVer->declare('1.2'); # 1.2.0 - -This parser strips out any underscores from the version string and passes it -to to C's C constructor, which always creates dotted-integer -version objects. This is the most flexible way to declare versions. Consider -using it to normalize version strings. - -=head3 C - - my $semver = SemVer->parse('1.2'); # 1.200.0 - -This parser dispatches to C's C constructor, which tries to be -more flexible in how it converts simple decimal strings and numbers. Not -really recommended, since it's treatment of decimals is quite different from -the dotted-integer format of semantic version strings, and thus can lead to -inconsistencies. Included only for proper compatibility with L. - -=head2 Instance Methods - -=head3 C - - SemVer->declare('v1.2')->normal; # 1.2.0 - SemVer->parse('1.2')->normal; # 1.200.0 - SemVer->declare('1.02.0-b1')->normal; # 1.2.0-b1 - SemVer->parse('1.02_30')->normal # 1.230.0 - SemVer->parse(1.02_30)->normal # 1.23.0 - -Returns a normalized representation of the version. This string will always be -a strictly-valid dotted-integer semantic version string suitable for passing -to C. Unlike L's C method, there will be no leading -"v". - -=head3 C - - SemVer->declare('v1.2')->stringify; # v1.2 - SemVer->parse('1.200')->stringify; # v1.200 - SemVer->declare('1.2-r1')->stringify; # v1.2-r1 - SemVer->parse(1.02_30)->stringify; # v1.0230 - SemVer->parse(1.02_30)->stringify; # v1.023 - -Returns a string that is as close to the original representation as possible. -If the original representation was a numeric literal, it will be returned the -way perl would normally represent it in a string. This method is used whenever -a version object is interpolated into a string. - -=head3 C - -Throws an exception. Semantic versions cannot be numified. Just don't go -there. - -=head3 C - - my $is_alpha = $semver->is_alpha; - -Returns true if an ASCII string is appended to the end of the version string. -This also means that the version number is a "special version", in the -semantic versioning specification meaning of the phrase. - -=head3 C - -Compares the semantic version object to another version object or string and -returns 0 if they're the same, -1 if the invocant is smaller than the -argument, and 1 if the invocant is greater than the argument. - -Mostly you don't need to worry about this: Just use the comparison operators -instead. They will use this method: - - if ($semver < $another_semver) { - die "Need $another_semver or higher"; - } - -Note that in addition to comparing other semantic version objects, you can -also compare regular L objects: - - if ($semver < $version) { - die "Need $version or higher"; - } - -You can also pass in a version string. It will be turned into a semantic -version object using C. So if you're using integer versions, you may -or may not get what you want: - - my $semver = version::Semver->new('1.2.0'); - my $version = '1.2'; - my $bool = $semver == $version; # true - -If that's not what you want, pass the string to C first: - - my $semver = version::Semver->new('1.2.0'); - my $version = version::Semver->parse('1.2'); # 1.200.0 - my $bool = $semver == $version; # false - -=head1 See Also - -=over - -=item * L. - -=item * L - -=item * L - -=back - -=head1 Support - -This module is managed in an open -L. Feel free to fork and -contribute, or to clone L and send -patches! - -Found a bug? Please L or -L a report! - -=head1 Acknowledgements - -Many thanks to L author John Peacock for his suggestions and -debugging help. - -=head1 Authors - -=over - -=item * David E. Wheeler - -=item * Johannes Kilian - -=back - -=head1 Copyright and License - -Copyright (c) 2010-2018 David E. Wheeler. Some Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under -the same terms as Perl itself. - -=cut +package SemVer; + +use 5.008001; +use strict; +use version 0.82; +use Scalar::Util (); + +use overload ( + '""' => 'stringify', + '<=>' => 'vcmp', + 'cmp' => 'vcmp', + 'bool' => 'vbool', +); + +our @ISA = qw(version); +our $VERSION = '0.10.0'; # For Module::Build + +sub _die { require Carp; Carp::croak(@_) } + +# Prevent version.pm from mucking with our internals. +sub import {} + +sub new { + my ($class, $ival) = @_; + + # Handle vstring. + return $class->SUPER::new($ival) if Scalar::Util::isvstring($ival); + + # Let version handle cloning. + if (eval { $ival->isa('version') }) { + my $self = $class->SUPER::new($ival); + $self->{extra} = $ival->{extra}; + $self->{patch} = $ival->{patch}; + $self->{prerelease} = $ival->{prerelease}; + return $self; + } + + # Regex taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string. + my ($major, $minor, $patch, $prerelease, $meta) = ( + $ival =~ /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ); + _die qq{Invalid semantic version string format: "$ival"} + unless defined $major; + + return _init($class->SUPER::new("$major.$minor.$patch"), $prerelease, $meta); +} + +sub _init { + my ($self, $pre, $meta) = @_; + if (defined $pre) { + $self->{extra} = "-$pre"; + @{$self->{prerelease}} = split /[.]/, $pre; + } + if (defined $meta) { + $self->{extra} .= "+$meta"; + @{$self->{patch}} = split /[.]/, $meta; + } + + return $self; +} + +$VERSION = __PACKAGE__->new($VERSION); # For ourselves. + +sub _lenient { + my ($class, $ctor, $ival) = @_; + return $class->new($ival) if Scalar::Util::isvstring($ival) + or eval { $ival->isa('version') }; + + # Use official regex for prerelease and meta, use more lenient version num matching and whitespace. + my ($v, $prerelease, $meta) = ( + $ival =~ /^[[:space:]]* + v?([\d_]+(?:\.[\d_]+(?:\.[\d_]+)?)?) + (?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))? + [[:space:]]*$/x + ); + + _die qq{Invalid semantic version string format: "$ival"} + unless defined $v; + + $v += 0 if $v && $v =~ s/_//g; # ignore underscores. + my $code = $class->can("SUPER::$ctor"); + return _init($code->($class, $v), $prerelease, $meta); +} + +sub declare { + shift->_lenient('declare', @_); +} + +sub parse { + shift->_lenient('parse', @_); +} + +sub stringify { + my $self = shift; + my $str = $self->SUPER::stringify; + # This is purely for SemVers constructed from version objects. + $str += 0 if $str =~ s/_//g; # ignore underscores. + return $str . ($self->{dash} || '') . ($self->{extra} || ''); +} + +sub normal { + my $self = shift; + (my $norm = $self->SUPER::normal) =~ s/^v//; + $norm =~ s/_/./g; + return $norm . ($self->{extra} || ''); +} + +sub numify { _die 'Semantic versions cannot be numified'; } +sub is_alpha { !!shift->{extra} } +sub vbool { + my $self = shift; + return version::vcmp($self, $self->new("0.0.0"), 1); +} + +# Sort Ordering: +# Precedence refers to how versions are compared to each other when ordered. Precedence MUST be calculated by +# separating the version into major, minor, patch and pre-release identifiers in that order (Build metadata does not figure into precedence). +# Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: +# 1. Major, minor, and patch versions are always compared numerically. Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. +# 2. When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. +# Example: 1.0.0-alpha < 1.0.0. +# 3. Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by +# comparing each dot separated identifier from left to right until a difference is found as follows: +# 3.a. identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are +# compared lexically in ASCII sort order. +# 3.b. Numeric identifiers always have lower precedence than non-numeric identifiers. +# 3.c. A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal. +# Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. +sub vcmp { + my $left = shift; + my $right = ref($left)->declare(shift); + + # Reverse? + ($left, $right) = shift() ? ($right, $left): ($left, $right); + + # Major and minor win. - case 1. + if (my $ret = $left->SUPER::vcmp($right, 0)) { + return $ret; + } else { #cases 2, 3 + my $lenLeft = 0; + my $lenRight = 0; + if (defined $left->{prerelease}) { + $lenLeft = scalar(@{$left->{prerelease}}); + } + if (defined $right->{prerelease}) { + $lenRight = scalar(@{$right->{prerelease}}); + } + my $lenMin = ($lenLeft, $lenRight)[$lenLeft > $lenRight]; + if ( $lenLeft == 0) { + if ($lenRight == 0) { + return 0; # Neither LEFT nor RIGHT have prerelease identifiers - versions are equal + } else { + # Case 2: When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. + return 1; # Only RIGHT has prelease - not LEFT -> LEFT wins + } + } else { + if ($lenRight == 0) { + # Case 2: When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. + return -1; # Only LEFT has prelease identifiers - not RIGHT -> RIGHT wins + } else { + # LEFT and RIGHT have prelease identifiers - compare each part separately + for (my $i = 0; $i < $lenMin; $i++) { + my $isNumLeft = Scalar::Util::looks_like_number($left->{prerelease}->[$i]); + my $isNumRight = Scalar::Util::looks_like_number($right->{prerelease}->[$i]); + # Case 3.b: Numeric identifiers always have lower precedence than non-numeric identifiers + if (!$isNumLeft && $isNumRight) { + return 1; # LEFT identifier is Non-numeric - RIGHT identifier is numeric -> LEFT wins + } elsif ($isNumLeft && !$isNumRight) { + return -1; # LEFT identifier is numeric - RIGHT identifier is non-numeric -> RIGHT wins + } elsif ($isNumLeft && $isNumRight) { + # Case 3.a.1: identifiers consisting of only digits are compared numerically + if ($left->{prerelease}->[$i] == $right->{prerelease}->[$i] ) { + next; # LEFT identifier and RIGHT identifier are equal - step to next part + } elsif ($left->{prerelease}->[$i] > $right->{prerelease}->[$i] ) { + return 1; # LEFT identifier is bigger than RIGHT identifier -> LEFT wins + } else { + return -1; return 1; # LEFT identifier is smaller than RIGHT identifier -> RIGHT wins + } + } else { + # Case 3.a.2: identifiers with letters or hyphens are compared lexically in ASCII sort order. + if (lc $left->{prerelease}->[$i] eq lc $right->{prerelease}->[$i] ) { + next; # LEFT identifier and RIGHT identifier are equal - step to next part + } elsif (lc $left->{prerelease}->[$i] gt lc $right->{prerelease}->[$i] ) { + return 1; # LEFT identifier is bigger than RIGHT identifier -> LEFT wins + } else { + return -1; return 1; # LEFT identifier is smaller than RIGHT identifier -> RIGHT wins + } + } + } + # Case 3.c: A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal + if ($lenLeft > $lenRight) { + return 1; # All existing identifiers are equal, but LEFT has more identifiers -> LEFT wins + } elsif ($lenLeft < $lenRight) { + return -1; # All existing identifiers are equal, but RIGHT has more identifiers -> RIGHT wins + } + # All identifiers are equal + return 0; + } + } + } +} + +1; +__END__ + +=head1 Name + +SemVer - Use semantic version numbers + +=head1 Synopsis + + use SemVer; our $VERSION = SemVer->new('1.2.0-b1'); + +=head1 Description + +This module subclasses L to create semantic versions, as defined by +the L. +The three salient points of the specification, for the purposes of version +formatting, are: + +=over + +=item 1. + +A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative +integers, and MUST NOT contain leading zeroes. X is the major version, Y is the +minor version, and Z is the patch version. Each element MUST increase numerically. +For instance: C<< 1.9.0 -> 1.10.0 -> 1.11.0 >>. + +=item 2. + +A pre-release version MAY be denoted by appending a hyphen and a series of dot +separated identifiers immediately following the patch version. Identifiers MUST +comprise only ASCII alphanumerics and hyphen C<[0-9A-Za-z-]>. Identifiers MUST NOT +be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions +have a lower precedence than the associated normal version. A pre-release version +indicates that the version is unstable and might not satisfy the intended +compatibility requirements as denoted by its associated normal version: +C<< 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92 >> + +=item 3. + +Build metadata MAY be denoted by appending a plus sign and a series of dot separated +identifiers immediately following the patch or pre-release version. Identifiers MUST +comprise only ASCII alphanumerics and hyphen C<[0-9A-Za-z-]>. Identifiers MUST NOT +be empty. Build metadata SHOULD be ignored when determining version precedence. Thus +two versions that differ only in the build metadata, have the same precedence. +Examples: C<< 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85 >>. + +=back + +=head2 Usage + +For strict parsing of semantic version numbers, use the C constructor. +If you need something more flexible, use C. And if you need +something more comparable with what L expects, try C. +Compare how these constructors deal with various version strings (with values +shown as returned by C: + + Argument | new | declare | parse + -------------+----------+--------------------------- + '1.0.0' | 1.0.0 | 1.0.0 | 1.0.0 + '5.5.2-b1' | 5.5.2-b1 | 5.5.2-b1 | 5.5.2-b1 + '1.05.0' | | 1.5.0 | 1.5.0 + '1.0' | | 1.0.0 | 1.0.0 + ' 012.2.2' | | 12.2.2 | 12.2.2 + '1.1' | | 1.1.0 | 1.100.0 + 1.1 | | 1.1.0 | 1.100.0 + '1.1.0+b1' | 1.1.0+b1 | 1.1.0+b1 | 1.1.0+b1 + '1.1-b1' | | 1.1.0-b1 | 1.100.0-b1 + '1.2.b1' | | 1.2.0-b1 | 1.2.0-b1 + '9.0-beta4' | | 9.0.0-beta4 | 9.0.0-beta4 + '9' | | 9.0.0 | 9.0.0 + '1-b' | | 1.0.0-b | 1.0.0-b + 0 | | 0.0.0 | 0.0.0 + '0-rc1' | | 0.0.0-rc1 | 0.0.0-rc1 + '1.02_30' | | 1.23.0 | 1.23.0 + 1.02_30 | | 1.23.0 | 1.23.0 + +Note that, unlike in L, the C and C methods ignore +underscores. That is, version strings with underscores are treated as decimal +numbers. Hence, the last two examples yield exactly the same semantic +versions. + +As with L objects, the comparison and stringification operators are +all overloaded, so that you can compare semantic versions. You can also +compare semantic versions with version objects (but not the other way around, +alas). Boolean operators are also overloaded, such that all semantic version +objects except for those consisting only of zeros (ignoring prerelease and +metadata) are considered true. + +=head1 Interface + +=head2 Constructors + +=head3 C + + my $semver = SemVer->new('1.2.2'); + +Performs a validating parse of the version string and returns a new semantic +version object. If the version string does not adhere to the semantic version +specification an exception will be thrown. See C and C for +more forgiving constructors. + +=head3 C + + my $semver = SemVer->declare('1.2'); # 1.2.0 + +This parser strips out any underscores from the version string and passes it +to to C's C constructor, which always creates dotted-integer +version objects. This is the most flexible way to declare versions. Consider +using it to normalize version strings. + +=head3 C + + my $semver = SemVer->parse('1.2'); # 1.200.0 + +This parser dispatches to C's C constructor, which tries to be +more flexible in how it converts simple decimal strings and numbers. Not +really recommended, since it's treatment of decimals is quite different from +the dotted-integer format of semantic version strings, and thus can lead to +inconsistencies. Included only for proper compatibility with L. + +=head2 Instance Methods + +=head3 C + + SemVer->declare('v1.2')->normal; # 1.2.0 + SemVer->parse('1.2')->normal; # 1.200.0 + SemVer->declare('1.02.0-b1')->normal; # 1.2.0-b1 + SemVer->parse('1.02_30')->normal # 1.230.0 + SemVer->parse(1.02_30)->normal # 1.23.0 + +Returns a normalized representation of the version string. This string will +always be a strictly-valid dotted-integer semantic version string suitable +for passing to C. Unlike L's C method, there will be +no leading "v". + +=head3 C + + SemVer->declare('v1.2')->stringify; # v1.2 + SemVer->parse('1.200')->stringify; # v1.200 + SemVer->declare('1.2-r1')->stringify; # v1.2-r1 + SemVer->parse(1.02_30)->stringify; # v1.0230 + SemVer->parse(1.02_30)->stringify; # v1.023 + +Returns a string that is as close to the original representation as possible. +If the original representation was a numeric literal, it will be returned the +way perl would normally represent it in a string. This method is used whenever +a version object is interpolated into a string. + +=head3 C + +Throws an exception. Semantic versions cannot be numified. Just don't go +there. + +=head3 C + + my $is_alpha = $semver->is_alpha; + +Returns true if a prerelease and/or metadata string is appended to the end of +the version string. This also means that the version number is a "special +version", in the semantic versioning specification meaning of the phrase. + +=head3 C + + say "Version $semver" if $semver; + say "Not a $semver" if !$semver; + +Returns true for a non-zero semantic semantic version object, without regard +to the prerelease or build metadata parts. Overloads boolean operations. + +=head3 C + +Compares the semantic version object to another version object or string and +returns 0 if they're the same, -1 if the invocant is smaller than the +argument, and 1 if the invocant is greater than the argument. + +Mostly you don't need to worry about this: Just use the comparison operators +instead: + + if ($semver < $another_semver) { + die "Need $another_semver or higher"; + } + +Note that in addition to comparing other semantic version objects, you can +also compare regular L objects: + + if ($semver < $version) { + die "Need $version or higher"; + } + +You can also pass in a version string. It will be turned into a semantic +version object using C. So if you're using numeric versions, you may +or may not get what you want: + + my $semver = version::Semver->new('1.2.0'); + my $version = '1.2'; + my $bool = $semver == $version; # true + +If that's not what you want, pass the string to C first: + + my $semver = Semver->new('1.2.0'); + my $version = Semver->parse('1.2'); # 1.200.0 + my $bool = $semver == $version; # false + +=head1 See Also + +=over + +=item * L. + +=item * L + +=item * L + +=back + +=head1 Support + +This module is managed in an open +L. Feel free to fork and +contribute, or to clone L and send +patches! + +Found a bug? Please L a report! + +=head1 Acknowledgements + +Many thanks to L author John Peacock for his suggestions and +debugging help. + +=head1 Authors + +=over + +=item * David E. Wheeler + +=item * Johannes Kilian + +=back + +=head1 Copyright and License + +Copyright (c) 2010-2020 David E. Wheeler. Some Rights Reserved. + +This module is free software; you can redistribute it and/or modify it under +the same terms as Perl itself. + +=cut diff -Nru libsemver-perl-0.7.0/MANIFEST libsemver-perl-0.10.0/MANIFEST --- libsemver-perl-0.7.0/MANIFEST 2018-07-24 09:15:21.000000000 +0000 +++ libsemver-perl-0.10.0/MANIFEST 2020-05-09 13:57:55.000000000 +0000 @@ -1,9 +1,9 @@ -Build.bat Build.PL Changes lib/SemVer.pm MANIFEST This list of files README.md t/base.t -META.yml -META.json +t/corpus.t +META.yml +META.json diff -Nru libsemver-perl-0.7.0/META.json libsemver-perl-0.10.0/META.json --- libsemver-perl-0.7.0/META.json 2018-07-24 09:15:21.000000000 +0000 +++ libsemver-perl-0.10.0/META.json 2020-05-09 13:57:55.000000000 +0000 @@ -1,60 +1,60 @@ -{ - "abstract" : "Use semantic version numbers", - "author" : [ - "unknown" - ], - "dynamic_config" : 1, - "generated_by" : "Module::Build version 0.4224", - "license" : [ - "perl_5" - ], - "meta-spec" : { - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", - "version" : 2 - }, - "name" : "SemVer", - "prereqs" : { - "build" : { - "requires" : { - "Module::Build" : "0.30", - "Test::More" : "0.88" - } - }, - "configure" : { - "requires" : { - "Module::Build" : "0.30" - } - }, - "runtime" : { - "recommends" : { - "Test::Pod" : "1.41", - "Test::Pod::Coverage" : "1.06" - }, - "requires" : { - "perl" : "5.008001", - "version" : "0.82" - } - } - }, - "provides" : { - "SemVer" : { - "file" : "lib/SemVer.pm", - "version" : "v0.7.0" - } - }, - "release_status" : "stable", - "resources" : { - "bugtracker" : { - "web" : "http://github.com/theory/semver/issues/" - }, - "homepage" : "http://search.cpan.org/dist/SemVer/", - "license" : [ - "http://dev.perl.org/licenses/" - ], - "repository" : { - "url" : "http://github.com/theory/semver" - } - }, - "version" : "v0.7.0", - "x_serialization_backend" : "JSON::PP version 2.94" -} +{ + "abstract" : "Use semantic version numbers", + "author" : [ + "unknown" + ], + "dynamic_config" : 1, + "generated_by" : "Module::Build version 0.4231", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "SemVer", + "prereqs" : { + "build" : { + "requires" : { + "Module::Build" : "0.30", + "Test::More" : "0.88" + } + }, + "configure" : { + "requires" : { + "Module::Build" : "0.30" + } + }, + "runtime" : { + "recommends" : { + "Test::Pod" : "1.41", + "Test::Pod::Coverage" : "1.06" + }, + "requires" : { + "perl" : "5.008001", + "version" : "0.82" + } + } + }, + "provides" : { + "SemVer" : { + "file" : "lib/SemVer.pm", + "version" : "v0.10.0" + } + }, + "release_status" : "stable", + "resources" : { + "bugtracker" : { + "web" : "https://github.com/theory/semver/issues/" + }, + "homepage" : "https://metacpan.org/release/SemVer", + "license" : [ + "http://dev.perl.org/licenses/" + ], + "repository" : { + "url" : "https://github.com/theory/semver" + } + }, + "version" : "v0.10.0", + "x_serialization_backend" : "JSON::PP version 4.02" +} diff -Nru libsemver-perl-0.7.0/META.yml libsemver-perl-0.10.0/META.yml --- libsemver-perl-0.7.0/META.yml 2018-07-24 09:15:21.000000000 +0000 +++ libsemver-perl-0.10.0/META.yml 2020-05-09 13:57:55.000000000 +0000 @@ -1,33 +1,33 @@ ---- -abstract: 'Use semantic version numbers' -author: - - unknown -build_requires: - Module::Build: '0.30' - Test::More: '0.88' -configure_requires: - Module::Build: '0.30' -dynamic_config: 1 -generated_by: 'Module::Build version 0.4224, CPAN::Meta::Converter version 2.150010' -license: perl -meta-spec: - url: http://module-build.sourceforge.net/META-spec-v1.4.html - version: '1.4' -name: SemVer -provides: - SemVer: - file: lib/SemVer.pm - version: v0.7.0 -recommends: - Test::Pod: '1.41' - Test::Pod::Coverage: '1.06' -requires: - perl: '5.008001' - version: '0.82' -resources: - bugtracker: http://github.com/theory/semver/issues/ - homepage: http://search.cpan.org/dist/SemVer/ - license: http://dev.perl.org/licenses/ - repository: http://github.com/theory/semver -version: v0.7.0 -x_serialization_backend: 'CPAN::Meta::YAML version 0.018' +--- +abstract: 'Use semantic version numbers' +author: + - unknown +build_requires: + Module::Build: '0.30' + Test::More: '0.88' +configure_requires: + Module::Build: '0.30' +dynamic_config: 1 +generated_by: 'Module::Build version 0.4231, CPAN::Meta::Converter version 2.150010' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: '1.4' +name: SemVer +provides: + SemVer: + file: lib/SemVer.pm + version: v0.10.0 +recommends: + Test::Pod: '1.41' + Test::Pod::Coverage: '1.06' +requires: + perl: '5.008001' + version: '0.82' +resources: + bugtracker: https://github.com/theory/semver/issues/ + homepage: https://metacpan.org/release/SemVer + license: http://dev.perl.org/licenses/ + repository: https://github.com/theory/semver +version: v0.10.0 +x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -Nru libsemver-perl-0.7.0/README.md libsemver-perl-0.10.0/README.md --- libsemver-perl-0.7.0/README.md 2018-07-24 09:13:45.000000000 +0000 +++ libsemver-perl-0.10.0/README.md 2020-05-09 13:57:55.000000000 +0000 @@ -1,78 +1,78 @@ -SemVer version 0.7.0 -==================== - -This module subclasses [`version`] to create semantic versions, as defined by -the [Semantic Versioning 2.0.0 Specification] -The salient points of the specification, for the purposes of version -formatting, are: - -1. A normal version number MUST take the form X.Y.Z where X, Y, and Z are - non-negative integers, and MUST NOT contain leading zeroes. X is the major - version, Y is the minor version, and Z is the patch version. Each element - MUST increase numerically. - For instance: `1.9.0 < 1.10.0 < 1.11.0`. - -2. A pre-release version MAY be denoted by appending a hyphen and a series - of dot separated identifiers immediately following the patch version. - Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. - Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading - zeroes. Pre-release versions have a lower precedence than the associated - normal version. A pre-release version indicates that the version is - unstable and might not satisfy the intended compatibility requirements - as denoted by its associated normal version. - Examples: `1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92`. - -3. Build metadata MAY be denoted by appending a plus sign and a series of - dot separated identifiers immediately following the patch or pre-release - version. Identifiers MUST comprise only ASCII alphanumerics and hyphen - [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata SHOULD be - ignored when determining version precedence. Thus two versions that differ - only in the build metadata, have the same precedence. - Examples: `1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85`. - -4. Precedence refers to how versions are compared to each other when ordered. - Precedence MUST be calculated by separating the version into major, minor, - patch and pre-release identifiers in that order (Build metadata does not - figure into precedence). Precedence is determined by the first difference - when comparing each of these identifiers from left to right as follows: - Major, minor, and patch versions are always compared numerically. - Example: `1.0.0 < 2.0.0 < 2.1.0 < 2.1.1`. - When major, minor, and patch are equal, a pre-release version has lower - precedence than a normal version. - Example: `1.0.0-alpha < 1.0.0`. - Precedence for two pre-release versions with the same major, minor, and - patch version MUST be determined by comparing each dot separated identifier - from left to right until a difference is found as follows: identifiers - consisting of only digits are compared numerically and identifiers with - letters or hyphens are compared lexically in ASCII sort order. Numeric - identifiers always have lower precedence than non-numeric identifiers. A - larger set of pre-release fields has a higher precedence than a smaller - set, if all of the preceding identifiers are equal. - Example: `1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0`. - - -[`version`]: http://search.cpan.org/perldoc?version -[Semantic Versioning 2.0.0 Specification]: http://semver.org/spec/v2.0.0.html - -Installation -============ - -To install this module, type the following: - - perl Build.PL - ./Build - ./Build test - ./Build install - -Dependencies ------------- - -SemVer requires version. - -Copyright and License ---------------------- - -Copyright (c) 2010-2018 David E. Wheeler. Some Rights Reserved. - -This module is free software; you can redistribute it and/or modify it under -the same terms as Perl itself. +SemVer version 0.10.0 +===================== + +This module subclasses [`version`] to create semantic versions, as defined by +the [Semantic Versioning 2.0.0 Specification] +The salient points of the specification, for the purposes of version +formatting, are: + +1. A normal version number MUST take the form X.Y.Z where X, Y, and Z are + non-negative integers, and MUST NOT contain leading zeroes. X is the major + version, Y is the minor version, and Z is the patch version. Each element + MUST increase numerically. + For instance: `1.9.0 < 1.10.0 < 1.11.0`. + +2. A pre-release version MAY be denoted by appending a hyphen and a series + of dot separated identifiers immediately following the patch version. + Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading + zeroes. Pre-release versions have a lower precedence than the associated + normal version. A pre-release version indicates that the version is + unstable and might not satisfy the intended compatibility requirements + as denoted by its associated normal version. + Examples: `1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92`. + +3. Build metadata MAY be denoted by appending a plus sign and a series of + dot separated identifiers immediately following the patch or pre-release + version. Identifiers MUST comprise only ASCII alphanumerics and hyphen + [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata SHOULD be + ignored when determining version precedence. Thus two versions that differ + only in the build metadata, have the same precedence. + Examples: `1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85`. + +4. Precedence refers to how versions are compared to each other when ordered. + Precedence MUST be calculated by separating the version into major, minor, + patch and pre-release identifiers in that order (Build metadata does not + figure into precedence). Precedence is determined by the first difference + when comparing each of these identifiers from left to right as follows: + Major, minor, and patch versions are always compared numerically. + Example: `1.0.0 < 2.0.0 < 2.1.0 < 2.1.1`. + When major, minor, and patch are equal, a pre-release version has lower + precedence than a normal version. + Example: `1.0.0-alpha < 1.0.0`. + Precedence for two pre-release versions with the same major, minor, and + patch version MUST be determined by comparing each dot separated identifier + from left to right until a difference is found as follows: identifiers + consisting of only digits are compared numerically and identifiers with + letters or hyphens are compared lexically in ASCII sort order. Numeric + identifiers always have lower precedence than non-numeric identifiers. A + larger set of pre-release fields has a higher precedence than a smaller + set, if all of the preceding identifiers are equal. + Example: `1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0`. + + +[`version`]: https://metacpan.org/pod/version +[Semantic Versioning 2.0.0 Specification]: https://semver.org/spec/v2.0.0.html + +Installation +============ + +To install this module, type the following: + + perl Build.PL + ./Build + ./Build test + ./Build install + +Dependencies +------------ + +SemVer requires version. + +Copyright and License +--------------------- + +Copyright (c) 2010-2020 David E. Wheeler. Some Rights Reserved. + +This module is free software; you can redistribute it and/or modify it under +the same terms as Perl itself. diff -Nru libsemver-perl-0.7.0/t/base.t libsemver-perl-0.10.0/t/base.t --- libsemver-perl-0.7.0/t/base.t 2018-07-24 09:13:45.000000000 +0000 +++ libsemver-perl-0.10.0/t/base.t 2020-05-09 13:57:55.000000000 +0000 @@ -1,320 +1,414 @@ -#!/usr/bin/perl -w - -use strict; -use warnings; -use Test::More tests => 610; -#use Test::More 'no_plan'; - -use FindBin qw($Bin); -use lib "$Bin/../lib"; - -my $CLASS; -BEGIN { - $CLASS = 'SemVer'; - use_ok $CLASS or die; -} - -diag 'Testing with version v', version->VERSION; -can_ok $CLASS, qw( - new - declare - parse - normal - numify - is_alpha - is_qv - vcmp -); - -# Try the basics. -isa_ok my $version = $CLASS->new('0.1.0'), $CLASS, 'An instance'; -isa_ok $SemVer::VERSION, $CLASS, q{SemVer's own $VERSION}; -my $is_vpp = !!grep { $_ eq 'version::vpp' } @version::ISA; - -for my $v (qw( - 1.2.2 - 0.2.2 - 1.2.2 - 0.0.0 - 0.1.999 - 9999.9999999.823823 - 1.0.0-beta1 - 1.0.0-beta2 - 1.0.0 - 0.0.0-rc1 - v1.2.2 - 999993333.0.0 -)) { - isa_ok my $semver =$CLASS->new($v), $CLASS, "new($v)"; - my $str = $v =~ /^v/ ? substr $v, 1 : $v; - is "$semver", $str, qq{$v should stringify to "$str"}; - $str =~ s/(\d)([a-z].+)$/$1-$2/; - is $semver->normal, $str, qq{$v should normalize to "$str"}; - - SKIP: { - skip 'Boolean comparison broken with version::vpp', 1, $is_vpp; - if ($v =~ /0\.0\.0/) { - ok !$semver, "$v should be false"; - } else { - ok !!$semver, "$v should be true"; - } - } - - ok $semver->is_qv, "$v should be dotted-decimal"; - - my $is_alpha = $semver->is_alpha; - if ($v =~ /[.]\d+-?[a-z]/) { - ok $is_alpha, "$v should be alpha"; - } else { - ok !$is_alpha, "$v should not be alpha"; - } -} - -local $@; -eval { $CLASS->new('') }; -ok $@, 'Empty string should be an invalid version'; - -for my $bv (qw( - 1.2 - 0 - 0.0 - 1.2b - 1.b - 1.04.0 - 1.65.r2 -)) { - local $@; - eval { $CLASS->new($bv) }; - like $@, qr{Invalid semantic version string format: "$bv"}, - qq{"$bv" should be an invalid semver}; -} - -# Try a vstring. -isa_ok $version = $CLASS->new(v2.3.2), $CLASS, 'vstring version'; -is $version->stringify, 'v2.3.2', 'vestring should stringify with "v"'; -is $version->normal, '2.3.2', 'vstring should normalize without "v"'; - -# Try a shorter vstring. -my $no_2digitvst = $] < 5.10 && version->VERSION < 0.9910; -SKIP: { - skip 'Two-integer vstrings weak on Perl 5.8', 3 if $no_2digitvst; - isa_ok $version = $CLASS->new(v2.3), $CLASS, 'vstring version'; - is $version->stringify, 'v2.3', 'short vestring should stringify with "v"'; - is $version->normal, '2.3.0', 'short vstring should normalize without required 0'; -} - -# Try another SemVer. -isa_ok my $cloned = $CLASS->new($version), $CLASS, 'Cloned SemVer'; -is $cloned->stringify, $version->stringify, 'Cloned stringify like original'; -is $cloned->normal, $version->normal, 'Cloned should normalize like original'; - -# Try a SemVer with alpha. -isa_ok $version = $CLASS->new('2.3.2-b1'), $CLASS, 'new version'; -isa_ok $cloned = $CLASS->new($version), $CLASS, 'Second cloned SemVer'; -is $cloned->stringify, $version->stringify, 'Second cloned stringify like original'; -is $cloned->normal, $version->normal, 'Second cloned should normalize like original'; - -# Numify should die -local $@; -eval { $version->numify }; -like $@, qr{Semantic versions cannot be numified}, - 'Should get error from numify()'; - -# Now do some comparisons. Start with equivalents. -for my $spec ( - [ '1.2.2', '1.2.2' ], - [ '1.2.23', '1.2.23' ], - [ '0.0.0', '0.0.0' ], - [ '999.888.7777', '999.888.7777' ], - [ '0.1.2-beta3', '0.1.2-beta3' ], - [ '1.0.0-rc-1', '1.0.0-RC-1' ], -) { - my $l = $CLASS->new($spec->[0]); - my $r = $CLASS->new($spec->[1]); - is $l->vcmp($r), 0, "$l->vcmp($r) == 0"; - is $l <=> $r, 0, "$l <=> $r == 0"; - is $r <=> $l, 0, "$r <=> $l == 0"; - cmp_ok $l, '==', $r, "$l == $r"; - cmp_ok $l, '==', $r, "$l == $r"; - cmp_ok $l, '<=', $r, "$l <= $r"; - cmp_ok $l, '>=', $r, "$l >= $r"; - is $l cmp $r, 0, "$l cmp $r == 0"; - is $r cmp $l, 0, "$r cmp $l == 0"; - cmp_ok $l, 'eq', $r, "$l eq $r"; - cmp_ok $l, 'eq', $r, "$l eq $r"; - cmp_ok $l, 'le', $r, "$l le $r"; - cmp_ok $l, 'ge', $r, "$l ge $r"; -} - -# Test not equal. -for my $spec ( - ['1.2.2', '1.2.3'], - ['0.0.1', '1.0.0'], - ['1.0.1', '1.1.0'], - ['1.1.1', '1.1.0'], - ['1.2.3-b', '1.2.3'], - ['1.2.3', '1.2.3-b'], - ['1.2.3-a', '1.2.3-b'], - ['1.2.3-aaaaaaa1', '1.2.3-aaaaaaa2'], -) { - my $l = $CLASS->new($spec->[0]); - my $r = $CLASS->new($spec->[1]); - cmp_ok $l->vcmp($r), '!=', 0, "$l->vcmp($r) != 0"; - cmp_ok $l, '!=', $r, "$l != $r"; - cmp_ok $l, 'ne', $r, "$l ne $r"; -} - -# Test >, >=, <, and <=. -for my $spec ( - ['2.2.2', '1.1.1'], - ['2.2.2', '2.1.1'], - ['2.2.2', '2.2.1'], - ['2.2.2-b', '2.2.1'], - ['2.2.2', '2.2.2-b'], - ['2.2.2-c', '2.2.2-b'], - ['2.2.2-rc-2', '2.2.2-RC-1'], - ['0.9.10', '0.9.9'], -) { - my $l = $CLASS->new($spec->[0]); - my $r = $CLASS->new($spec->[1]); - cmp_ok $l->vcmp($r), '>', 0, "$l->vcmp($r) > 0"; - cmp_ok $r->vcmp($l), '<', 0, "$r->vcmp($l) < 0"; - cmp_ok $l, '>', $r, "$l > $r"; - cmp_ok $l, '>=', $r, "$l >= $r"; - cmp_ok $r, '<', $l, "$r < $l"; - cmp_ok $r, '<=', $l, "$r <= $l"; - cmp_ok $l, 'gt', $r, "$l gt $r"; - cmp_ok $l, 'ge', $r, "$l ge $r"; - cmp_ok $r, 'lt', $l, "$r lt $l"; - cmp_ok $r, 'le', $l, "$r le $l"; -} - -# Compare Versions from SemVer 2.0 -my @ver = ("0.9.0","1.0.0-alpha","1.0.0-alpha.1","1.0.0-alpha.beta","1.0.0-beta","1.0.0-beta.2","1.0.0-beta.11","1.0.0-beta.31","1.0.0-beta.200","1.0.0-rc.1","1.0.0","2.0.0","2.1.0","2.1.1"); - -for (my $i = 0; $i < (scalar(@ver)-1); $i++) { - for (my $j = $i+1; $j < scalar(@ver); $j++) { - my $l = SemVer->new($ver[$i]); - my $r = SemVer->new($ver[$j]); - cmp_ok $l, '<', $r, "$l < $r"; - } -} - -# Compare to version objects. -my $semver = $CLASS->new('1.2.0'); -for my $v (qw( - 1.002 - 1.2.0 - v1.002 - v1.2.0 -)) { - my $version = version->new($v); - ok $semver == $version, "$semver == $version"; -} - -# Compare to strings. -for my $v (qw( - 1.2.0 - v1.2.0 -)) { - my $semver = $CLASS->new($v); - cmp_ok $semver, '==', $v, qq{$semver == "$v"}; - cmp_ok $v, '==', $semver, qq{"$v" == $semver}; - cmp_ok $semver, 'eq', $v, qq{$semver eq "$v"}; - cmp_ok $v, 'eq', $semver, qq{"$v" eq $semver}; -} - -# Test declare() and parse. -for my $spec ( - ['1.2.2', '1.2.2'], - ['01.2.2', '1.2.2'], - ['1.02.2', '1.2.2'], - ['1.2.02', '1.2.2'], -# ['1.2.02b', '1.2.2-b'], -# ['1.2.02beta-3 ', '1.2.2-beta-3'], -# ['1.02.02rc1', '1.2.2-rc1'], - ['1.0', '1.0.0'], - ['1.1', '1.1.0', '1.100.0'], - [ 1.1, '1.1.0', '1.100.0'], -# ['1.1b1', '1.1.0-b1', '1.100.0-b1'], -# ['1b', '1.0.0-b'], -# ['9.0beta4', '9.0.0-beta4'], - [' 012.2.2', '12.2.2'], - ['99999998', '99999998.0.0'], - ['1.02_30', '1.23.0'], - [1.02_30, '1.23.0'], - [3.4, '3.4.0', '3.400.0'], - [3.04, '3.4.0', '3.40.0' ], - ['3.04', '3.4.0', '3.40.0' ], - [v3.4, '3.4.0' ], - [9, '9.0.0' ], - ['9', '9.0.0' ], - ['0', '0.0.0' ], - [0, '0.0.0' ], -# ['0rc1', '0.0.0-rc1' ], -) { SKIP: { - skip 'Two-integer vstrings weak on Perl 5.8', 12 - if $no_2digitvst && Scalar::Util::isvstring($spec->[0]); - my $r = $CLASS->new($spec->[1]); - isa_ok my $l = SemVer->declare($spec->[0]), $CLASS, "Declared $spec->[0]"; - my $string = Scalar::Util::isvstring($spec->[0]) - ? join '.', map { ord } split // => $spec->[0] : $spec->[0]; - $string =~ s/^\s+//; - $string =~ s/\s+$//; - $string += 0 if $string =~ s/_//g; - my $vstring = $string =~ /^\d+[.][^.]+$/ ? "v$string" : $string; - SKIP: { - skip 'Stringification broken with version::vpp', 1, $is_vpp; - is $l->stringify, $vstring, qq{... And it should stringify to "$vstring"}; - } - is $l->normal, $spec->[1], qq{... And it should normalize to "$spec->[1]"}; - - # Compare the non-semantic version string to the semantic one. - cmp_ok $spec->[0], '==', $r, qq{$r == "$spec->[0]"}; - - if ($spec->[0] && $spec->[0] !~ /^[a-z]/ && $spec->[0] !~ /[.]{2}/) { - my $exp = $spec->[2] || $spec->[1]; - isa_ok $l = SemVer->parse($spec->[0]), $CLASS, "Parsed $spec->[0]"; - $string = "v$string" if Scalar::Util::isvstring($spec->[0]); - $string =~ s/_//; - is $l->stringify, $string, "... And it should stringify to $string"; - is $l->normal, $exp, "... And it should normalize to $exp"; - - # Try with the parsed version. - $r = $CLASS->new($spec->[2]) if $spec->[2]; - cmp_ok $l, '==', $r, qq{$l == $r} unless $string =~ /_/; - } - - # Try creating as a version object and cloning. - if ($spec->[0] !~ /[a-z]/i) { - isa_ok my $v = version->parse($spec->[0]), 'version', "base version $spec->[0]"; - isa_ok my $sv = SemVer->new($v), 'SemVer', "SemVer from base version $spec->[0]"; - is $sv->stringify, $string, qq{... And it should stringify to "$vstring"}; - SKIP: { - skip 'version 0.9911 broke alpha->normal()', 1, - if $spec->[0] =~ /_/ && version->VERSION == 0.9911; - is $sv->normal, $l->normal, - '... And it should normalize to "' . $l->normal . '"'; - } - } -}} - -for my $v (qw( - 1.2.02b - 1.2.02beta-3 - 1.02.02rc1 - 1.1b1 - 1b - 9.0beta4 - 0rc1 -)) { - eval { - my $l = SemVer->declare($v); - }; - if ($@) { - is 1, 1, $v.' is not a SemVer'; - } - else { - is 1, 0, $v.' should not be not a SemVer'; - } -} +#!/usr/bin/perl -w + +use strict; +use warnings; +use Test::More tests => 941; +#use Test::More 'no_plan'; + +use FindBin qw($Bin); +use lib "$Bin/../lib"; + +my $CLASS; +BEGIN { + $CLASS = 'SemVer'; + use_ok $CLASS or die; +} + +diag 'Testing with version v', version->VERSION; +can_ok $CLASS, qw( + new + declare + parse + normal + numify + is_alpha + is_qv + vcmp +); + +# Try the basics. +isa_ok my $version = $CLASS->new('0.1.0'), $CLASS, 'An instance'; +isa_ok $SemVer::VERSION, $CLASS, q{SemVer's own $VERSION}; + +for my $v (qw( + 1.2.2 + 0.2.2 + 1.2.2 + 0.0.0 + 0.1.999 + 9999.9999999.823823 + 1.0.0-beta1 + 1.0.0-beta2 + 1.0.0 + 0.0.0-rc1 + v1.2.2 + 999993333.0.0 +)) { + isa_ok my $semver = $CLASS->new($v), $CLASS, "new($v)"; + my $str = $v =~ /^v/ ? substr $v, 1 : $v; + is "$semver", $str, qq{$v should stringify to "$str"}; + $str =~ s/(\d)([a-z].+)$/$1-$2/; + is $semver->normal, $str, qq{$v should normalize to "$str"}; + + if ($v =~ /0\.0\.0/) { + ok !$semver, "$v should be false"; + } else { + ok !!$semver, "$v should be true"; + } + + ok $semver->is_qv, "$v should be dotted-decimal"; + + my $is_alpha = $semver->is_alpha; + if ($v =~ /[.]\d+-?[a-z]/) { + ok $is_alpha, "$v should be alpha"; + } else { + ok !$is_alpha, "$v should not be alpha"; + } +} + +local $@; +eval { $CLASS->new('') }; +ok $@, 'Empty string should be an invalid version'; + +for my $bv (qw( + 1.2 + 0 + 0.0 + 1.2b + 1.b + 1.04.0 + 1.65.r2 +)) { + local $@; + eval { $CLASS->new($bv) }; + like $@, qr{Invalid semantic version string format: "$bv"}, + qq{"$bv" should be an invalid semver}; +} + +# Try a vstring. +isa_ok $version = $CLASS->new(v2.3.2), $CLASS, 'vstring version'; +is $version->stringify, 'v2.3.2', 'vestring should stringify with "v"'; +is $version->normal, '2.3.2', 'vstring should normalize without "v"'; + +# Try a shorter vstring. +my $no_2digitvst = $] < 5.10 && version->VERSION < 0.9910; +SKIP: { + skip 'Two-integer vstrings weak on Perl 5.8', 3 if $no_2digitvst; + isa_ok $version = $CLASS->new(v2.3), $CLASS, 'vstring version'; + is $version->stringify, 'v2.3', 'short vestring should stringify with "v"'; + is $version->normal, '2.3.0', 'short vstring should normalize without required 0'; +} + +# Try another SemVer. +isa_ok my $cloned = $CLASS->new($version), $CLASS, 'Cloned SemVer'; +is $cloned->stringify, $version->stringify, 'Cloned stringify like original'; +is $cloned->normal, $version->normal, 'Cloned should normalize like original'; + +# Try a SemVer with alpha. +isa_ok $version = $CLASS->new('2.3.2-b1'), $CLASS, 'new version'; +isa_ok $cloned = $CLASS->new($version), $CLASS, 'Second cloned SemVer'; +is $cloned->stringify, $version->stringify, 'Second cloned stringify like original'; +is $cloned->normal, $version->normal, 'Second cloned should normalize like original'; + +# Numify should die +local $@; +eval { $version->numify }; +like $@, qr{Semantic versions cannot be numified}, + 'Should get error from numify()'; + +# Now do some comparisons. Start with equivalents. +for my $spec ( + [ '1.2.2', '1.2.2' ], + [ '1.2.23', '1.2.23' ], + [ '0.0.0', '0.0.0' ], + [ '999.888.7777', '999.888.7777' ], + [ '0.1.2-beta3', '0.1.2-beta3' ], + [ '1.0.0-rc-1', '1.0.0-RC-1' ], +) { + my $l = $CLASS->new($spec->[0]); + my $r = $CLASS->new($spec->[1]); + is $l->vcmp($r), 0, "$l->vcmp($r) == 0"; + is $l <=> $r, 0, "$l <=> $r == 0"; + is $r <=> $l, 0, "$r <=> $l == 0"; + cmp_ok $l, '==', $r, "$l == $r"; + cmp_ok $l, '==', $r, "$l == $r"; + cmp_ok $l, '<=', $r, "$l <= $r"; + cmp_ok $l, '>=', $r, "$l >= $r"; + is $l cmp $r, 0, "$l cmp $r == 0"; + is $r cmp $l, 0, "$r cmp $l == 0"; + cmp_ok $l, 'eq', $r, "$l eq $r"; + cmp_ok $l, 'eq', $r, "$l eq $r"; + cmp_ok $l, 'le', $r, "$l le $r"; + cmp_ok $l, 'ge', $r, "$l ge $r"; +} + +# Test equivalents with declare() +for my $spec ( + [ '1.2.0', '1.2' ], + [ '0.0.0', '0' ], + [ '1.4_0', '1.4' ], + [ '1.08', '1.8' ], + [ 1.02_30, '1.23.0' ], + [ '1.02_30', '1.23.0' ], + [ '999.888.7777-alpha.3', '999.888.7777-alpha.3' ], + [ '0.1.2-beta3', '0.1.2-beta3' ], + [ '1.0.0-rc-1', '1.0.0-RC-1' ], +) { + my $l = $CLASS->declare($spec->[0]); + my $r = $CLASS->declare($spec->[1]); + is $l->vcmp($r), 0, "declare $l->vcmp($r) == 0"; + is $l <=> $r, 0, "declare $l <=> $r == 0"; + is $r <=> $l, 0, "declare $r <=> $l == 0"; + cmp_ok $l, '==', $r, "declare $l == $r"; + cmp_ok $l, '==', $r, "declare $l == $r"; + cmp_ok $l, '<=', $r, "declare $l <= $r"; + cmp_ok $l, '>=', $r, "declare $l >= $r"; + is $l cmp $r, 0, "declare $l cmp $r == 0"; + is $r cmp $l, 0, "declare $r cmp $l == 0"; + cmp_ok $l, 'eq', $r, "declare $l eq $r"; + cmp_ok $l, 'eq', $r, "declare $l eq $r"; + cmp_ok $l, 'le', $r, "declare $l le $r"; + cmp_ok $l, 'ge', $r, "declare $l ge $r"; +} + +# Test equivalents with parse() +for my $spec ( + [ '1.02.0', '1.2.0' ], + [ '0.0.0', '0' ], + [ '1.4_0', '1.4' ], + [ 1.02_30, '1.23.0' ], + [ '1.02_30', '1.23.0' ], + [ '999.888.7777-alpha.3', '999.888.7777-alpha.3' ], + [ '0.1.2-beta3', '0.1.2-beta3' ], + [ '1.0.0-rc-1', '1.0.0-RC-1' ], +) { + my $l = $CLASS->parse($spec->[0]); + my $r = $CLASS->parse($spec->[1]); + is $l->vcmp($r), 0, "parse $l->vcmp($r) == 0"; + is $l <=> $r, 0, "parse $l <=> $r == 0"; + is $r <=> $l, 0, "parse $r <=> $l == 0"; + cmp_ok $l, '==', $r, "parse $l == $r"; + cmp_ok $l, '==', $r, "parse $l == $r"; + cmp_ok $l, '<=', $r, "parse $l <= $r"; + cmp_ok $l, '>=', $r, "parse $l >= $r"; + is $l cmp $r, 0, "parse $l cmp $r == 0"; + is $r cmp $l, 0, "parse $r cmp $l == 0"; + cmp_ok $l, 'eq', $r, "parse $l eq $r"; + cmp_ok $l, 'eq', $r, "parse $l eq $r"; + cmp_ok $l, 'le', $r, "parse $l le $r"; + cmp_ok $l, 'ge', $r, "parse $l ge $r"; +} + +# Test not equal. +for my $spec ( + ['1.2.2', '1.2.3'], + ['0.0.1', '1.0.0'], + ['1.0.1', '1.1.0'], + ['1.1.1', '1.1.0'], + ['1.2.3-b', '1.2.3'], + ['1.2.3', '1.2.3-b'], + ['1.2.3-a', '1.2.3-b'], + ['1.2.3-aaaaaaa1', '1.2.3-aaaaaaa2'], +) { + my $l = $CLASS->new($spec->[0]); + my $r = $CLASS->new($spec->[1]); + cmp_ok $l->vcmp($r), '!=', 0, "$l->vcmp($r) != 0"; + cmp_ok $l, '!=', $r, "$l != $r"; + cmp_ok $l, 'ne', $r, "$l ne $r"; +} + +# Test not equal with declare. +for my $spec ( + ['1.2.2', '1.2.3'], + ['0.0.1', '1.0.0'], + ['1.0.1', '1.1.0'], + ['1.1.1', '1.1.0'], + ['1.2.3-b', '1.2.3'], + ['1.2.3', '1.2.3-b'], + ['1.2.3-a', '1.2.3-b'], + ['1.2_0', '1.20' ], + ['1.2.3-aaaaaaa1', '1.2.3-aaaaaaa2'], +) { + my $l = $CLASS->declare($spec->[0]); + my $r = $CLASS->declare($spec->[1]); + cmp_ok $l->vcmp($r), '!=', 0, "declare $l->vcmp($r) != 0"; + cmp_ok $l, '!=', $r, "declare $l != $r"; + cmp_ok $l, 'ne', $r, "declare $l ne $r"; +} + +# Test not equal with parse. +for my $spec ( + ['1.2.2', '1.2.3'], + ['0.0.1', '1.0.0'], + ['1.0.1', '1.1.0'], + ['1.1.1', '1.1.0'], + ['1.2.3-b', '1.2.3'], + ['1.2.3', '1.2.3-b'], + ['1.2.3-a', '1.2.3-b'], + ['1.2_0', '1.2.0' ], + ['1.2.3-aaaaaaa1', '1.2.3-aaaaaaa2'], +) { + my $l = $CLASS->parse($spec->[0]); + my $r = $CLASS->parse($spec->[1]); + cmp_ok $l->vcmp($r), '!=', 0, "parse $l->vcmp($r) != 0"; + cmp_ok $l, '!=', $r, "parse $l != $r"; + cmp_ok $l, 'ne', $r, "parse $l ne $r"; +} + +# Test >, >=, <, and <=. +for my $spec ( + ['2.2.2', '1.1.1'], + ['2.2.2', '2.1.1'], + ['2.2.2', '2.2.1'], + ['2.2.2-b', '2.2.1'], + ['2.2.2', '2.2.2-b'], + ['2.2.2-c', '2.2.2-b'], + ['2.2.2-rc-2', '2.2.2-RC-1'], + ['0.9.10', '0.9.9'], +) { + my $l = $CLASS->new($spec->[0]); + my $r = $CLASS->new($spec->[1]); + cmp_ok $l->vcmp($r), '>', 0, "$l->vcmp($r) > 0"; + cmp_ok $r->vcmp($l), '<', 0, "$r->vcmp($l) < 0"; + cmp_ok $l, '>', $r, "$l > $r"; + cmp_ok $l, '>=', $r, "$l >= $r"; + cmp_ok $r, '<', $l, "$r < $l"; + cmp_ok $r, '<=', $l, "$r <= $l"; + cmp_ok $l, 'gt', $r, "$l gt $r"; + cmp_ok $l, 'ge', $r, "$l ge $r"; + cmp_ok $r, 'lt', $l, "$r lt $l"; + cmp_ok $r, 'le', $l, "$r le $l"; +} + +# Compare Versions from SemVer 2.0 +my @ver = ("0.9.0","1.0.0-alpha","1.0.0-alpha.1","1.0.0-alpha.beta","1.0.0-beta","1.0.0-beta.2","1.0.0-beta.11","1.0.0-beta.31","1.0.0-beta.200","1.0.0-rc.1","1.0.0","2.0.0","2.1.0","2.1.1"); + +for (my $i = 0; $i < (scalar(@ver)-1); $i++) { + for (my $j = $i+1; $j < scalar(@ver); $j++) { + my $l = SemVer->new($ver[$i]); + my $r = SemVer->new($ver[$j]); + cmp_ok $l, '<', $r, "$l < $r"; + } +} + +# Compare to version objects. +my $semver = $CLASS->new('1.2.0'); +for my $v (qw( + 1.002 + 1.2.0 + v1.002 + v1.2.0 +)) { + my $version = version->new($v); + ok $semver == $version, "$semver == $version"; +} + +# Compare to strings. +for my $v (qw( + 1.2.0 + v1.2.0 +)) { + my $semver = $CLASS->new($v); + cmp_ok $semver, '==', $v, qq{$semver == "$v"}; + cmp_ok $v, '==', $semver, qq{"$v" == $semver}; + cmp_ok $semver, 'eq', $v, qq{$semver eq "$v"}; + cmp_ok $v, 'eq', $semver, qq{"$v" eq $semver}; +} + +# Tweak tweak v prefix regex? Some versions of version:vpp do it differently. +my $vq = qr/^\d+[.][^.]+$/; +if ($CLASS->declare('0')->stringify eq 'v0') { + $vq = qr/^\d+([.]?[^.]+)?$/; +} + +# Test declare() and parse. +for my $spec ( + ['1.2.2', '1.2.2'], + ['01.2.2', '1.2.2'], + ['1.02.2', '1.2.2'], + ['1.2.02', '1.2.2'], + ['1.2.02-b', '1.2.2-b'], + ['1.2.02-beta-3 ', '1.2.2-beta-3'], + ['1.02.02-rc1', '1.2.2-rc1'], + ['1.0', '1.0.0'], + ['1.1', '1.1.0', '1.100.0'], + [ 1.1, '1.1.0', '1.100.0'], + ['1.1-b1', '1.1.0-b1', '1.100.0-b1'], + ['1-b', '1.0.0-b'], + ['9.0-beta4', '9.0.0-beta4'], + [' 012.2.2', '12.2.2'], + ['99999998', '99999998.0.0'], + ['1.02_30', '1.23.0'], + [1.02_30, '1.23.0'], + [3.4, '3.4.0', '3.400.0'], + [3.04, '3.4.0', '3.40.0' ], + ['3.04', '3.4.0', '3.40.0' ], + [v3.4, '3.4.0' ], + [9, '9.0.0' ], + ['9', '9.0.0' ], + ['0', '0.0.0' ], + [0, '0.0.0' ], + ['0-rc1', '0.0.0-rc1' ], +) { SKIP: { + skip 'Two-integer vstrings weak on Perl 5.8', 12 + if $no_2digitvst && Scalar::Util::isvstring($spec->[0]); + my $r = $CLASS->new($spec->[1]); + isa_ok my $l = SemVer->declare($spec->[0]), $CLASS, "Declared $spec->[0]"; + my $string = Scalar::Util::isvstring($spec->[0]) + ? join '.', map { ord } split // => $spec->[0] : $spec->[0]; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + $string += 0 if $string =~ s/_//g; + my $vstring = $string =~ $vq ? "v$string" : $string; + is $l->stringify, $vstring, qq{... And it should stringify to "$vstring"}; + is $l->normal, $spec->[1], qq{... And it should normalize to "$spec->[1]"}; + + # Compare the non-semantic version string to the semantic one. + cmp_ok $spec->[0], '==', $r, qq{$r == "$spec->[0]"}; + + if ($spec->[0] && $spec->[0] !~ /^[a-z]/ && $spec->[0] !~ /[.]{2}/) { + my $exp = $spec->[2] || $spec->[1]; + isa_ok $l = SemVer->parse($spec->[0]), $CLASS, "Parsed $spec->[0]"; + $string = "v$string" if Scalar::Util::isvstring($spec->[0]); + $string =~ s/_//; + is $l->stringify, $string, "... And it should stringify to $string"; + is $l->normal, $exp, "... And it should normalize to $exp"; + + # Try with the parsed version. + $r = $CLASS->new($spec->[2]) if $spec->[2]; + cmp_ok $l, '==', $r, qq{$l == $r} unless $string =~ /_/; + } + + # Try creating as a version object and cloning. + if ($spec->[0] !~ /[a-z]/i) { + isa_ok my $v = version->parse($spec->[0]), 'version', "base version $spec->[0]"; + isa_ok my $sv = SemVer->new($v), 'SemVer', "SemVer from base version $spec->[0]"; + is $sv->stringify, $string, qq{... And it should stringify to "$vstring"}; + SKIP: { + skip 'version 0.9911 broke alpha->normal()', 1, + if $spec->[0] =~ /_/ && version->VERSION == 0.9911; + is $sv->normal, $l->normal, + '... And it should normalize to "' . $l->normal . '"'; + } + } +}} + +for my $v (qw( + 1.2.02b + 1.2.02beta-3 + 1.02.02rc1 + 1.1b1 + 1b + 9.0beta4 + 0rc1 +)) { + eval { + my $l = SemVer->declare($v); + }; + if ($@) { + is 1, 1, $v.' is not a SemVer'; + } + else { + is 1, 0, $v.' should not be not a SemVer'; + } +} diff -Nru libsemver-perl-0.7.0/t/corpus.t libsemver-perl-0.10.0/t/corpus.t --- libsemver-perl-0.7.0/t/corpus.t 1970-01-01 00:00:00.000000000 +0000 +++ libsemver-perl-0.10.0/t/corpus.t 2020-05-09 13:57:55.000000000 +0000 @@ -0,0 +1,112 @@ +#!/usr/bin/perl -w + +# Test the SemVer corpus from https://regex101.com/r/Ly7O1x/3/. + +use strict; +use warnings; +use Test::More tests => 222; +#use Test::More 'no_plan'; + +use FindBin qw($Bin); +use lib "$Bin/../lib"; +use SemVer; + +# Valid Semantic Versions +for my $v (qw( + 0.0.4 + 1.2.3 + 10.20.30 + 1.1.2-prerelease+meta + 1.1.2+meta + 1.1.2+meta-valid + 1.0.0-alpha + 1.0.0-beta + 1.0.0-alpha.beta + 1.0.0-alpha.beta.1 + 1.0.0-alpha.1 + 1.0.0-alpha0.valid + 1.0.0-alpha.0valid + 1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay + 1.0.0-rc.1+build.1 + 2.0.0-rc.1+build.123 + 1.2.3-beta + 10.2.3-DEV-SNAPSHOT + 1.2.3-SNAPSHOT-123 + 1.0.0 + 2.0.0 + 1.1.7 + 2.0.0+build.1848 + 2.0.1-alpha.1227 + 1.0.0-alpha+beta + 1.2.3----RC-SNAPSHOT.12.9.1--.12+788 + 1.2.3----R-S.12.9.1--.12+meta + 1.2.3----RC-SNAPSHOT.12.9.1--.12 + 1.0.0+0.build.1-rc.10000aaa-kk-0.1 + 1.0.0-0A.is.legal +)) { + local $@; + ok my $sv = eval { SemVer->new($v) }, qq{New "$v" should be valid} or diag $@; + is $sv->stringify, $v, qq{Should stringify to "$v"}; + + ok $sv = eval { SemVer->declare($v) }, qq{Declare "$v" should work} or diag $@; + is $sv->stringify, $v, qq{Should stringify to "$v"}; + + ok $sv = eval { SemVer->parse($v) }, qq{Parse "$v" should work} or diag $@; + is $sv->stringify, $v, qq{Should stringify to "$v"}; +} + +SKIP: { + local $TODO = 'Large versions overflow version.pm integer bounds'; + local $SIG{__WARN__} = sub { }; # Ignore version overflow warning + my $v = '99999999999999999999999.999999999999999999.99999999999999999'; + ok my $sv = eval { SemVer->new($v) }, qq{"$v" should be valid}; + is $sv->stringify, $v, qq{Should stringify to "$v"}; +} + +# Invalid Semantic Versions +for my $bv (qw( + 1 + 1.2 + 1.2.3-0123 + 1.2.3-0123.0123 + 1.1.2+.123 + +invalid + -invalid + -invalid+invalid + -invalid.01 + alpha + alpha.beta + alpha.beta.1 + alpha.1 + alpha+beta + alpha_beta + alpha. + alpha.. + beta + 1.0.0-alpha_beta + -alpha. + 1.0.0-alpha.. + 1.0.0-alpha..1 + 1.0.0-alpha...1 + 1.0.0-alpha....1 + 1.0.0-alpha.....1 + 1.0.0-alpha......1 + 1.0.0-alpha.......1 + 01.1.1 + 1.01.1 + 1.1.01 + 1.2 + 1.2.3.DEV + 1.2-SNAPSHOT + 1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788 + 1.2-RC-SNAPSHOT + -1.0.3-gamma+b7718 + +justmeta + 9.8.7+meta+meta + 9.8.7-whatever+meta+meta + 99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12 +)) { + local $@; + eval { SemVer->new($bv) }; + ok $@, qq{"$bv" should be an invalid semver}; +}