Files
org-hyperion-cules/_dynamic_version
2023-11-24 18:00:52 -05:00

260 lines
6.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# PROGRAMMING NOTE: apparently some git commands report
# inaccurate information if the current directory isn't
# root repository directory where the source files live.
orig_dir="$(pwd)"
top_srcdir="$1"
vers_part="$2"
cd "$top_srcdir"
INFILE=configure.ac
MIN_GIT_VERSION="1.8" # (earlier versions of git return inaccurate results)
#-----------------------------------------------------------
# vercomp -- compare versions
#-----------------------------------------------------------
#
# $1: first version to be compared (e.g. "1.2.3")
# $2: expected relationship (e.g. ">")
# $3: second version to be compared (e.g. "1.2")
#
# The algorithm takes into account leading zeros as well
# as missing components (4.08 < 4.08.01, 3.2.0.9 > 3.2),
# but only exact equality is supported for text strings
# which have non-numeric components (1.2rc3 = 1.2rc3).
#
# Returns: 0 = success if relationship is true
# Returns: 1 = failure if relationship is false
#
# We use 0 for true and 1 for false so that the caller
# can do such things as:
#
# if vercomp 1.2.3 '>' 1.2.0; then
# echo "True!"
# else
# echo "FALSE!"
# fi
#
#-----------------------------------------------------------
vercomp()
{
local op
_vercomp $1 $3
case $? in
0) op='=';;
1) op='>';;
2) op='<';;
esac
if [[ $op != $2 ]]; then
return 1
else
return 0
fi
}
#-----------------------------------------------------------
# (vercomp helper function)
#-----------------------------------------------------------
_vercomp()
{
# rc = 0: $1 = $2 $1 equals $2
# rc = 1: $1 > $2 $1 greater than $2
# rc = 2: $1 < $2 $1 less than $2
if [[ $1 == $2 ]]; then
return 0
fi
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
}
#------------------------------------------------------------------------------
# M A I N
#------------------------------------------------------------------------------
# Extract the VERS_MAJ, VERS_INT and VERS_MIN values from $INFILE
VERS_MAJ=$(grep -o -a -m 1 '^VERS_MAJ=[0-9][0-9]*' $INFILE)
VERS_INT=$(grep -o -a -m 1 '^VERS_INT=[0-9][0-9]*' $INFILE)
VERS_MIN=$(grep -o -a -m 1 '^VERS_MIN=[0-9][0-9]*' $INFILE)
VERS_DEV=$(grep -o -a -m 1 '^VERS_DEV=[0-9][0-9]*' $INFILE)
# Result of above is "VERS_xxx=n". The below does the assignment.
eval $VERS_MAJ
eval $VERS_INT
eval $VERS_MIN
eval $VERS_DEV
# PROGRAMMING NOTE: must check for the existence of both the .git
# directory as well as the git command itself since either may exist
# or not exist independent of the other. Only when both are true
# can we then safely query/use the git repository values.
if ! test -d "./.git" ||
! type "git" >/dev/null 2>/dev/null; then
# Can't query the git repository since the .git directory doesn't
# exist (i.e. this directory isn't a git repository clone) or else
# the git command doesn't exist (i.e. git itself isn't installed)
VERS_BLD="0"
git_hash=""
modified_str=""
else
# The current directory appears to be a git repository clone AND the
# git command exists (i.e. git *IS* installed), so we can safely ask
# git for some repository values that we can then use in our VERSION.
# Determine if any local modifications exist. PLEASE NOTE that doing
# "update-index --refresh" beforehand is seemingly critical to ensure
# accurate "diff-index" results with some versions of git.
git update-index --refresh -q > /dev/null 2>&1
git diff-index --quiet HEAD
if test "$?" == "0"; then
modified_str=""
else
# Check for possibly inaccurate results
gitvers=$(git --version | egrep -o "([0-9]{1,}\.)+[0-9]{1,}" | head -n 1)
if vercomp $gitvers '>' $MIN_GIT_VERSION; then
modified_str="-modified"
else
modified_str="-modified(?)" # (indicate questionable results)
fi
fi
# Extract the short git hash of the repository (usually the last commit)
git_hash=-g$(git rev-parse --short HEAD)
# Count the number of commits and use that as our "build" number
# PROGRAMMING NOTE: we purposely do NOT use the simpler, newer, easier,
# slightly faster, and harder to get wrong "rev-list --count" technique,
# since older gits that come with some still in use older distros likely
# don't understand the "--count" option. Thus, we use the slightly
# slower, older, more complex and much easier to get wrong technique
# of piping the output of "log --pretty..." into "wc -l". Please also
# note that, unlike many broken implementations that are out there, we
# correctly use "tformat" and not "format" to ensure an accurate count.
VERS_BLD=$(($(git log --pretty=tformat:'' | wc -l)))
if test "$VERS_BLD" == "0"; then
# Try "format" instead of "tformat"...
VERS_BLD=$(($(git log --pretty=format:'' | wc -l)))
if test "$VERS_BLD" != "0"; then
# increment by 1 (because "format" was used, not "tformat")
VERS_BLD=$((++VERS_BLD))
else
# Last chance: use new "rev-list --count" method
VERS_BLD=$(($(git rev-list --count HEAD)))
fi
fi
fi
# Make sure all required variables have a value
if test "x$VERS_MAJ" = "x"; then
VERS_MAJ=0
fi
if test "x$VERS_INT" = "x"; then
VERS_INT=0
fi
if test "x$VERS_MIN" = "x"; then
VERS_MIN=0
fi
if test "x$VERS_BLD" = "x"; then
VERS_BLD=0
fi
if test "x$VERS_DEV" = "x"; then
VERS_DEV=0
fi
# Determine whether this is an official formal release version,
# or a between formal releases intermediate development version.
if test "$VERS_DEV" == "0"; then
dev_string="" # (official formal release version)
else
dev_string="-DEV" # (between release development version)
fi
# Construct a quoted VERSION string value
QUOTE='"'
VERSION="${QUOTE}${VERS_MAJ}.${VERS_INT}.${VERS_MIN}.${VERS_BLD}-SDL${dev_string}${git_hash}${modified_str}${QUOTE}"
# Finally, return (via echo) the desired version component back to the caller
if test "$vers_part" == "VERS_MAJ"; then
echo $VERS_MAJ
elif test "$vers_part" == "VERS_INT"; then
echo $VERS_INT
elif test "$vers_part" == "VERS_MIN"; then
echo $VERS_MIN
elif test "$vers_part" == "VERS_BLD"; then
echo $VERS_BLD
elif test "$vers_part" == "VERS_DEV"; then
echo $VERS_DEV
elif test "$vers_part" == "VERSION"; then
echo $VERSION
else
echo $VERSION
fi
# DONE! Exit back to caller...
cd "$orig_dir"
exit 0