-
-
Save Ariel-Rodriguez/9e3c2163f4644d7a389759b224bfe7f3 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# THIS IS AN OBSOLETE SCRIPT WITH BUGS. FOR UPDATED VERSIONS PLEASE CHECK https://github.com/Ariel-Rodriguez/sh-semversion-2 | |
### | |
# semantic version comparition using semver specification http://semver.org/ | |
# This bash script compares pre-releases alphabetically as well | |
# | |
# returns 1 when A greater than B | |
# returns 0 when A equals B | |
# returns -1 when A lower than B | |
# | |
# Usage | |
# chmod +x semver.sh | |
# ./semver.sh 1.0.0 v1.0.0-rc.0 | |
# --> 1 | |
# | |
# Author Ariel Rodriguez | |
# License MIT | |
### | |
semver_compare() { | |
local version_a version_b pr_a pr_b | |
# strip word "v" and extract first subset version (x.y.z from x.y.z-foo.n) | |
version_a=$(echo "${1//v/}" | awk -F'-' '{print $1}') | |
version_b=$(echo "${2//v/}" | awk -F'-' '{print $1}') | |
if [ "$version_a" \= "$version_b" ] | |
then | |
# check for pre-release | |
# extract pre-release (-foo.n from x.y.z-foo.n) | |
pr_a=$(echo "$1" | awk -F'-' '{print $2}') | |
pr_b=$(echo "$2" | awk -F'-' '{print $2}') | |
#### | |
# Return 0 when A is equal to B | |
[ "$pr_a" \= "$pr_b" ] && echo 0 && return 0 | |
#### | |
# Return 1 | |
# Case when A is not pre-release | |
if [ -z "$pr_a" ] | |
then | |
echo 1 && return 0 | |
fi | |
#### | |
# Case when pre-release A exists and is greater than B's pre-release | |
# extract numbers -rc.x --> x | |
number_a=$(echo ${pr_a//[!0-9]/}) | |
number_b=$(echo ${pr_b//[!0-9]/}) | |
[ -z "${number_a}" ] && number_a=0 | |
[ -z "${number_b}" ] && number_b=0 | |
[ "$pr_a" \> "$pr_b" ] && [ -n "$pr_b" ] && [ "$number_a" -gt "$number_b" ] && echo 1 && return 0 | |
#### | |
# Retrun -1 when A is lower than B | |
echo -1 && return 0 | |
fi | |
arr_version_a=(${version_a//./ }) | |
arr_version_b=(${version_b//./ }) | |
cursor=0 | |
# Iterate arrays from left to right and find the first difference | |
while [ "$([ "${arr_version_a[$cursor]}" -eq "${arr_version_b[$cursor]}" ] && [ $cursor -lt ${#arr_version_a[@]} ] && echo true)" == true ] | |
do | |
cursor=$((cursor+1)) | |
done | |
[ "${arr_version_a[$cursor]}" -gt "${arr_version_b[$cursor]}" ] && echo 1 || echo -1 | |
} | |
[ -n "$1" ] && echo $(semver_compare $1 $2) |
#!/bin/bash | |
# OUTDATED GIST | |
# PLEASE CHECK https://github.com/Ariel-Rodriguez/sh-semversion-2 | |
# Include semver_compare tool | |
source ./semver.sh | |
versions=( | |
0.0.0 0.0.0 0 | |
0.0.1 0.0.0 1 | |
0.0.0 0.0.1 -1 | |
0.0.1-rc v0.0.1-rc 0 | |
0.0.1-rc.1 v0.0.1-rc 1 | |
0.0.1-rc.0 v0.0.1-rc.2 -1 | |
v0.0.1-rc.0 0.0.1-rc.0 0 | |
v0.0.1 v0.0.1-rc.2 1 | |
v0.0.1 v0.0.1 0 | |
v0.1.0-rc.0 0.1.0-rc.1 -1 | |
0.1.0-rc.1 v0.1.0-rc.1 0 | |
v0.1.0 v0.1.0-rc.1 1 | |
v0.1.0-rc.1 v0.1.0 -1 | |
v0.1.0-rc.9 v0.1.0-rc.10 -1 | |
v0.1.0-alpha v0.1.0-beta -1 | |
v0.1.0-alpha.1 v0.1.0-beta.0 -1 | |
) | |
_assert_is() { | |
echo $1 $2 is expected to be $4 $(if [ $3 == $4 ]; then echo "OK"; else echo FAIL got $3; fi) | |
} | |
for (( i=0; i<=$(( ${#versions[@]} -3 )); i+=3 )) | |
do | |
echo compare $(_assert_is ${versions[i]} ${versions[ i + 1]} $(semver_compare ${versions[i]} ${versions[ i + 1]}) ${versions[i+2]}) | |
done | |
# compare 0.0.1-rc.0 v0.0.1-rc.2 is expected to be -1 OK | |
# compare v0.0.1-rc.0 0.0.1-rc.0 is expected to be 0 OK | |
# compare v0.0.1 v0.0.1-rc.2 is expected to be 1 OK | |
# compare v0.0.1 v0.0.1 is expected to be 0 OK | |
# compare v0.1.0-rc.0 0.1.0-rc.1 is expected to be -1 OK | |
# compare 0.1.0-rc.1 v0.1.0-rc.1 is expected to be 0 OK | |
# compare v0.1.0 v0.1.0-rc.1 is expected to be 1 OK | |
# compare v0.1.0-rc.1 v0.1.0 is expected to be -1 OK |
What about versions like 1.0.5-rc.9 1.0.5-rc.10? For me it
./semver.sh 1.0.5-rc.9 1.0.5-rc.10
1
What about versions like 1.0.5-rc.9 1.0.5-rc.10? For me it
./semver.sh 1.0.5-rc.9 1.0.5-rc.10 1
So sorry for this late response, i have never notice you commented here. Exactly 1 year ago i was traveling and potentially missed it and never checked again this gist.
I have updated the script and also the tests!
Hope this helps for further people.
Great script. Thank you.
An alternative (in dpkg world) would be: https://stackoverflow.com/a/46299983/2450431
dpkg --compare-versions "1.0.5-rc.9" "eq" "1.0.5-rc.10"
And using return code (bash: $?
) to check result. Other conditions work also: lt
, gt
.
Thanks for suggesting. Yes that's an awesome tool. However I intended to find a solution to get rid of dependencies and make it work on OSX natively.
There's an error in line 54, which I think should be this:
[ "$pr_a" \> "$pr_b" ] && [ -n "$pr_b" ] && echo 1 && return 0
instead of what's currently there:
[ "$pr_a" \> "$pr_b" ] && [ -n "$pr_b" ] && [ "$number_a" -gt "$number_b" ] && echo 1 && return 0
The current version will give a -1 when comparing v1.16.0-rc1 to v1.16.0-alpha4 because it ends up looking at the number in the prerelease instead of the pre section itself.
@rfay true that there is a bug when comparing between different prerelease word name. Thanks for reporting it!
Please, be aware your solution breaks other test.
I will take a look on this by this week if possible.
This is an important-enough script to move into its own repository, where it can have issues and PRs and testing!
Great script. Thank you. Would love to see this in a git repo so contributions could be made. Of note, it seems the script does not work with build numbers, as outlined in the semver 2.0 spec. https://semver.org/spec/v2.0.0.html#spec-item-10
Know build numbers can not be compared - but maybe the script should just strip them off?
Wow i didn't expect this script were going to be useful.
I will refactor all this and create a repository. I will focus on next:
- Create this script 100% POSIX sh compatible. (current one uses AWK and newer Bash, not good 0 portability)
- I will make it semver 2.0 compatible free of bugs
I will try to make it for today. Thanks for the suggestions and support!
hey @michaelajr @rfay @hrvoj3e @amatsumara
I created repository and script reworked from scratch with better portability and more coverage.
Take a look https://github.com/Ariel-Rodriguez/sh-semversion-2
Thanks.
Thanks!
How to
Download tool
Add execution permissions
chmod +x semver.sh
Usage
semver.sh 1.0.0 1.0.0-rc.1
--> 1
Test