Hi,

ir. ing. Jan Dockx wrote:
Well, your schema does follow the Java standard (<http://java.sun.com/j2se/1.5.0/docs/guide/versioning/spec/versioning2.html#wp89936>). That might be a good default. Maven could apply a strategy pattern to allow for other versioning schemes. Only 3 functions are needed, as far as I can see:

/**
 * @invar ! equals(null);
 * @invar ! isCompatible(null);
 * @invar ! isBetter(null);
 * @invar (forall Version v; equals(v) ==> isCompatible(v));
 * @invar (forall Version v; equals(v) ==> ! isBetter(v));
 * @invar (forall Version v; isBetter(v) ==> isCompatible(v));
 */
public interface Version {

  boolean isCompatible(Version other);

  boolean isBetter(Version other);

  boolean equals(Object other);

}


What tool uses those invariant annotations? Looks useful for application 
validation.

(You can't extend Comparable, because the contract says that you need to have a result for all combinations of objects of a given type, and here only compatible versions are comparable).

The only thing left for dependency notes in a dependency listing is then to say whether you want compatible, better versions, or you want to stay with the exact version denoted. You don't have to specify here which versions you want, the dependency knows itself whether or not it is compatible and better than what you require.

<dependency>
    <groupId>...</groupId>
        <artifactId>...<artifactId>
    <version>[versionString]</version>
        <useBestCompatible>true</useBestCompatible>
    <scope>...</scope>
</dependency>

What would be in the version string? Usually the first N digits denote 
incompatible
versions, later ones denote compatibility updates, for instance for all X: 1.2.X
is compatible.

Right now maven already handles this using version ranges: [1.2,1.3) indicates 
1.2[.0] and
all other compatible versions (excluding alpha versions).


The POM of an artifact should than refer to a Version implementation. So, version implementations should be separate artifacts themselves.

...
<versionScheme>
    <groupId>...</groupId>
        <artifactId>...<artifactId>
    <version>[versionString]</version>
</versionScheme>
<version>[versionString]</version>
...


Yeah, something like that would be useful - it should define a metadata file
indicating the version class implementations to use for that artifact. That was 
one
other possibility I was considering. It's probably more flexible.

And the version scheme for version schemes should be fixed by Maven.


We probably need a factory too for each version implementation:

public interface VersionFactory {

  Version parse(String versionString);

}

Yup. Or a one arg constructor with string - it'll probably be called using 
reflection anyway.

-- Kenney



On 19 Dec 2006, at 11:44, Carlos Sanchez wrote:

Sound like a lot of added complexity that will cause trouble to all
tooling on top of Maven

What about forcing the xml schema to a standard versioning system. If
it's used then you'll benefit from all Maven goodies. If you just use
a String Maven will do its best.

For instance

<version>
 <major>1</major>
 <minor>2<minor>
 <bug>1</bug>
 <buildnumber>123</buildnumber>
</version>

It's gonna be more complex for manual editing but being standard xml
will be easier to implement

On 12/18/06, Kenney Westerhof <[EMAIL PROTECTED]> wrote:

Hi,

The current versioning implementation is IMHO too 'tight'. For instance,
2.0.0alpha1 is parsed as '0.0.0.0' with a qualifier of '2.0.0alpha1', whereas this should
be parsed in the same way as 2.0.0.alpha.1 or 2.0.0-alpha-1.

Here's a proposal:

- don't use the current 4-digit limitation, but instead list with a random amount of entries
- entries are separated by dots or dashes
- entries are separated by transition to/from alpha to numeric
- sub-lists are indicated by '-'
- entries can be either: string, integer, or sublist
- versions are compared entry by entry, where we have 3 options;
  * integer <=> integer: normal numerical compare
  * integer <=> string: integers are newer
  * integer <=> list: integers are newer
* string <=> string: if it's a qualifier, qualifier compare, else lexical compare,
     taking into account if either is a qualifier.
  * string <=> list: list is newer
* list <=> list: recursion, same as a 'top-level' version compare. Where one list is shorter, '0' is assumed (so 2.0 <=> 2 == 0, 2.0-alpha <=> 2.0 => 2.0-alpha <=> 2.0.0 = -1 (2.0 = newer))

Now for some examples to explain the rules above:

(note; i'm using the following notation:
   [1, 0] is a list with items 1, 0;
[1, 0, [2, 3]] is a list with items 1, 0, [2, 3] where the latter is a sublist)

Version parsing:

'1.0':          [1, 0]
'1.0.0.0.0'     [1, 0, 0, 0, 0]
'1.0-2.3':      [1, 0, [2, 3]]
'1.0-2-3':      [1, 0, [2, [3]]]

'1.0-alpha-1':  [1, 0, ["alpha", [1]]]
'1.0alpha1': [1, 0, ["alpha", [1]]] or [1, 0, "alpha", 1], which is the current implementation (see bottom)


String sorting (qualifiers)

SNAPSHOT < alpha < beta < gamma < rc < ga < unknown(lexical sort) < '' < sp

(ga = latest rc, final version
 '' = no qualifier, final version
 sp = service pack, improvement/addition on final release)

usually systems either use '' or ga, not both.

so 1.0-rc3 < 1.0-ga == 1.0 < 1.0-sp1 < 1.0.1


Comparing;

1)
  1.0-SNAPSHOT       <=>   1.0
  [1, 0, [SNAPSHOT]] <=>   [1, 0]

the first 2 items are equal, the last is assumed to be 0 for the right hand, and thus is newer.

2)
  1.0-beta-3            <=>  1.0-alpha-4

  [1, 0, ["beta", [3]]] <=> [1, 0, ["alpha", [4]]]

  same here, then "beta" is newer then "alpha" so the first half wins

