Add vercmp function
The existing vercmp_numbers function only handles, as the name says, numbers. I noticed that "sort" has had a version sort for a long time [1] and, rather than re-implement it badly, use this as a version of vercmp that works a bit more naturally. This is intended to be used in an "if" statement as in prog_ver=$(prog_ver --version | grep ...) if vercmp $prog_ver "<" 2.0; then ... fi A test-case is added to test the basic features and some edge-cases. [1] http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=4c9fae4e97d95a9f89d1399a8aeb03051f0fec96 Change-Id: Ie55283acdc40a095b80b2631a55310072883ad0d
This commit is contained in:
parent
bcad037697
commit
2ba36cda79
46
functions
46
functions
@ -527,12 +527,58 @@ function vercmp_numbers {
|
||||
typeset v1=$1 v2=$2 sep
|
||||
typeset -a ver1 ver2
|
||||
|
||||
deprecated "vercmp_numbers is deprecated for more generic vercmp"
|
||||
|
||||
IFS=. read -ra ver1 <<< "$v1"
|
||||
IFS=. read -ra ver2 <<< "$v2"
|
||||
|
||||
_vercmp_r "${#ver1[@]}" "${ver1[@]}" "${ver2[@]}"
|
||||
}
|
||||
|
||||
# vercmp ver1 op ver2
|
||||
# Compare VER1 to VER2
|
||||
# - op is one of < <= == >= >
|
||||
# - returns true if satisified
|
||||
# e.g.
|
||||
# if vercmp 1.0 "<" 2.0; then
|
||||
# ...
|
||||
# fi
|
||||
function vercmp {
|
||||
local v1=$1
|
||||
local op=$2
|
||||
local v2=$3
|
||||
local result
|
||||
|
||||
# sort the two numbers with sort's "-V" argument. Based on if v2
|
||||
# swapped places with v1, we can determine ordering.
|
||||
result=$(echo -e "$v1\n$v2" | sort -V | head -1)
|
||||
|
||||
case $op in
|
||||
"==")
|
||||
[ "$v1" = "$v2" ]
|
||||
return
|
||||
;;
|
||||
">")
|
||||
[ "$v1" != "$v2" ] && [ "$result" = "$v2" ]
|
||||
return
|
||||
;;
|
||||
"<")
|
||||
[ "$v1" != "$v2" ] && [ "$result" = "$v1" ]
|
||||
return
|
||||
;;
|
||||
">=")
|
||||
[ "$result" = "$v2" ]
|
||||
return
|
||||
;;
|
||||
"<=")
|
||||
[ "$result" = "$v1" ]
|
||||
return
|
||||
;;
|
||||
*)
|
||||
die $LINENO "unrecognised op: $op"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# This function sets log formatting options for colorizing log
|
||||
# output to stdout. It is meant to be called by lib modules.
|
||||
|
47
tests/test_vercmp.sh
Executable file
47
tests/test_vercmp.sh
Executable file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Tests for DevStack vercmp functionality
|
||||
|
||||
TOP=$(cd $(dirname "$0")/.. && pwd)
|
||||
|
||||
# Import common functions
|
||||
source $TOP/functions
|
||||
source $TOP/tests/unittest.sh
|
||||
|
||||
assert_true "numeric gt" vercmp 2.0 ">" 1.0
|
||||
assert_true "numeric gte" vercmp 2.0 ">=" 1.0
|
||||
assert_true "numeric gt" vercmp 1.0.1 ">" 1.0
|
||||
assert_true "numeric gte" vercmp 1.0.1 ">=" 1.0
|
||||
assert_true "alpha gt" vercmp 1.0.1b ">" 1.0.1a
|
||||
assert_true "alpha gte" vercmp 1.0.1b ">=" 1.0.1a
|
||||
assert_true "alpha gt" vercmp b ">" a
|
||||
assert_true "alpha gte" vercmp b ">=" a
|
||||
assert_true "alpha gt" vercmp 2.0-rc3 ">" 2.0-rc1
|
||||
assert_true "alpha gte" vercmp 2.0-rc3 ">=" 2.0-rc1
|
||||
|
||||
assert_false "numeric gt fail" vercmp 1.0 ">" 1.0
|
||||
assert_true "numeric gte" vercmp 1.0 ">=" 1.0
|
||||
assert_false "numeric gt fail" vercmp 0.9 ">" 1.0
|
||||
assert_false "numeric gte fail" vercmp 0.9 ">=" 1.0
|
||||
assert_false "numeric gt fail" vercmp 0.9.9 ">" 1.0
|
||||
assert_false "numeric gte fail" vercmp 0.9.9 ">=" 1.0
|
||||
assert_false "numeric gt fail" vercmp 0.9a.9 ">" 1.0.1
|
||||
assert_false "numeric gte fail" vercmp 0.9a.9 ">=" 1.0.1
|
||||
|
||||
assert_false "numeric lt" vercmp 1.0 "<" 1.0
|
||||
assert_true "numeric lte" vercmp 1.0 "<=" 1.0
|
||||
assert_true "numeric lt" vercmp 1.0 "<" 1.0.1
|
||||
assert_true "numeric lte" vercmp 1.0 "<=" 1.0.1
|
||||
assert_true "alpha lt" vercmp 1.0.1a "<" 1.0.1b
|
||||
assert_true "alpha lte" vercmp 1.0.1a "<=" 1.0.1b
|
||||
assert_true "alpha lt" vercmp a "<" b
|
||||
assert_true "alpha lte" vercmp a "<=" b
|
||||
assert_true "alpha lt" vercmp 2.0-rc1 "<" 2.0-rc3
|
||||
assert_true "alpha lte" vercmp 2.0-rc1 "<=" 2.0-rc3
|
||||
|
||||
assert_true "eq" vercmp 1.0 "==" 1.0
|
||||
assert_true "eq" vercmp 1.0.1 "==" 1.0.1
|
||||
assert_false "eq fail" vercmp 1.0.1 "==" 1.0.2
|
||||
assert_false "eq fail" vercmp 2.0-rc1 "==" 2.0-rc2
|
||||
|
||||
report_results
|
@ -92,6 +92,51 @@ function assert_empty {
|
||||
fi
|
||||
}
|
||||
|
||||
# assert the arguments evaluate to true
|
||||
# assert_true "message" arg1 arg2
|
||||
function assert_true {
|
||||
local lineno
|
||||
lineno=`caller 0 | awk '{print $1}'`
|
||||
local function
|
||||
function=`caller 0 | awk '{print $2}'`
|
||||
local msg=$1
|
||||
shift
|
||||
|
||||
$@
|
||||
if [ $? -eq 0 ]; then
|
||||
PASS=$((PASS+1))
|
||||
echo "PASS: $function:L$lineno - $msg"
|
||||
else
|
||||
FAILED_FUNCS+="$function:L$lineno\n"
|
||||
echo "ERROR: test failed in $function:L$lineno!"
|
||||
echo " $msg"
|
||||
ERROR=$((ERROR+1))
|
||||
fi
|
||||
}
|
||||
|
||||
# assert the arguments evaluate to false
|
||||
# assert_false "message" arg1 arg2
|
||||
function assert_false {
|
||||
local lineno
|
||||
lineno=`caller 0 | awk '{print $1}'`
|
||||
local function
|
||||
function=`caller 0 | awk '{print $2}'`
|
||||
local msg=$1
|
||||
shift
|
||||
|
||||
$@
|
||||
if [ $? -eq 0 ]; then
|
||||
FAILED_FUNCS+="$function:L$lineno\n"
|
||||
echo "ERROR: test failed in $function:L$lineno!"
|
||||
echo " $msg"
|
||||
ERROR=$((ERROR+1))
|
||||
else
|
||||
PASS=$((PASS+1))
|
||||
echo "PASS: $function:L$lineno - $msg"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Print a summary of passing and failing tests and exit
|
||||
# (with an error if we have failed tests)
|
||||
# usage: report_results
|
||||
|
Loading…
Reference in New Issue
Block a user