Daniel Azuma |
||
Ruby Version Numbers Done Right?
Posted on Mon, Nov 30, 2009, at 11:53 PM
Tags:
ruby
Summary: Introducing versionomy, a new rubygem offering robust parsing, interpretation, manipulation, and comparison of version numbers. It features an adaptive parser with enough flexibility to handle a variety of syntaxes, including prerelease (e.g. alpha, beta) syntax, patchlevels, and nonstandard delimiters. Try it out and feel free to leave feedback. The Challenge of Version NumbersHow do you compare version numbers? Suppose you have some ruby code that requires Ruby 1.8.7 or later, and won’t work under 1.8.6. Well, I’ve seen a lot of code that does something like this:
Treating the version number as a string works well enough… that is, until it doesn’t. If RUBY_VERSION is “1.8.7”, everything’s okay. Same for “1.8.6”, “1.8.8”, and even “1.9.1”. But wait… what if the RUBY_VERSION was “1.8.10”? Then a simple string comparison would fail. Not that we expect that many point releases of Ruby 1.8, but the example should make us pause and think. Version numbers aren’t strings, and in the general case it isn’t sufficient to treat them as such. They need to be parsed. Here’s another example. A package management system such as rubygems needs to track what version of each package is installed so that it knows when to perform upgrades. For a long time, rubygems saw a version number as a period-delimited series of numbers, e.g. “1.2.3”. It provided a class that parsed a version string into a list of integers, so it didn’t fail on string comparisons. However, some gem authors wanted to be able to release “prerelease” versions of their gems, i.e. versions before the “.0” release. This wasn’t technically possible, and so some gem authors resorted to schemes such as “1.2.99” to denote a pre-“1.3” version, a system that had some obvious problems. More recently, rubygems added limited support for prerelease versions by allowing a “string” field in a version number that is always sorted before “0”. So, a pre-“1.3” beta release could be versioned “1.3.beta.1”. That was an improvement, but still nonoptimal: it forces the use of a syntax that we don’t normally expect for a version number. Furthermore, it doesn’t properly support “patchlevel” versions such as we find used for the Ruby virtual machine itself; versions like “1.9.1-p243” could get misinterpreted as a prerelease. The trouble with version numbers is that there are many different cases we want to express: major and minor versions, prereleases, patches, and so forth; and there are many different syntaxes used to express them. Working with version numbers is a challenge. Introducing VersionomyThe Versionomy library is my attempt to make sense of version numbers. It represents version numbers as ruby objects, and knows how to parse, interpret, compare, and manipulate all the syntax forms I discuss above, plus many, many more. It interprets prerelease versions and patchlevels, and knows how to handle them when doing manipulation and comparison. It also provides facilities for creating new parsers to recognize different syntax forms, or even different version number structures. In short, Versionomy is trying to solve the version number challenge once and for all. Here are some examples, straight from the README file:
You can install Versionomy from rubygems/gemcutter:
Documentation is available at http://virtuoso.rubyforge.org/versionomy/Versionomy_rdoc.html Source code is hosted on Github at http://github.com/dazuma/versionomy Report bugs on Github issues at http://github.org/dazuma/versionomy/issues Versionomy is released under a BSD-style license. How Are You Handling Version Numbers?I’m releasing Versionomy to the community as a request-for-comments. How do you think version numbers should be handled? Is this library on the right track, or is there a better strategy? Do you find it useful? What major syntaxes are missing support right now? Leave me a note.
3 Comments
James Tucker
at Wed, Dec 02, 2009, 04:12 AM
If you have rubygems already loaded:
Daniel Azuma
at Wed, Dec 02, 2009, 11:32 AM
Yeah,
Luis Lavena
at Wed, Dec 02, 2009, 04:18 PM
I agree with Daniel Version parsing and comparison is challenging. There are so many version schemas in the wild. Take for example OpenSSL: 0.9.8k, 0.9.8l Other packages uses different version schema. RubyGems is not smart enough to even deal with patchlevels (take for example 1.9.2dev which is patchelvel -1) I think for the purpose of RubyGems, version comparison is OK, but there is need for a specialized versioning parsing and processing library. Comments are disabled for this article. |
Recent
Tags
Random blogs
|
|