Skip to content

Instantly share code, notes, and snippets.

@prasincs
Created February 6, 2018 18:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prasincs/91beffb28761ded91b04bc07f4a35672 to your computer and use it in GitHub Desktop.
Save prasincs/91beffb28761ded91b04bc07f4a35672 to your computer and use it in GitHub Desktop.
#!/usr/bin/sh
# git-distance-based SEMVER
#
# Optional Flag: -t to cause the script to actually tag the github repo
# Using -t will cause the original behavior of Jerry's version.
# Not using -t will not touch the github repo or tags. Just will set the VERSION output and VERSION file
#
# Optional Argument: path to VERSION file. Defaults to VERSION in the current director
# major and minor, once released, are designated by add RELEASE-vx.y tag and the patch will be derived based on distance to that tag
# if we don't find such a tag, v0.0 is assumed and we we'll use the distance to FIRST_COMMIT
#
# for master branch, it will tag it like "v0.1.5"
# for other branches, e.g. feature-xyz, it will tag it like "feature-xyz-v0.1.5
#
# The VERSION output will be just the SEMVER with no v prefix so that other
# processes can use just the version. But a v will be appended to the git tag
# that is created
#
# REQUIREMENTS:
# 1. Have the FIRST_COMMIT tag created on, well, the first commit.
# This gives us a reference point. (the reason we may not figure out by doing "git rev-list" is that in some situations,
# our repo is a shallowed git clone)
# 2. Repo being operated on needs to be writeable by the process running this script. Having mist-ci-bot associated with the repo will works
#
function parse_git_dirty {
[[ $(git status 2> /dev/null | tail -n1) != "nothing to commit, working tree clean" ]] && echo "*"
}
while getopts ":t" opt; do
case $opt in
t)
DO_GIT_TAG=1
shift $((OPTIND-1))
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done
if [ -z "$1" ]; then
VERSION_FILE=VERSION
else
VERSION_FILE=$1
fi
#if [ "`git rev-list HEAD | tail -n 1`" != "`git log FIRST_COMMIT --format=%H`" ] ; then git fetch --unshallow ; fi
git fetch --prune --tags
# looking for the nearest RELEASE-vx.y tag and extract vx.y
MAJORMINOR=$(git rev-list HEAD --pretty="format:%d" | grep -v commit | sed -n 's/.*RELEASE-v\([0-9]*\.[0-9]*\).*/\1/p' | head -n 1)
# use this RELEASE-vx.y to calculate the distance
if [ "$MAJORMINOR" = "" ] ; then
MAJORMINOR="0.0"
DISTANCE=$(git rev-list FIRST_COMMIT..HEAD --count)
else
DISTANCE=$(git rev-list RELEASE-v$MAJORMINOR..HEAD --count)
fi
# use SEMVER for master
# master: v0.1.5
# feature-xyz: feature-xyz-v0.1.5
BRANCH=`git rev-parse --abbrev-ref HEAD`
VERSION="${MAJORMINOR}.${DISTANCE}"
if [ "${BRANCH}" != "master" ] ; then
VERSION="${BRANCH}-${VERSION}"
fi
dirty=`parse_git_dirty`
if [ "${dirty}" = "*" ]; then
VERSION="${VERSION}-dirty"
fi
echo "VERSION: ${VERSION}"
## END of git-distance-based SEMVER¯
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment