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



John Casey wrote:
> Hmm, okay. I'm just going to reply at the top level, since I'm going to
> make
> a few general comments:
>
> 1. I really like this explanation/algorithm/implementation. It seems to
> take
> into account a LOT of permutations, and even more importantly, it
specifies
> a specification that we can write down in whatever form...and then
extend,
> if necessary.

Indeed.

> 1a. I think the version scheme should be specified in something like
> EBNF so
> people can write compliant lexers/parsers in whatever language they
want.

Hm, good idea, except most grammars use other syntax for EBNF or only
support BNF.
If we had a pluggable 'version' component, the implementation would take
care of
parsing/ordering, and we didn't need to specify the version in EBNF, but
just some metadata in the version jar or the project's homepage.


I script almost everything in Ruby, not Java. Having some sort of normal
form would be immensly useful, if for nothing else but posterity.

1b. For Java, I think this version-parser needs to be separated from
> maven-artifact, and available for reuse by itself from other APIs
(thinking
> plugins here, among other things).

Yes, good idea.

> 2. While I do like the following algorithm, I think it needs to be the
> DEFAULT version scheme, and we need to make room for others to plug in
> their
> own. We can spend years trying to incorporate all possible version
schemes
> in a single parser, but IMO the complexity involved with encompassing
every
> version in a single parser just isn't worth it.

The 1b would support this pluggability. But agreed, we can't support all
version schemes, but this comes close IMHO.

> I think we need to come up with an API for other implementations of a
> VersionScheme. This probably isn't going to be a single interface, for
the
> purposes of separating behaviors...but we should include in this API
> everything that needs to be known about a version in order to:
>
> * resolve conflicts
>
> * compute range boundaries
>
> * order versions
>
> * determine what version strings denote snapshot behavior (multiple
> releases
> of a single version of an RPM can act this way, for instance)

So we can handle versions that don't have the SNAPSHOT keyword in them
as snapshots too? That would be cool - for instance, some projects use
'-dev'
to denote snapshots.


Ugh. While I like the idea of flexibility, this takes it too far. I like
being able to look at any Maven project in the world and know, by looking at
it, that -SNAPSHOT means "in development", and not have to guess if some
special project is using -dev. This should be immutable, imo.

* whatever else.

Right. ;)

The biggest difference in the API would be that there's no
'getMajor|MinorVersion' anymore
since we can't know if the scheme has that or even names it like that.


You could reasonably assume that the first element is major, second is
minor, and then - whatever the cardinality - the rest accessible by index.

2a. Version schemes should be standardized, and available to a build using
> artifact resolution and the default maven version scheme (you have to
> make a
> stand somewhere :). IMO, specifying a regex or some other free-form
version
> scheme directly inside a POM is neither sufficient nor reusable enough;
if
> people need a custom version scheme, they need to encode it somewhere
> that's
> permanent.

Agreed. Except that I'd like to split off the discussion about version
specifications.
We've got 3 major points of discussion here:

- replace the default implementation to be more flexible (my original
intent)
- make version schemes pluggable/configurable, for instance by specifying
a version lib implementation
- define something default to specify version schemes, like regex/EBNF/xsd

> This is just my opinion, but I've been working outside the bounds of
> 'normal' Jar/Maven versioning quite a bit over the last year and a half,
> and
> I definitely think we need to keep it in mind that the only truly
> sufficient
> model of reality is reality itself...which means a lot of complexity.
>
> I think that's about it; I'll keep thinking, though.

Thanks!

More details on RPM versioning would be welcome; I'm only familiar with
Debian versioning
which would, AFAIK, be supported by my proposal.

-- Kenney

>
> Cheers,
>
> -john
>
>
> 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]
>>
>>
>

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




--
Eric Redmond
http://codehaus.org/~eredmond

Reply via email to