Skip to content

Instantly share code, notes, and snippets.

@chriha
Created April 2, 2018 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chriha/577d65099ed295bfe13668cc1bdfde7e to your computer and use it in GitHub Desktop.
Save chriha/577d65099ed295bfe13668cc1bdfde7e to your computer and use it in GitHub Desktop.
Get next version tag of a Git repo considering a version constraint
#!/usr/bin/env bash
# # # # # # # # # # # # # # # # # # # #
# Compare two versions
# https://stackoverflow.com/a/4025065
#
# Arguments:
# VERSION_1
# VERSION_2
# Returns:
# 0 =
# 1 >
# 2 <
# # # # # # # # # # # # # # # # # # # #
compare_versions() {
[[ $1 == $2 ]] && return 0
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++)); do
if [[ -z ${ver2[i]} ]]; then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]})); then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]})); then
return 2
fi
done
return 0
}
#######################################
# Get the next latest tag
#
# Arguments:
# REPO_URL
# VERSION_CONSTRAINT
#######################################
next_tag() {
local CURRENT=$(echo "$2" | sed -E 's/(\*\.)?\*/0/g')
local REPO_URL=$(get_repo_url $1)
# allow last minor version to go up
# 1.3.1 >= 1.3.1 < 1.4.0
# 1.3 >= 1.3 < 2.0.0
local MAX_VERSION=$(echo "$CURRENT" \
| awk -F. '{ major=$1+1; minor="0"; patch=""; if ( $3 || $3 == 0 ) { major=$1; minor=$2+1; patch=".0"; } print major"."minor""patch; }')
local SORTED_TAGS=$(git ls-remote --tags $REPO_URL \
| grep -o "0\.\d*\.*\d*$" \
| sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g)
#echo "CURRENT: $CURRENT"
#echo "MAX_VERSION: $MAX_VERSION"
while read -r TAG; do
GIT_TAG=$TAG
compare_versions $CURRENT $TAG
OP=$?
# TAG is an older version
[[ $OP -eq 2 ]] || continue
compare_versions $TAG $MAX_VERSION
OP=$?
# stop search if TAG is greater than MAX_VERSION
[ $OP -eq 1 ] && break
NEXT_VERSION=$TAG
done <<< "$SORTED_TAGS"
echo ${NEXT_VERSION:-$GIT_TAG}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment