...
- Major versoin
- Minor version
- Incremental version (bugfix)
- Build number
- A Qualifier.
Flaws
Other than the limitation of supported versions, the current implementation has several flaws:
- It only supports the following schemes:
- 'positiveInteger-buildnumber' where buildnumber doesn't start with '0' and has to be
- 'positiveinteger-qualifier'
- positiveInteger(.positiveInteger(.positiveInteger))-(buildNr|qualifier)
- Inconsistent/unintuitive parsing:
Wiki Markup in something-X, where X is \[1..9\], X will be a buildnumber
- in something-0X, where X is any string, '0X' will be a qualifier
- something.0something will yield 0.0.0.0-something.0something
- something.NaN will also yield 0.0.0.0-something.NaN
- getBuildNumber returns '0' when no buildnumber is specified, yet you can never specify 0 as a buildnumber
- qualifiers are sorted lexically
- if a qualifier is a prefix of another, the shorter one is considered newer (example:'1.0-alpha10' is considered older than '1.0-alpha1')
The unit tests that are there to test comparison only check for a few cases with snapshots. When all tests
(version A < version B) are expanded to also test for SNAPSHOTs (version A-SNAPSHOT < version B-SNAPSHOT) a
lot of the tests fail.
< =
Left | Op | Right | Without SNAPSHOT | With SNAPSHOT |
---|---|---|---|---|
1-SNAPSHOT | = | 1-SNAPSHOT | | |
1-SNAPSHOT | < | 2-SNAPSHOT | | |
1.5-SNAPSHOT | < | 2-SNAPSHOT | | |
1-SNAPSHOT | < | 2.5-SNAPSHOT | | |
1-SNAPSHOT | = | 1.0-SNAPSHOT | | |
1-SNAPSHOT | = | 1.0.0-SNAPSHOT | | |
1.0-SNAPSHOT | < | 1.1-SNAPSHOT | | |
1.1-SNAPSHOT | < | 1.2-SNAPSHOT | | |
1.0.0-SNAPSHOT | < | 1.1-SNAPSHOT | | |
1.1-SNAPSHOT | < | 1.2.0-SNAPSHOT | | |
1.0-alpha-1-SNAPSHOT | < | 1.0-SNAPSHOT | | |
1.0-alpha-1-SNAPSHOT | < | 1.0-alpha-2-SNAPSHOT | | |
1.0-alpha-1-SNAPSHOT | < | 1.0-beta-1-SNAPSHOT | | |
1.0-SNAPSHOT-SNAPSHOT | < | 1.0-beta-1-SNAPSHOT | | |
1.0-SNAPSHOT-SNAPSHOT | < | 1.0-SNAPSHOT | | |
1.0-alpha-1-SNAPSHOT-SNAPSHOT | < | 1.0-alpha-1-SNAPSHOT | | |
1.0-SNAPSHOT | < | 1.0-1-SNAPSHOT | | |
1.0-1-SNAPSHOT | < | 1.0-2-SNAPSHOT | | |
2.0-0-SNAPSHOT | = | 2.0-SNAPSHOT | | |
2.0-SNAPSHOT | < | 2.0-1-SNAPSHOT | | |
2.0.0-SNAPSHOT | < | 2.0-1-SNAPSHOT | | |
2.0-1-SNAPSHOT | < | 2.0.1-SNAPSHOT | | |
2.0.1-klm-SNAPSHOT | < | 2.0.1-lmn-SNAPSHOT | | |
2.0.1-xyz-SNAPSHOT | < | 2.0.1-SNAPSHOT | | |
2.0.1-SNAPSHOT | < | 2.0.1-123-SNAPSHOT | | |
2.0.1-xyz-SNAPSHOT | < | 2.0.1-123-SNAPSHOT | | |
Proposal
I'm proposing the following implementation: GenericArtifactVersion.java (unit test: GenericArtifactVersionTest.java)
...
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.