version: adjust to a pure semver version number, per bradfitz's proposal.

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson
2020-08-03 17:53:08 +00:00
committed by Dave Anderson
parent 6298018704
commit c3467fbadb
2 changed files with 134 additions and 98 deletions
+101 -83
View File
@@ -5,89 +5,107 @@ set -eu
mode=$1
describe=$2
long() {
ver="${describe#v}"
stem="${ver%%-*}"
case "$stem" in
*.*.*)
# Full SemVer, nothing to do.
semver="${stem}"
# Git describe output overall looks like
# MAJOR.MINOR.PATCH-NUMCOMMITS-GITHASH. Depending on the tag being
# described and the state of the repo, ver can be missing PATCH,
# NUMCOMMITS, or both.
#
# Valid values look like: 1.2.3-1234-abcdef, 0.98-1234-abcdef,
# 1.0.0-abcdef, 0.99-abcdef.
ver="${describe#v}"
stem="${ver%%-*}" # Just the semver-ish bit e.g. 1.2.3, 0.98
suffix="${ver#$stem}" # The rest e.g. -23-abcdef, -abcdef
# Normalize the stem into a full major.minor.patch semver. We might
# not use all those pieces depending on what kind of version we're
# making, but it's good to have them all on hand.
case "$stem" in
*.*.*)
# Full SemVer, nothing to do
stem="$stem"
;;
*.*)
# Old style major.minor, add a .0
semver="${stem}.0"
;;
*)
echo "Unparseable version $stem" >&2
exit 1
;;
esac
suffix="${ver#$stem}"
case "$suffix" in
-*-*)
# Has a change count in addition to the commit hash.
*.*)
# Old style major.minor, add a .0
stem="${stem}.0"
;;
*)
echo "Unparseable version $stem" >&2
exit 1
;;
esac
major=$(echo "$stem" | cut -f1 -d.)
minor=$(echo "$stem" | cut -f2 -d.)
patch=$(echo "$stem" | cut -f3 -d.)
# Extract the change count and git ID from the suffix.
case "$suffix" in
-*-*)
# Has both a change count and a commit hash.
changecount=$(echo "$suffix" | cut -f2 -d-)
githash=$(echo "$suffix" | cut -f3 -d-)
;;
-*)
# Git hash only, change count is zero.
changecount="0"
githash=$(echo "$suffix" | cut -f2 -d-)
;;
*)
echo "Unparseable version suffix $suffix" >&2
exit 1
;;
esac
# Validate that the version data makes sense. Rules:
# - Odd number minors are unstable. Patch must be 0, and gets
# replaced by changecount.
# - Even number minors are stable. Changecount must be 0, and
# gets removed.
#
# After this section, we only use major/minor/patch, which have been
# tweaked as needed.
if expr "$minor" : "[0-9]*[13579]$" >/dev/null; then
# Unstable
if [ "$patch" != "0" ]; then
# This is a fatal error, because a non-zero patch number
# indicates that we created an unstable git tag in violation
# of our versioning policy, and we want to blow up loudly to
# get that fixed.
echo "Unstable release $describe has a non-zero patch number, which is not allowed" >&2
exit 1
fi
patch="$changecount"
else
# Stable
if [ "$changecount" != "0" ]; then
# This is a commit that's sitting between two stable
# releases. We never want to release such a commit to the
# pbulic, but it's useful to be able to build it for
# debugging. Just force the version to 0.0.0, so that we're
# forced to rely on the git commit hash.
major=0
minor=0
patch=0
fi
fi
case "$1" in
long)
echo "${major}.${minor}.${patch}-${githash}"
;;
short)
echo "${major}.${minor}.${patch}"
;;
xcode)
# CFBundleShortVersionString: the "short name" used in the App
# Store. eg. 0.92.98
echo "VERSION_NAME = ${major}.${minor}.${patch}"
# CFBundleVersion: the build number. Needs to be 3 numeric
# sections that increment for each release according to SemVer
# rules.
#
# We start counting at 100 because we submitted using raw
# build numbers before, and Apple doesn't let you start over.
# e.g. 0.98.3 -> 100.98.3
echo "VERSION_ID = $((major + 100)).${minor}.${patch}"
;;
-*)
# Missing change count, add one.
suffix="-0${suffix}"
;;
*)
echo "Unexpected version suffix" >&2
exit 1
esac
echo "${semver}${suffix}"
}
short() {
ver="$(long)"
case "$ver" in
*-*-*)
echo "${ver%-*}"
;;
*-*)
echo "$ver"
;;
*)
echo "Long version in invalid format" >&2
exit 1
;;
esac
}
xcode() {
ver=$(short | sed -e 's/-/./')
major=$(echo "$ver" | cut -f1 -d.)
minor=$(echo "$ver" | cut -f2 -d.)
patch=$(echo "$ver" | cut -f3 -d.)
changecount=$(echo "$ver" | cut -f4 -d.)
# Apple version numbers must be major.minor.patch. We have 4 fields
# because we need major.minor.patch for go module compatibility, and
# changecount for automatic version numbering of unstable builds. To
# resolve this, for Apple builds, we combine changecount into patch:
patch=$((patch*10000 + changecount))
# CFBundleShortVersionString: the "short name" used in the App Store.
# eg. 0.92.98
echo "VERSION_NAME = $major.$minor.$patch"
# CFBundleVersion: the build number. Needs to be 3 numeric sections
# that increment for each release according to SemVer rules.
#
# We start counting at 100 because we submitted using raw build
# numbers before, and Apple doesn't let you start over.
# e.g. 0.98.3-123 -> 100.98.3123
major=$((major + 100))
echo "VERSION_ID = $major.$minor.$patch"
}
case "$mode" in
long)
long
;;
short)
short
;;
xcode)
xcode
;;
esac