Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Make version handling pluggable

tbd

Define a grammar for version specifications

When somebody devices a version scheme that cannot be handled by the above, it should be possible
to plug in a new scheme. Two possible scenarios for unsupported schemes:

  • The dash hash higher priority than the dot: 1-0 is newer than 1.0
  • Dashes and dots have the same priority: 1.1 == 1-1.
  • Qualifier order is different, or unknown qualifiers.

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

Define a grammar for version specifications

I'm not entirely sure this is necessary, but for other languages that cannot use pre-packaged version scheme implementations in Java,
we need to have some sort of metadata, preferrably in the version-scheme artifact, describing the version scheme. Perhaps something like
version-scheme-1.0.jar!/META-INF/maven/version-scheme.file-extension 

Several proposals have been made for the version scheme description language:

  • regular expressions. Downside: you cannot record version ordering information, only parse rules
  • (E)BNF grammar. Same downside, though the operator ('.' and '-') priority can be expressed by the level in the AST.
  • XSD.
  • XML, where we provide an XSD with the grammar for the grammar.

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>

A sample scheme:

No Format

<versionSchemeDefinition>
  <qualifierDefinition name="snapshot"/>
  <qualifierDefinition name="alpha"/>
  <qualifierDefinition name="beta"/>
  <qualifierDefinition name="rc"/>
  <qualifierDefinition name=""/>
  <qualifierDefinition name="ga"/>
  <qualifierDefinition name="sp"/>
  <numberComponent name="major"/>
  <numberComponent name="minor" optional="true"/>
  <numberComponent name="micro" optional="true"/>
  <stringComponent name="qualifier" optional="true"/>
  <numberComponent name="buildnumber" optional="true"/>
</versionSchemeDefinition>

This scheme doesn't even come close to being able to describe the variety of
version schemes supported by my proposal.

Perhaps it's better if, when we do XML, we use XSD to describe the version schemes.
We define a set of simple/complextypes that people have to extend, and the engine can then
convert it to a parser/verifier/order implementation/representation using the base classes.
The parser would use the 'prefix' values and the type attributes to determine what kind of
token is next, in the version string. It would then build an XML DOM that can be validated against
the XSD, which can have extra rules.

Anyway, UDDI tried to do something similar for random applications - to have the API specs
in a uniform format so you could generate an application around reusable components, but that didn't work out
and AFAIK the specs are just human readable documents. If somebody wants to create a parser/validator/sorter for
a version spec, there should just be enough documentation for them to do it.tbd