summaryrefslogtreecommitdiff
path: root/version
diff options
context:
space:
mode:
Diffstat (limited to 'version')
-rwxr-xr-xversion237
1 files changed, 237 insertions, 0 deletions
diff --git a/version b/version
new file mode 100755
index 0000000..f904839
--- /dev/null
+++ b/version
@@ -0,0 +1,237 @@
+#! /usr/bin/env bash
+
+# Manage build2 toolchain version.
+#
+# Usage: version [<module>...]
+#
+usage="usage: $0 [<module>...]"
+
+# Notes:
+#
+# * min/max are [min, max)
+# if min == max, then '== min' is assumed
+# if max is unspecified, then '>= min' is assumed
+#
+
+build2_min=0.1.0 # No max, always >=.
+
+libbutl=0.1.0
+libbutl_min=$libbutl
+libbutl_max=$libbutl
+libbutl_build2=$build2_min
+libbutl_hxx=butl/version
+
+build2=0.1.0
+build2_libbutl_min=$libbutl_min
+build2_libbutl_max=$libbutl_max
+build2_build2=$build2_min
+build2_hxx=build2/version
+
+libbpkg=0.1.0
+libbpkg_min=$libbpkg
+libbpkg_max=$libbpkg
+libbpkg_libbutl_min=$libbutl_min
+libbpkg_libbutl_max=$libbutl_max
+libbpkg_build2=$build2_min
+libbpkg_hxx=bpkg/version
+
+bpkg=0.1.0
+bpkg_libbutl_min=$libbutl_min
+bpkg_libbutl_max=$libbutl_max
+bpkg_libbpkg_min=$libbpkg_min
+bpkg_libbpkg_max=$libbpkg_max
+bpkg_build2=$build2_min
+bpkg_hxx=bpkg/bpkg-version
+
+build2_toolchain=0.1.0
+build2_toolchain_build2=$build2_min
+
+brep=0.1.0
+brep_libbutl_min=$libbutl_min
+brep_libbutl_max=$libbutl_max
+brep_libbpkg_min=$libbpkg_min
+brep_libbpkg_max=$libbpkg_max
+brep_build2=$build2_min
+brep_hxx=brep/version
+
+#
+#
+owd=`pwd`
+trap "{ cd $owd; exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+modules=
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ *)
+ modules="$modules ${1%/}"
+ shift
+ ;;
+ esac
+done
+
+if [ -z "$modules" ]; then
+ modules="libbutl build2 libbpkg bpkg build2-toolchain brep"
+fi
+
+# Convert string version representation (1.2.3-a1) to its numeric equivalent
+# in the form AABBCCDD where:
+#
+# AA - major version number
+# BB - minor version number
+# CC - bugfix version number
+# DD - alpha / beta (DD + 50) version number
+#
+# When DD is not 00, 1 is subtracted from AABBCC. For example:
+#
+# Version AABBCCDD
+# 2.0.0 02000000
+# 2.1.0 02010000
+# 2.1.1 02010100
+# 2.2.0-a1 02019901
+# 3.0.0-b2 02999952
+#
+# For a version in the 1.2.3- form, it returns (AABBCC-1)00, which is the
+# highest possible version that is less than 1.2.3-.
+#
+function str_num () # <ver-str>
+{
+ # Here we assume the version is valid.
+ #
+ local a=`echo $1 | sed -e 's/\([0-9]*\).*/\1/' -`
+ local b=`echo $1 | sed -e 's/[^.]*\.\([0-9]*\).*/\1/' -`
+ local c=`echo $1 | sed -e 's/[^.]*\.[^.]*\.\([0-9]*\).*/\1/' -`
+ local d=`echo $1 | sed -n -e 's/[^.]*\.[^.]*\.[^-]*\(-[ab]*[0-9]*\)/\1/p' -`
+
+ local v=$(($a * 1000000 + $b * 10000 + $c * 100))
+
+ if [ "$d" ]; then
+ ((v -= 100))
+ if [ $d != "-" ]; then
+ if [ ${d:1:1} = 'b' ]; then
+ ((v += 50))
+ fi
+ d=`echo $d | sed -e 's/-[ab]\([0-9]*\)/\1/' -`
+ ((v += $d))
+ fi
+ fi
+
+ #info $1 -> $a $b $c $d -> $v
+ echo $v
+}
+
+function str_num_test () { if [ `str_num $1` != $2 ]; then error $1 != $2; fi }
+
+str_num_test 2.0.0 2000000
+str_num_test 2.1.0 2010000
+str_num_test 2.1.1 2010100
+str_num_test 2.2.0-a1 2019901
+str_num_test 3.0.0-b2 2999952
+
+str_num_test 2.0.0- 1999900
+str_num_test 2.2.0- 2019900
+
+# In-place sed.
+#
+function ised () # <regex> <file>
+{
+ local r=$1
+ local f=$2
+ local o=$f.orig
+
+ mv $f $o
+ cp -p $o $f # Keep owner, permissions.
+
+ if ! sed -e "$r" $o >$f; then
+ mv $o $f
+ return 1
+ fi
+
+ if cmp -s $o $f; then
+ mv $o $f
+ else
+ rm $o
+ fi
+}
+
+# Modules which we may depend on. These are translated to 'depends:' in the
+# manifest and preprocessor checks in the version header. Note that we can
+# add external modules like libodb, etc., when the time comes.
+#
+depends="libbutl libbpkg"
+
+for m in $modules; do
+ v=`echo $m | sed -e 's/-/_/g'`
+ V=`echo $v | sed -e 's/\(.*\)/\U\1/'`
+
+ s=${!v}
+ n=`str_num $s`
+
+ b=${v}_build2; b=${!b}
+
+ # version
+ #
+ ised "s/^[0-9].*/$s/" $m/version
+
+ # manifest
+ #
+ if [ -f $m/manifest ]; then
+ ised "s/^\(version:\) .*/\1 $s/" $m/manifest
+ ised "s/^\(requires: build2\) .*/\1 >= $b/" $m/manifest
+ fi
+
+ # bootstrap.build
+ #
+ ised "s/^\(version =\) .*/\1 $s/" $m/build/bootstrap.build
+ ised "s/^\(using build@\).*/\1$b/" $m/build/bootstrap.build
+
+ # version header
+ #
+ h=${v}_hxx; h=${!h}
+ if [ "$h" ]; then
+ ised "s/^\(#define ${V}_VERSION\) .*/\1 $n/" $m/$h
+ ised "s/^\(#define ${V}_VERSION_STR\) .*/\1 \"$s\"/" $m/$h
+ fi
+
+ # Dependencies (manifest and version header).
+ #
+ for d in $depends; do
+ if [ $d = $m ]; then continue; fi
+
+ dv=`echo $d | sed -e 's/-/_/g'`
+ DV=`echo $dv | sed -e 's/\(.*\)/\U\1/'`
+
+ dmin=${v}_${dv}_min; dmin=${!dmin}
+ dmax=${v}_${dv}_max; dmax=${!dmax}
+
+ if [ -z "$dmin" ]; then continue; fi # No dependency.
+
+ dminn=`str_num $dmin`
+
+ # Figure out dependency contraints for the manifest and the header.
+ #
+ if [ -z "$dmax" ]; then
+ dcm=">= $dmin"
+ dch="${DV}_VERSION < $dminn"
+ elif [ "$dmin" = "$dmax" ]; then
+ dcm="== $dmin"
+ dch="${DV}_VERSION != $dminn"
+ else
+ dmaxn=`str_num $dmax`
+ dcm="[$dmin, $dmax)"
+ dch="${DV}_VERSION < $dminn || ${DV}_VERSION > $dmaxn"
+ fi
+
+ if [ -f $m/manifest ]; then
+ ised "s/^\(depends: $d\) .*/\1 $dcm/" $m/manifest
+ fi
+
+ if [ "$h" ]; then
+ ised "s/^#if ${DV}_VERSION .*/#if $dch/" $m/$h
+ fi
+ done
+done