ajoberstar / reckon

Infer a project's version from your Git repository.
Apache License 2.0
185 stars 28 forks source link

support maven's well-known version qualifiers #112

Closed esz closed 5 years ago

esz commented 5 years ago

When using the snapshot version schema snapshotFromProp(), the reckoner only supports maven's snapshot or final qualifier, i.e. I'm able to publish e.g. 1.2.3-SNAPSHOT (snapshot) or 1.2.3 (final) but I can't produce 1.2.3-rc1 or 1.2.3-rc.1.

Currently maven's ComparableVersion supports the following qualifiers (with a predefined order of precedence):

It would be great to have them supported in the reckoner. The concept is quite similar to the stage version schema stageFromProp(..) however the suffix pattern of the produced version differs (no commit hash, etc.). One problem is, that currently the reckoner isn't able to distinguish between the two versioning schemas in order to decide which pattern to produce since it only checks if a specific snapshot stage has been supplied or not.

Additional documentation on maven's versioning schema can be found in the corresponding unit test, confluence or on maven.apache.org.

ajoberstar commented 5 years ago

Thanks for the detail and reference links in this issue!

Reckon's version schemes are built around compliance with SemVer and Gradle's version precedence. In both cases no names are considered special when ordering between two components. e.g. rc < snapshot, and ga < rc. So, there's a little incompatibility there with the ga and sp variants, though you weren't specifically asking for those.

I wasn't aware of Maven's rules for this before, but I kept SNAPSHOT and alpha/beta/rc separate because it seemed unintuitive to me that a SNAPSHOT would be pulled in over an rc. Generally, I expect the more "mature" version to be picked up in a dynamic range.

From what I understand now, I don't think I'd want to include this, because it seems to muddy the waters of what reckon tries to provide. However, if I'm missing something, please let me know more about how you would expect this scheme to work within reckon.

esz commented 5 years ago

Hi @ajoberstar

My idea was to have reckon support the follwing classic "maven-style" versioning scheme very similar to the current Stage Version Scheme, however with the pattern for insignificant versions being different.

Type Scheme Example Description
final <major>.<minor>.<patch> 1.2.3 A version ready for end-user consumption
significant <major>.<minor>.<patch>-<stage>.<num> 1.3.0-alpha.1, 1.3.0-rc.1 A version indicating an important stage has been reached on the way to the next final release (e.g. alpha, beta, rc, milestone)
insignificant <major>.<minor>.<patch>-SNAPSHOT 1.3.0-SNAPSHOT A general build in-between significant releases.

I wasn't aware that this suggested schema isn't exactly 100% SemVer compliant. §11 says:

Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by comparing each dot separated identifier from left to right until a difference is found as follows: identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are compared lexically in ASCII sort order.

Which (as you already explained) means: 1.3.0-rc.1 < 1.3.0-SNAPSHOT (when using dynamic versions in maven)

.. it seemed unintuitive to me that a SNAPSHOT would be pulled in over an rc ..

You're right. I wasn't aware of that - somehow I overlooked this when reading the maven docs:

alpha < beta < milestone < rc = cr < snapshot < "" = final = ga < sp

The funny thing is, that as for SNAPSHOT vs rc gradle works the other way round and (in contrast to maven) will favor rc: VersionConstraint

  • The strings "rc", "release" and "final" are considered higher than any other string part (sorted in that order): 1.0-zeta < 1.0-rc < 1.0-release < 1.0-final < 1.0
  • The string "SNAPSHOT" has no special meaning, and is sorted alphabetically like any other string part: 1.0-alpha < 1.0-SNAPSHOT < 1.0-zeta < 1.0-rc < 1.0

With the subtle differences in SemVer vs. gradle vs. maven I understand your intention to keep things as simple as possible only requiring the user to remember the "alphabetical ordering" rule. Please feel free to close this issue again.