#!/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_" }