diff --git a/semver.sh b/semver.sh index e5237a4..a8e5ba6 100755 --- a/semver.sh +++ b/semver.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh function semverParseInto() { - local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)' + local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)[-]\{0,1\}\([0-9A-Za-z-]*\)' #MAJOR eval $2=`echo $1 | sed -e "s#$RE#\1#"` #MINOR @@ -12,7 +12,15 @@ function semverParseInto() { eval $5=`echo $1 | sed -e "s#$RE#\4#"` } -function semverEQ() { +function semverConstruct() { + if [[ $# -eq 5 ]]; then + eval $5=`echo "$1.$2.$3-$4"` + fi + + eval $4=`echo "$1.$2.$3"` +} + +function semverCmp() { local MAJOR_A=0 local MINOR_A=0 local PATCH_A=0 @@ -26,105 +34,212 @@ function semverEQ() { semverParseInto $1 MAJOR_A MINOR_A PATCH_A SPECIAL_A semverParseInto $2 MAJOR_B MINOR_B PATCH_B SPECIAL_B - if [ $MAJOR_A -ne $MAJOR_B ]; then - return 1 + # major + if [ $MAJOR_A -lt $MAJOR_B ]; then + return -1 fi - if [ $MINOR_A -ne $MINOR_B ]; then + if [ $MAJOR_A -gt $MAJOR_B ]; then return 1 fi - if [ $PATCH_A -ne $PATCH_B ]; then + # minor + if [ $MINOR_A -lt $MINOR_B ]; then + return -1 + fi + + if [ $MINOR_A -gt $MINOR_B ]; then return 1 fi - if [[ "_$SPECIAL_A" != "_$SPECIAL_B" ]]; then + # patch + if [ $PATCH_A -lt $PATCH_B ]; then + return -1 + fi + + if [ $PATCH_A -gt $PATCH_B ]; then return 1 fi + # special + if [[ ( "$SPECIAL_A" != "" ) && ( "$SPECIAL_B" == "" ) ]]; then + return -1 + fi - return 0 + if [[ ( "$SPECIAL_A" == "" ) && ( "$SPECIAL_B" != "" ) ]]; then + return 1 + fi -} + if [[ "$SPECIAL_A" < "$SPECIAL_B" ]]; then + return -1 + fi -function semverLT() { - local MAJOR_A=0 - local MINOR_A=0 - local PATCH_A=0 - local SPECIAL_A=0 + if [[ "$SPECIAL_A" > "$SPECIAL_B" ]]; then + return 1 + fi - local MAJOR_B=0 - local MINOR_B=0 - local PATCH_B=0 - local SPECIAL_B=0 + # equal + return 0 +} - semverParseInto $1 MAJOR_A MINOR_A PATCH_A SPECIAL_A - semverParseInto $2 MAJOR_B MINOR_B PATCH_B SPECIAL_B +function semverEQ() { + semverCmp $1 $2 + local RESULT=$? - if [ $MAJOR_A -lt $MAJOR_B ]; then - return 0 + if [ $RESULT -ne 0 ]; then + # not equal + return 1 fi - if [[ $MAJOR_A -le $MAJOR_B && $MINOR_A -lt $MINOR_B ]]; then - return 0 - fi - - if [[ $MAJOR_A -le $MAJOR_B && $MINOR_A -le $MINOR_B && $PATCH_A -lt $PATCH_B ]]; then - return 0 - fi + return 0 +} - if [[ "_$SPECIAL_A" == "_" ]] && [[ "_$SPECIAL_B" == "_" ]] ; then +function semverLT() { + semverCmp $1 $2 + local RESULT=$? + + # XXX: compare to 255, as returning -1 becomes return value 255 + if [ $RESULT -ne 255 ]; then + # not lesser than return 1 fi - if [[ "_$SPECIAL_A" == "_" ]] && [[ "_$SPECIAL_B" != "_" ]] ; then + + return 0 +} + +function semverGT() { + semverCmp $1 $2 + local RESULT=$? + + if [ $RESULT -ne 1 ]; then + # not greater than return 1 fi - if [[ "_$SPECIAL_A" != "_" ]] && [[ "_$SPECIAL_B" == "_" ]] ; then - return 0 - fi - if [[ "_$SPECIAL_A" < "_$SPECIAL_B" ]]; then - return 0 - fi + return 0 +} - return 1 +function semverBumpMajor() { + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local SPECIAL="" + semverParseInto $1 MAJOR MINOR PATCH SPECIAL + MAJOR=$(($MAJOR + 1)) + MINOR=0 + PATCH=0 + SPECIAL="" + + semverConstruct $MAJOR $MINOR $PATCH $SPECIAL $2 } -function semverGT() { - semverEQ $1 $2 - local EQ=$? +function semverBumpMinor() { + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local SPECIAL="" - semverLT $1 $2 - local LT=$? + semverParseInto $1 MAJOR MINOR PATCH SPECIAL + MINOR=$(($MINOR + 1)) + PATCH=0 + SPECIAL="" - if [ $EQ -ne 0 ] && [ $LT -ne 0 ]; then - return 0 - else - return 1 - fi + semverConstruct $MAJOR $MINOR $PATCH $SPECIAL $2 +} + +function semverBumpPatch() { + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local SPECIAL="" + + semverParseInto $1 MAJOR MINOR PATCH SPECIAL + PATCH=$(($PATCH + 1)) + SPECIAL="" + + semverConstruct $MAJOR $MINOR $PATCH $SPECIAL $2 +} + +function semverStripSpecial() { + local MAJOR=0 + local MINOR=0 + local PATCH=0 + local SPECIAL="" + + semverParseInto $1 MAJOR MINOR PATCH SPECIAL + SPECIAL="" + + semverConstruct $MAJOR $MINOR $PATCH $SPECIAL $2 } if [ "___semver.sh" == "___`basename $0`" ]; then + if [ "$2" == "" ]; then + echo "$0 [version]" + echo "Commands: cmp, eq, lt, gt, bump_major, bump_minor, bump_patch, strip_special" + echo "" + echo "cmp: compares left version against right version, return 0 if equal, 255 (-1) if left is lower than right, 1 if left is higher than right" + echo "eq: compares left version against right version, returns 0 if both versions are equal" + echo "lt: compares left version against right version, returns 0 if left version is less than right version" + echo "gt: compares left version against right version, returns 0 if left version is greater than than right version" + echo "" + echo "bump_major: bumps major of version, setting minor and patch to 0, removing special" + echo "bump_minor: bumps minor of version, setting patch to 0, removing special" + echo "bump_patch: bumps patch of version, removing special" + echo "" + echo "strip_special: strips special from version" + exit 255 + fi -MAJOR=0 -MINOR=0 -PATCH=0 -SPECIAL="" + if [ "$2" == "cmp" ]; then + semverCmp $1 $3 + RESULT=$? + echo $RESULT + exit $RESULT + fi -semverParseInto $1 MAJOR MINOR PATCH SPECIAL -echo "$1 -> M: $MAJOR m:$MINOR p:$PATCH s:$SPECIAL" + if [ "$2" == "eq" ]; then + semverEQ $1 $3 + RESULT=$? + echo $RESULT + exit $RESULT + fi -semverParseInto $2 MAJOR MINOR PATCH SPECIAL -echo "$2 -> M: $MAJOR m:$MINOR p:$PATCH s:$SPECIAL" + if [ "$2" == "lt" ]; then + semverLT $1 $3 + RESULT=$? + echo $RESULT + exit $RESULT + fi -semverEQ $1 $2 -echo "$1 == $2 -> $?." + if [ "$2" == "gt" ]; then + semverGT $1 $3 + RESULT=$? + echo $RESULT + exit $RESULT + fi -semverLT $1 $2 -echo "$1 < $2 -> $?." + if [ "$2" == "bump_major" ]; then + semverBumpMajor $1 VERSION + echo ${VERSION} + exit 0 + fi -semverGT $1 $2 -echo "$1 > $2 -> $?." + if [ "$2" == "bump_minor" ]; then + semverBumpMinor $1 VERSION + echo ${VERSION} + exit 0 + fi + + if [ "$2" == "bump_patch" ]; then + semverBumpPatch $1 VERSION + echo ${VERSION} + exit 0 + fi + if [ "$2" == "strip_special" ]; then + semverStripSpecial $1 VERSION + echo ${VERSION} + exit 0 + fi fi diff --git a/semver_test.sh b/semver_test.sh index a0ff994..d004022 100755 --- a/semver_test.sh +++ b/semver_test.sh @@ -2,6 +2,20 @@ . ./semver.sh +function doTest() { + local TEST=$1 + local EXPECTED=$2 + local ACTUAL=$3 + + echo -n "$TEST: " + + if [[ "$EXPECTED" == "$ACTUAL" ]]; then + echo "passed" + else + echo "FAILED, expected '${EXPECTED}', actual: '${ACTUAL}'" + fi +} + semverTest() { local A=R1.3.2 local B=R2.3.2 @@ -10,142 +24,201 @@ local D=R1.3.3 local E=R1.3.2a local F=R1.3.2b local G=R1.2.3 +local H=1.2.3-a local MAJOR=0 local MINOR=0 local PATCH=0 local SPECIAL="" +local VERSION="" + +echo "Parsing" semverParseInto $A MAJOR MINOR PATCH SPECIAL -echo "$A -> M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL. Expect M:1 m:3 p:2 s:" +doTest "semverParseInto $A -> M m p s" "M:1 m:3 p:2 s:" "M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL" + +semverParseInto $B MAJOR MINOR PATCH SPECIAL +doTest "semverParseInto $B -> M m p s" "M:2 m:3 p:2 s:" "M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL" + semverParseInto $E MAJOR MINOR PATCH SPECIAL -echo "$E -> M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL. Expect M:1 m:3 p:2 s:a" +doTest "semverParseInto $E -> M m p s" "M:1 m:3 p:2 s:a" "M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL" + +semverParseInto $H MAJOR MINOR PATCH SPECIAL +doTest "semverParseInto $H -> M m p s" "M:1 m:2 p:3 s:a" "M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL" + -echo "Equality comparisions" +echo "Comparisons" +semverCmp $A $A +doTest "semverCmp $A $A" 0 $? + +semverCmp $A $B +doTest "semverCmp $A $B" 255 $? + +semverCmp $B $A +doTest "semverCmp $B $A" 1 $? + + +echo "Equality comparisons" semverEQ $A $A -echo "$A == $A -> $?. Expect 0." +doTest "semverEQ $A $A" 0 $? semverLT $A $A -echo "$A < $A -> $?. Expect 1." +doTest "semverLT $A $A" 1 $? semverGT $A $A -echo "$A > $A -> $?. Expect 1." +doTest "semverGT $A $A" 1 $? -echo "Major number comparisions" +echo "Major number comparisons" semverEQ $A $B -echo "$A == $B -> $?. Expect 1." +doTest "semverEQ $A $B" 1 $? semverLT $A $B -echo "$A < $B -> $?. Expect 0." +doTest "semverLT $A $B" 0 $? semverGT $A $B -echo "$A > $B -> $?. Expect 1." +doTest "semverGT $A $B" 1 $? semverEQ $B $A -echo "$B == $A -> $?. Expect 1." +doTest "semverEQ $B $A" 1 $? semverLT $B $A -echo "$B < $A -> $?. Expect 1." +doTest "semverLT $B $A" 1 $? semverGT $B $A -echo "$B > $A -> $?. Expect 0." +doTest "semverGT $B $A" 0 $? -echo "Minor number comparisions" +echo "Minor number comparisons" semverEQ $A $C -echo "$A == $C -> $?. Expect 1." +doTest "semverEQ $A $C" 1 $? semverLT $A $C -echo "$A < $C -> $?. Expect 0." +doTest "semverLT $A $C" 0 $? semverGT $A $C -echo "$A > $C -> $?. Expect 1." +doTest "semverGT $A $C" 1 $? semverEQ $C $A -echo "$C == $A -> $?. Expect 1." +doTest "semverEQ $C $A" 1 $? semverLT $C $A -echo "$C < $A -> $?. Expect 1." +doTest "semverLT $C $A" 1 $? semverGT $C $A -echo "$C > $A -> $?. Expect 0." +doTest "semverGT $C $A" 0 $? -echo "patch number comparisions" + +echo "Patch number comparisons" semverEQ $A $D -echo "$A == $D -> $?. Expect 1." +doTest "semverEQ $A $D" 1 $? semverLT $A $D -echo "$A < $D -> $?. Expect 0." +doTest "semverLT $A $D" 0 $? semverGT $A $D -echo "$A > $D -> $?. Expect 1." +doTest "semverGT $A $D" 1 $? semverEQ $D $A -echo "$D == $A -> $?. Expect 1." +doTest "semverEQ $D $A" 1 $? semverLT $D $A -echo "$D < $A -> $?. Expect 1." +doTest "semverLT $D $A" 1 $? semverGT $D $A -echo "$D > $A -> $?. Expect 0." +doTest "semverGT $D $A" 0 $? + -echo "special section vs no special comparisions" +echo "Special section vs no special comparisons" semverEQ $A $E -echo "$A == $E -> $?. Expect 1." +doTest "semverEQ $A $E" 1 $? semverLT $A $E -echo "$A < $E -> $?. Expect 1." +doTest "semverLT $A $E" 1 $? semverGT $A $E -echo "$A > $E -> $?. Expect 0." +doTest "semverGT $A $E" 0 $? semverEQ $E $A -echo "$E == $A -> $?. Expect 1." +doTest "semverEQ $E $A" 1 $? semverLT $E $A -echo "$E < $A -> $?. Expect 0." +doTest "semverLT $E $A" 0 $? semverGT $E $A -echo "$E > $A -> $?. Expect 1." +doTest "semverGT $E $A" 1 $? + -echo "special section vs special comparisions" +echo "Special section vs special comparisons" semverEQ $E $F -echo "$E == $F -> $?. Expect 1." +doTest "semverEQ $E $F" 1 $? semverLT $E $F -echo "$E < $F -> $?. Expect 0." +doTest "semverLT $E $F" 0 $? semverGT $E $F -echo "$E > $F -> $?. Expect 1." +doTest "semverLT $E $F" 1 $? semverEQ $F $E -echo "$F == $E -> $?. Expect 1." +doTest "semverEQ $F $E" 1 $? semverLT $F $E -echo "$F < $E -> $?. Expect 1." +doTest "semverLT $F $E" 1 $? semverGT $F $E -echo "$F > $E -> $?. Expect 0." +doTest "semverGT $F $E" 0 $? + echo "Minor and patch number comparisons" semverEQ $A $G -echo "$A == $G -> $?. Expect 1." +doTest "semverEQ $A $G" 1 $? semverLT $A $G -echo "$A < $G -> $?. Expect 1." +doTest "semverLT $A $G" 1 $? semverGT $A $G -echo "$A > $G -> $?. Expect 0." +doTest "semverGT $A $G" 0 $? semverEQ $G $A -echo "$G == $A -> $?. Expect 1." +doTest "semverEQ $G $A" 1 $? semverLT $G $A -echo "$G < $A -> $?. Expect 0." +doTest "semverLT $G $A" 0 $? semverGT $G $A -echo "$G > $A -> $?. Expect 1." +doTest "semverGT $G $A" 1 $? + + +echo "Bumping major" +semverBumpMajor $A VERSION +doTest "semverBumpMajor $A" "2.0.0" $VERSION + +semverBumpMajor $E VERSION +doTest "semverBumpMajor $E" "2.0.0" $VERSION + + +echo "Bumping minor" +semverBumpMinor $A VERSION +doTest "semverBumpMinor $A" "1.4.0" $VERSION + +semverBumpMinor $E VERSION +doTest "semverBumpMinor $E" "1.4.0" $VERSION + + +echo "Bumping patch" +semverBumpPatch $A VERSION +doTest "semverBumpPatch $A" "1.3.3" $VERSION + +semverBumpPatch $E VERSION +doTest "semverBumpPatch $E" "1.3.3" $VERSION + + +echo "Strip special" +semverStripSpecial $A VERSION +doTest "semverStripSpecial $A" "1.3.2" $VERSION + +semverStripSpecial $E VERSION +doTest "semverStripSpecial $E" "1.3.2" $VERSION } semverTest