Reputation: 35823
The answer https://stackoverflow.com/a/31482463/927493 explains the order of Maven versions. Following https://blog.soebes.de/blog/2017/02/04/apache-maven-how-version-comparison-works/, you can compare versions on the command line. I got the following results:
C:\coprogramme\apache-maven-3.5.0\lib>java -jar maven-artifact-3.5.0.jar 2.0.0 2.0.0-a
Display parameters as parsed by Maven (in canonical form) and comparison result:
1. 2.0.0 == 2
2.0.0 < 2.0.0-a
2. 2.0.0-a == 2-a
C:\coprogramme\apache-maven-3.5.0\lib>java -jar maven-artifact-3.5.0.jar 2.0.0 2.0.0-alpha
Display parameters as parsed by Maven (in canonical form) and comparison result:
1. 2.0.0 == 2
2.0.0 > 2.0.0-alpha
2. 2.0.0-alpha == 2-alpha
Following the answer and also the Javadoc in https://github.com/apache/maven/blob/master/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java, the version parts alpha
and a
should be equal, which is apparently not the case.
Can anyone explain this to me?
Upvotes: 0
Views: 1399
Reputation: 1187
Despite what the documentation says, it appears that a
is a synonym for alpha
only when it is immediately followed by a digit. So
2.0.0-a1
is equivalent to 2.0.0-alpha1
and 2.0.0-alpha-1
(but not 2.0.0-alpha.1
)a
in 2.0.0-a
, 2.0.0-a.1
or 2.0.0-a-1
is an "unknown qualifier", not equivalent to 2.0.0-alpha-1
, and sorted after all the known qualifiersThe behaviour appears because ComparableVersion
has two ways of defining aliases, in the inner class that deals with string components:
private static final List<String> QUALIFIERS =
Arrays.asList( "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" );
private static final Properties ALIASES = new Properties();
static
{
ALIASES.put( "ga", "" );
ALIASES.put( "final", "" );
ALIASES.put( "release", "" );
ALIASES.put( "cr", "rc" );
}
// ...
StringItem( String value, boolean followedByDigit )
{
if ( followedByDigit && value.length() == 1 )
{
// a1 = alpha-1, b1 = beta-1, m1 = milestone-1
switch ( value.charAt( 0 ) )
{
case 'a':
value = "alpha";
break;
case 'b':
value = "beta";
break;
case 'm':
value = "milestone";
break;
default:
}
}
this.value = ALIASES.getProperty( value , value );
}
a
, b
, and m
, that is only triggered if followedByDigit==true
, and that only happens when the qualifier was terminated by the next character being a digit.ga
, final
and release
are exactly equivalent to the empty string (with the latter being the canonical form), and cr
's canonical form is rc
. This part behaves as the OP expects.I would guess that this is based on observed version usage, where sometimes letters are used literally as versions (e.g. OpenSSL used to use a trailing letter or two to number patch releases, such as 0.9.7m or 0.9.8zh), while alpha, beta and milestone releases always have a release number in practice, and projects using a short version aren't going to put any extra characters in: so a
by itself meaning "alpha" never actually occurs.
It's a shame it's not documented properly!
Upvotes: 4