Function to compare package versions added
This commit is contained in:
parent
bd46e4c9e8
commit
26c8605256
2 changed files with 79 additions and 2 deletions
|
|
@ -149,4 +149,71 @@ module DebImporter
|
||||||
end # Enumerator
|
end # Enumerator
|
||||||
end # def
|
end # def
|
||||||
|
|
||||||
|
# Determine which version string denotes the newer package
|
||||||
|
# v1: version of the first package
|
||||||
|
# v2: version of the second package
|
||||||
|
# op: the comparison operator (default: 'gt' / greater-than)
|
||||||
|
#
|
||||||
|
# The algorithm is described in the Debian Policy at
|
||||||
|
# https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version
|
||||||
|
# The reference implementation is "dpkg --compare-versions …"
|
||||||
|
def dpkg_compare_version(v1, v2, op: 'gt')
|
||||||
|
system("dpkg --compare-versions #{v1} #{op} #{v2}")
|
||||||
|
end
|
||||||
|
|
||||||
|
class Version
|
||||||
|
def initialize(version_string)
|
||||||
|
@version_string = version_string
|
||||||
|
# Split into "[epoch:]version[-revision]"
|
||||||
|
unless version_string =~ /^(?<epoch>(\d+)\:)?(?<version>.+)(?<revision>\-[\+\.~]+)?/
|
||||||
|
raise ArgumentError, "Cannot parse version string: #{version_string}"
|
||||||
|
end
|
||||||
|
@epoch = epoch if epoch
|
||||||
|
@version = version
|
||||||
|
@revision = revision if revision
|
||||||
|
end # /def
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
@version
|
||||||
|
end
|
||||||
|
|
||||||
|
def >(a,b)
|
||||||
|
return true if a.epoch > b.epoch
|
||||||
|
return true if version_compare(a.version, b.version)
|
||||||
|
return true if version_compare(a.revision, b.revision)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def version_compare(x,y)
|
||||||
|
# Compare a version string (like the upstream_version or
|
||||||
|
# debian_revision string) against another version string.
|
||||||
|
# The algorithm works like this:
|
||||||
|
#
|
||||||
|
# The strings are compared from left to right.
|
||||||
|
# First the initial part of each string consisting entirely of non-digit
|
||||||
|
# characters is determined. These two parts (one of which may be empty)
|
||||||
|
# are compared lexically. If a difference is found it is returned.
|
||||||
|
# The lexical comparison is a comparison of ASCII values modified so
|
||||||
|
# that all the letters sort earlier than all the non-letters and so that
|
||||||
|
# a tilde sorts before anything, even the end of a part.
|
||||||
|
# For example, the following parts are in sorted order from
|
||||||
|
# earliest to latest: ~~, ~~a, ~, the empty part, a.[37]
|
||||||
|
#
|
||||||
|
# Then the initial part of the remainder of each string which
|
||||||
|
# consists entirely of digit characters is determined. The
|
||||||
|
# numerical values of these two parts are compared, and any
|
||||||
|
# difference found is returned as the result of the comparison.
|
||||||
|
# For these purposes an empty string (which can only occur at
|
||||||
|
# the end of one or both version strings being compared) counts as zero.
|
||||||
|
#
|
||||||
|
# These two steps (comparing and removing initial non-digit strings
|
||||||
|
# and initial digit strings) are repeated until a difference is
|
||||||
|
# found or both strings are exhausted.
|
||||||
|
|
||||||
|
(x.chars).zip(y.chars) do |xchar,ychar|
|
||||||
|
puts xchar, ychar
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end # /class
|
||||||
end # module
|
end # module
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,20 @@ include DebImporter
|
||||||
|
|
||||||
class PackagesHelperTest < ActionView::TestCase
|
class PackagesHelperTest < ActionView::TestCase
|
||||||
|
|
||||||
|
test "should detect the proper order of package versions" do
|
||||||
|
assert(DebImporter::Version.new('2') > DebImporter::Version.new('1'))
|
||||||
|
assert(DebImporter::Version.new('1.0') > DebImporter::Version.new('0.9'))
|
||||||
|
assert(DebImporter::Version.new('2:1') > DebImporter::Version.new('1:2'))
|
||||||
|
assert(DebImporter::Version.new('1.0c') > DebImporter::Version.new('1.0aa'))
|
||||||
|
assert(DebImporter::Version.new('1.0.1') > DebImporter::Version.new('1.0.0.1'))
|
||||||
|
assert(DebImporter::Version.new('1.0c') > DebImporter::Version.new('1.0.0'))
|
||||||
|
assert(DebImporter::Version.new('1.0') > DebImporter::Version.new('1.0~pre'))
|
||||||
|
end
|
||||||
|
|
||||||
test "should be able to parse local Debian repository test files" do
|
test "should be able to parse local Debian repository test files" do
|
||||||
Rails.logger = Logger.new(STDOUT)
|
Rails.logger = Logger.new(STDOUT)
|
||||||
Rails.logger.level = Logger::ERROR
|
# Rails.logger.level = Logger::ERROR
|
||||||
# Rails.logger.level = Logger::INFO
|
Rails.logger.level = Logger::INFO
|
||||||
# Rails.logger.level = Logger::DEBUG
|
# Rails.logger.level = Logger::DEBUG
|
||||||
|
|
||||||
# Load information about test repository from environments/test.rb
|
# Load information about test repository from environments/test.rb
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue