issue tracked as MNG-3010
Improve default support for version schemes
...
I'm proposing the following implementation: GenericArtifactVersion.java (unit test: GenericArtifactVersionTest.java). It has been integrated in artifact 3.0-SNAPSHOT r656775(15/5/2008) as ComparableVersion.java.
Features:
- Mixing of '-' (dash) and '.' (dot) separators
- Transition between characters and digits also constitutes a separator:
- 1.0alpha1 => [1, 0, alpha, 1]; This fixes '1.0alpha10 < 1.0alpha2'
- Unlimited number of version components
- Version components in the text can be digits or strings
- strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering
- well-known qualifiers (case insensitive)
- alpha or a
- beta or b
- milestone or m
- rc or cr
- snapshot (NOTE; snapshot needs discussion)
- (the empty string) or ga or final
- sp
- well-known qualifiers (case insensitive)
- version components prefixed with '-' will result in a sub-list of version components.
A dash usually precedes a qualifier, and is always less important than something preceded with a dot.
We need to somehow record the separators themselves, which is done by sublists.
Parse examples:- 1.0-alpha1 => [1, 0, ["alpha", 1]]
- 1.0-rc-2 => [1, 0, ["rc", [2]]]
...
| Integer | String | List | null |
---|---|---|---|---|
Integer | Highest is newer | Integer is newer | Integer is newer | If integer==0 then equal, |
String | Integer is newer | order by well-known | List is newer | Compare with "" |
List | Integer is newer | List is newer | Version itself is a list; compare item by item | Compare with empty list item (recursion) |
null | If integer==0 then equal, | Compare with "" | Compare with empty list item (recursion) | doesn't happen |
...
To make version schemes pluggable, the following is required:
A POM change to support something like this to identify a version-scheme implementation artifact:
No Format <versionScheme> <groupId>..</groupId> <artifactId>..</artifactId> <version>..</version> <\!-\- we may need to disallow version ranges here \--> </versionScheme>
- Maven-metadata at the artifact level needs to include the tag above. We'll limit version schemes on a per artifact basis. This is required in order to resolve versions using ranges.
- An interface definition for VersionScheme
- A way to detect what is the version class inside the version-scheme artifact; I hope we can use plexus, as long as multiple version-scheme implementations (same hint, same package/classname) can be accessed simultaneously without conflict.
- Refactoring the version code out of maven-artifact so plugin code etc. can use it too
- The super pom will contain a default versionScheme tag listing the maven internal implementation
...
As an example here's an XSD you could use to describe versions:
No Format |
---|
<xs:schema> <xs:element name="versionSchemeDefinition"> <xs:complexType> <xs:sequence> <!-- the order of qualifierDefinitions is from oldest to newest --> <xs:element ref="qualifierDefinition" minOccurs="0" maxOccurs="unbounded"/> <xs:choice maxOccurs="unbounded" minOccurs="0"> <xs:element ref="stringComponent"/> <xs:element ref="numberComponent"/> <xs:element ref="subComponent"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="qualifierDefinition"> <xs:complexType> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="caseSensitive" type="xs:boolean" default="false"/> </xs:complexType> </xs:element> <xs:element name="stringComponent"> <xs:complexType> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="prefix" type="xs:string" default="."/> </xs:complexType> </xs:element> <xs:element name="numberComponent" type="xs:int"> <xs:complexType> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="prefix" type="xs:string" default="."/> <xs:attribute name="optional" type="xs:boolean" default="false"/> </xs:complexType> </xs:element> <xs:element name="subComponent"> <xs:complexType> <xs:choice maxOccurs="unbounded" minOccurs="0"> <xs:element ref="stringComponent"/> <xs:element ref="numberComponent"/> <xs:element ref="subComponent"/> </xs:choice> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="prefix" type="xs:string" default="-"/> </xs:complexType> </xs:element> </xs:schema> |
...