3)
  1.0-2.3          <=>  1.0-2-3
  [1, 0, [2, 3]]   <=>  [1, 0, [2, [3]]]
first 2 items are the same, then this is left;
  [2, 3]          <=>   [2, [3]]
first item is the same, second item: the left list wins since the right one is a sublist. So 1.0-2.3 is newer than 1.0-2-3 (which seems right: -[digit] usually indicates a maintainer update, and '.' here a bugfix version, though i doubt this will be a valid usecase).

4)
   1.0-alpha-2          <=>  1.0alpha2

   The current implementation parses this as:

   [1, 0, [alpha, [2]]] <=>  [1, 0, alpha, 2]
   The right one is newer.

If we change parsing '1.0alpha2' by using sublists on alpha<->digit transition, both will parse
   as [1, 0, ["alpha", [2]]. I think this is preferrable.

we may need to flatten the list or assume alpha<->digit transitions create a new sublist.


So, I've given both a way to represent versions in a generic way, and an algorithm to compare versions. Replacing DefaultArtifactVersion is easy enough (see bottom), though ranges may be a bit more complicated.

This scheme will support the eclipse version numbering: http://wiki.eclipse.org/index.php/Version_Numbering (basically: major.minor.bugfix.qualifier: [major, minor, bugfix, qualifier] and Jboss: http://docs.jboss.org/process-guide/en/html/release-procedure.html,
(basically: X.YY.ZZ.Q*, for instance 1.2.3.alpha4: [1, 2, 3, "alpha", 4]

Maven:  major.minor(.bugfix)?(-(alpha|beta|rc)-X)? which will be:
[ major, minor, bugfix?, [ alpha|beta|rc, [X] ]

I'll probably miss some usecases or got some things wrong, but if we do not support some sort of <versionScheme> tag in the POM, we want to be able to accommodate versioning in a most generic way, and I think this comes close.

I've created an implementation[1] and a unit test[2].

I've had to comment out one assert: 2.0.1-xyz < 2.0.1. I think generally this is not the case. For example, the wiki guide to patching plugins states that you could patch a plugin and change it's version to 2.0-INTERNAL. In this case, 2.0 would be newer than 2.0-INTERNAL, which renders the wiki description invalid. In my sample
implementation, 2.0.1-xyz is newer than 2.0.1.
Though should this be required, the code is easily modified to reflect this.

So, WDYT?

Any additional version schemes that cannot be handled by this?

If this looks ok, then my next challenge will be to support ranges. ;)

[1] http://www.neonics.com/~forge/GenericArtifactVersion.java - put in maven-artifact/src/main/java/.../versioning/ Note: this one doesn't implement ArtifactVersion since we never know what the major/minor versions etc. will be. It could implement it and default to 0 if the item isn't an integer; [2] http://www.neonics.com/~forge/GenericArtifactVersionTest.java - put in maven-artifact/src/test/java/.../versioning/ Note: this test is a copy of the DefaultArtifactVersionTest, with Default replaced by Generic. The testVersionParsing is left out since the other unit test already takes care of checking if this works okay, and because GenericArtifactVersion doesn't implement ArtifactVersion. I've tested for all constructor calls that the toString() method yields the constructor argument.


-- Kenney

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--I could give you my word as a Spaniard.
No good. I've known too many Spaniards.
                            -- The Princess Bride

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to