A normal version number MUST take the form X.Y.Z where X, Y, and Z are integers. X is the major version, Y is the minor version, and Z is the patch version. Each element MUST increase numerically. For instance: 1.9.0 < 1.10.0 < 1.11.0.
Not all packaging systems are capable of dealing with multipart as actual multiple parts. Lets give a more complete example to break it down. For instance:
1.9.0 < 1.10.0 < 1.11.0 < 2.0.0. That's what's supposed to happen... but that's not how it works. Arch for example see's versions as strings... so let me show you what happens.190
1100
1110
200
This is essentially what you could interpret the "."'s are essentially ignored ( Ok it's not actually how it works... juster's comment is more accurate than me but I think it's a good rule of thumb). They don't matter they're like spaces between words, they simply make it easier for a human to read. Never ever, ever, EVER! change the length of your versions to anything BUT larger. You will cause downstream annoyances, sure we've tools to work around it, but I don't want to and it shouldn't take any extra effort from upstream to make sure this doesn't happen.
In order to solve this if you ever need to move anything to double digits just don't go backwards. In other words:
1.9.0 < 1.10.0 < 1.11.0 < 2.00.0 would actually evaluate properly. I find it more likely that in an X.Y.Z schema that you will need X.Y.ZZ though, and maybe X.YY.ZZ. For a project More than 10 years old XX.YY.ZZ could happen. Anything more is probably ridiculous. If you find yourself hitting 99 slow your roll before you reach it by moving to a time based release, no more than once a month for example.Some people will say that Arch doesn't have a sane internal representation. Keep in mind that maintain over 300 package now for arch... of those 300 maybe 10 have ever caused me to create a workaround because of this issue. It's not difficult, so please just be considerate of downstream, it's a lot easier to acknowledge and be mindful of this than it is to fix downstream in a way that would work for all upstream packages (e.g. we've got more to consider that just your package).
UPDATE: Read juster's comment if you want more information on actual implementation and how I'm slightly wrong.
1.9.0 < 1.10.0 < 1.11.0 < 2.0.0 is actually true for Archlinux's version comparison. Archlinux's version comparison is mostly copied from rpm's code if I remember correctly. It is in libalpm's source code, which is included with pacman's.
ReplyDeleteThe periods (.'s) are not necessarily ignored. Each iteration, the next numeric portion up to the period (or whatever) is compared... for each version string. To make things easier, if one numeric portion (this is still a string) is longer it is considered larger and greater than the other numeric portion.
For example, with 1.9.0 compared to 1.10.0:
1 vs 1 : Is either one longer? No. Compare them. They are identical.
9 vs 10 : Is either one longer? Yes. 10 is greater than 9. Finished.
The problem comes when versions need to be compared numerically:
For example, 1.025 compared to 1.03:
1 vs 1 : Is either one longer? No. Compare them. They are identical.
025 vs 03 : Is either one longer? Yes. 025 is greater than 03. Finished.
Mathematically 1.025 is less than 1.03. Not so with Archlinux version comparison.
Here is some perl code I used to test the version comparison:
http://gist.github.com/437097
awesome technical explanation... I like my rule of thumb though... it's simpler. don't increase the length of the string, unless you plan to do so permanently.
ReplyDelete