diff options
-rwxr-xr-x | version | 237 |
1 files changed, 237 insertions, 0 deletions
@@ -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 |