Adding a script to update CHANGES and VERSION.

This is still experimental ...
This commit is contained in:
Robin Sommer 2011-07-19 19:06:23 -07:00
parent c4fd6c9280
commit 31f68c7627

236
aux/devel-tools/update-changes Executable file
View file

@ -0,0 +1,236 @@
#! /usr/bin/env bash
#
# Assembles a draft CHANGES entry out of recent commits. The entry is prepended
# to the current CHANGES file and the user then gets a chance to further edit
# it in the editor before it gets committed. Also updates the VERSION file.
#
# If $1 is given, it's interpreted as a release version and a correspondign
# tag is created.
#
# The script is not the fastest when there are many commits since the last update
# so better run it regularly ...
#
# (This script needs a clean up ...)
function my_describe
{
# "git describe" also counts commits on other than the main parent's path. This version doesn't.
rev=$1
if [ "$rev" == "" ]; then
rev=HEAD
fi
last_tag="<untagged>"
last_tag_rev="<norev>"
for i in `git rev-list --first-parent $rev`; do
echo $d >&2 git describe --exact-match $i
tag=`git describe --exact-match $i 2>/dev/null`;
if [ "$tag" != "" ]; then
last_tag="$tag"
last_tag_rev="$i"
break;
fi
done
cnt=0
for i in `git rev-list --first-parent $rev`; do
if [ "$i" == "$last_tag_rev" ]; then
break
fi
cnt=`expr $cnt '+' 1`
done
if [ "$cnt" == "0" ]; then
cnt=""
else
abbr=`git show --abbrev-commit --pretty=oneline $rev | head -1 | cut -d ' ' -f 1`
cnt="-$cnt-$abbr"
fi
echo "$last_tag$cnt"
}
function normed_describe
{
# $1 may be emty.
d=`my_describe $1 | sed 's/^v//g' | sed "s/-[^-]*$//g" | sed 's/ //g'`
if [ "$bro_style" == "1" ]; then
d=`echo $d | sed 's/-\([0-9]*\)$/.\\1/'`
fi
echo -n $d
}
if [ "$1" == "-I" ]; then
echo Initializing CHANGES file.
init=1
shift
fi
if [ "$1" != "" ]; then
NEWVERSION=$1
( echo $NEWVERSION | egrep -vq '^[0-9]+\.[0-9]+' ) && echo "Version must be of the form X.Y[.Z]" && exit 1
fi
changes=CHANGES
version=VERSION
if grep -q -- '-+-+-+-+-+-+-+-+-+-' $changes; then
# With Bro's CHANGES file, we use a slightly different style.
bro_style=1
else
bro_style=0
fi
tmp=${changes}.tmp
trap "rm -f $tmp" EXIT
version_short=`normed_describe`
version_full=`git describe 2>/dev/null | sed 's/^v//g'`
if [ "$NEWVERSION" == "" ]; then
version_string=$version_short
else
version_string=$NEWVERSION
fi
if [ "$version_short" == "" ]; then
echo "can't generate version_short string"
exit 1
fi
if [ "$init" == "1" ]; then
echo >>$changes
printf '%s | ' $version_string >$changes
git show -s "--pretty=tformat:%ci" master >>$changes
echo >>$changes
echo " * Starting $changes." >>$changes
exit 0
fi
# Get the last entry for which we recorded entries.
last=`cat $changes | awk '{print $1}' | egrep '[0-9]+\.[0-9]+' | head -1 | sed 's/ //g'`
# Get the corresponding revision.
not_last_rev=""
for i in `git rev-list --first-parent HEAD`; do
descr=`normed_describe $i`
# echo "### debug: $i $descr $last"
echo -n .
if [ "$descr" == "$last" ]; then
not_last_rev="^$i"
break;
fi
done
echo
if [ "$last" = "" -o "$not_last_rev" = "" ]; then
echo "Warning: cannot locate previous entry, assuming all is new ... ($last/$not_last_rev)"
else
echo "New revisions since" $last
fi
echo
rm -f $tmp
if [ "$bro_style" != "1" ]; then
printf '%s | ' $version_short >$tmp
git show -s "--pretty=tformat:%ci" master >>$tmp
else
printf '%s %s' $version_short "`date`" >$tmp
fi
echo >>$tmp
# echo >>$tmp
found=0
# echo "### debug: git rev-list --topo-order $not_last_rev HEAD"
for rev in `git rev-list --topo-order $not_last_rev HEAD`; do
rev_describe=`normed_describe $rev`
# echo "### debug: $rev $rev_describe $last"
#if [ "$rev_describe" == "$last" ]; then
# break;
#fi
git show -s "--pretty=tformat: %h | %aN | %s" $rev | cat
author=`git show -s "--pretty=format:%aN" $rev`
msg=`git show -s "--pretty=format:%B" $rev`
if [ "$msg" != "" ]; then
if [ "$bro_style" != "1" ]; then
bullet=" *"
else
bullet="-"
fi
( echo -n "$msg"; printf " (%s)" "$author" ) | awk -v bullet="$bullet" 'NR==1{printf "%s %s\n", bullet, $0; next }{printf " %s\n", $0}' >>$tmp
echo >>$tmp
found=1
fi
done
if [ "$found" == "0" ]; then
echo " None."
echo
if [ "$NEWVERSION" == "" ]; then
exit 0
fi
fi
# echo >>$tmp
cat $changes >>$tmp
echo
# If we are ahead of origin, we can amend. If not, we need to create a new commit.
if git status | grep -q "is ahead of 'origin/master'"; then
echo CHANGES modifications will be amended to last commit.
amend=1
else
echo CHANGES modifications will become a new commit.
amend=0
fi
echo
echo Type Enter to edit new $changes, or CTRL-C to abort without changes.
read
eval $EDITOR $tmp
rm -f $changes.bak
mv $tmp $changes
echo $version_string >$version
git add $changes $version
if [ "$amend" == "1" ]; then
git commit --amend
else
git commit
fi
echo "Old $tmp in saved in ${changes}.bak."
echo "Set $version to $version_string."
if [ "$NEWVERSION" != "" ]; then
git tag -d v$NEWVERSION 2>/dev/null
git tag -a v$NEWVERSION -m "Version $$NEWVERSION"
echo Created new tag v$NEWVERSION.
fi