Sorting Versions is Hard

Posted by kev Fri, 16 Mar 2007 17:58:00 GMT

class Package < ActiveRecord::Base
  def <=>(other)
    versions = self.version.split(".").push self.rel
    other_versions = other.version.split(".").push other.rel

    versions.size.times do |n|
      if versions[n] =~ /[^\d]/ || other_versions[n] =~ /[^\d]/
        comparison = versions[n] <=> other_versions[n]
      else
        comparison = versions[n].to_i <=> other_versions[n].to_i
      end
      return comparison unless comparison.zero?
    end

    return 0 
  end
end

[Package.new(:version => "0.0.8a"), 
 Package.new(:version => "0.0.8c"), 
 Package.new(:version => "0.0.8b")].sort.map(&:version)
# => ["0.0.8a", "0.0.8b", "0.0.8c"] 

[Package.new(:version => "0.0.8"), 
 Package.new(:version => "0.0.10"), 
 Package.new(:version => "0.0.9")].sort.map(&:version)
# => ["0.0.8", "0.0.9", "0.0.10"] 

Posted in ,  | 3 comments

Comments

  1. Avatar brendan said 6 days later:

    And if you want to handle all the versioning schemes out there in use, it gets insane. Take for example just a few described here: http://peak.telecommunity.com/DevCenter/setuptools#specifying-your-project-s-version

  2. Avatar Scott said 9 days later:

    I wrote a Version library that might help you out: http://railsaddict.com/past/2007/3/26/sorting_versions_is_easy/, thanks for the inspiration!

  3. Avatar Kyle Maxwell said 15 days later:

    Facets to the rescue: http://facets.rubyforge.org/src/doc/rdoc/more/classes/VersionNumber.html

Comments are disabled