151 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
#github.com/fsaintjacques/semver-tool
NAT='0|[1-9][0-9]*'
ALPHANUM='[0-9]*[A-Za-z-][0-9A-Za-z-]*'
IDENT="$NAT|$ALPHANUM"
FIELD='[0-9A-Za-z-]+'
SEMVER_REGEX="\
^[vV]?\
($NAT)\\.($NAT)\\.($NAT)\
(\\-(${IDENT})(\\.(${IDENT}))*)?\
(\\+${FIELD}(\\.${FIELD})*)?$"
function validate_version {
local version=$1
if [[ "$version" =~ $SEMVER_REGEX ]]; then
if [ "$#" -eq "2" ]; then
local major=${BASH_REMATCH[1]}
local minor=${BASH_REMATCH[2]}
local patch=${BASH_REMATCH[3]}
local prere=${BASH_REMATCH[4]}
local build=${BASH_REMATCH[8]}
eval "$2=(\"$major\" \"$minor\" \"$patch\" \"$prere\" \"$build\")"
else
echo "$version"
fi
fi
}
function is_nat {
[[ "$1" =~ ^($NAT)$ ]]
}
function is_null {
[ -z "$1" ]
}
function order_nat {
[ "$1" -lt "$2" ] && {
echo -1
return
}
[ "$1" -gt "$2" ] && {
echo 1
return
}
echo 0
}
function order_string {
[[ $1 < $2 ]] && {
echo -1
return
}
[[ $1 > $2 ]] && {
echo 1
return
}
echo 0
}
function compare_fields {
local l="$1[@]"
local r="$2[@]"
local leftfield=("${!l}")
local rightfield=("${!r}")
local left
local right
local i=$((-1))
local order=$((0))
while true; do
[ $order -ne 0 ] && {
echo $order
return
}
: $((i++))
left="${leftfield[$i]}"
right="${rightfield[$i]}"
is_null "$left" && is_null "$right" && {
echo 0
return
}
is_null "$left" && {
echo -1
return
}
is_null "$right" && {
echo 1
return
}
is_nat "$left" && is_nat "$right" && {
order=$(order_nat "$left" "$right")
continue
}
is_nat "$left" && {
echo -1
return
}
is_nat "$right" && {
echo 1
return
}
{
order=$(order_string "$left" "$right")
continue
}
done
}
# shellcheck disable=SC2206
function compare_version {
local order
validate_version "$1" V
validate_version "$2" V_
local left=("${V[0]}" "${V[1]}" "${V[2]}")
local right=("${V_[0]}" "${V_[1]}" "${V_[2]}")
order=$(compare_fields left right)
[ "$order" -ne 0 ] && {
echo "$order"
return
}
local prerel="${V[3]:1}"
local prerel_="${V_[3]:1}"
local left=(${prerel//./ })
local right=(${prerel_//./ })
[ -z "$prerel" ] && [ -z "$prerel_" ] && {
echo 0
return
}
[ -z "$prerel" ] && {
echo 1
return
}
[ -z "$prerel_" ] && {
echo -1
return
}
compare_fields left right
}
function command_compare {
local v
local v_
v=$(validate_version "$1")
v_=$(validate_version "$2")
set +u
compare_version "$v" "$v_"
}