68 lines
2.4 KiB
Bash
Executable File
68 lines
2.4 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
set -e
|
|
|
|
# accepts two semantic-ish versions and echoes a character representing the
|
|
# relationship between the two.
|
|
# "semantic-ish" means here "a superset of semantic versioning." all correctly
|
|
# constructed semantic versions should compare in accordance with version 2.0 of
|
|
# the semver.org spec. versions that do not conform to the spec may also
|
|
# compare correctly. the primary difference is that there is no limitation on
|
|
# the number of version fields.
|
|
comparever() { comparever_default $@; }
|
|
|
|
# a split definition allows other formats to use this function to define their
|
|
# own comparever functions if they wish.
|
|
comparever_default() {
|
|
v1="$1"
|
|
v2="$2"
|
|
|
|
# strip any trailing meta tags
|
|
v1="${v1%+*}"
|
|
v2="${v2%+*}"
|
|
|
|
# equal?
|
|
[ "$v1" != "$v2" ] || { echo "=" && return 0; }
|
|
|
|
# strip leading characters that match.
|
|
while [ "$(echo "$v1" | cut -c1)" = "$(echo "$v2" | cut -c1)" ]; do
|
|
v1="$(echo "$v1" | cut -c2-)"
|
|
v2="$(echo "$v2" | cut -c2-)"
|
|
done
|
|
v1head="$(echo "$v1" | cut -c1)"
|
|
v2head="$(echo "$v2" | cut -c1)"
|
|
|
|
# if the difference is a prerelease tag, the prerelease is lesser.
|
|
case "$v1head" in -) echo '<' && return 0;; esac
|
|
case "$v2head" in -) echo '>' && return 0;; esac
|
|
|
|
# otherwise, if one is a prefix of the other, the other is greater.
|
|
[ -n "$v1" ] || { echo '<' && return 0; }
|
|
[ -n "$v2" ] || { echo '>' && return 0; }
|
|
|
|
# otherwise, if one starts with a dot, the other is the greater.
|
|
case "$v1head" in .) echo '<' && return 0;; esac
|
|
case "$v2head" in .) echo '>' && return 0;; esac
|
|
|
|
# strip any remaining version fields
|
|
v1="$(echo "$v1" | sed s/\\..*\$//)"
|
|
v2="$(echo "$v2" | sed s/\\..*\$//)"
|
|
|
|
# if the version tails are numeric, compare numerically. (ignore prerelease
|
|
# tags.) otherwise, compare lexically.
|
|
if (echo "${v1%-*}${v2%-*}" | grep -q "^[0-9]\+\$"); then
|
|
[ "$(echo "${v1%-*}")" -gt "$(echo "${v2%-*}")" ] \
|
|
&& echo ">" \
|
|
|| echo "<"
|
|
|
|
else
|
|
# v1 and v2 contain only the differences. using 'cut' and tabs here to
|
|
# perform a lexical sort on the differences and retrieve the original
|
|
# string associated with the greater of the two remainders.
|
|
greater=$(printf "%s\t%s\n%s\t%s" "$v1" "$1" "$v2" "$2" \
|
|
| sort | tail -n1 | cut -f2)
|
|
|
|
[ "$greater" = "$1" ] && echo ">" || echo "<"
|
|
fi
|
|
}
|