-
-
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.shUsage
semver.sh 1.0.0 1.0.0-rc.1--> 1
Test