blob: 346937b5f3230f9af4b2156e00ba5c56e6798512 [file] [log] [blame]
#!/bin/bash
declare -A HEADERS
HEADERS[cib]="include/crm/cib.h include/crm/cib/*.h"
HEADERS[crmcommon]="include/crm/crm.h
include/crm/attrd.h
include/crm/msg_xml.h
include/crm/common/*.h"
HEADERS[crmcluster]="include/crm/cluster.h include/crm/cluster/*.h"
HEADERS[crmservice]="include/crm/services.h"
HEADERS[lrmd]="include/crm/lrmd*.h"
HEADERS[pe_rules]="include/crm/pengine/rules*.h"
HEADERS[pe_status]="include/crm/pengine/*.h"
HEADERS[pengine]="include/crm/pengine/common.h
include/crm/pengine/complex.h
include/crm/pengine/rules.h
include/crm/pengine/status.h"
HEADERS[stonithd]="include/crm/stonith-ng.h include/crm/fencing/*.h"
HEADERS[transitioner]="include/crm/transition.h"
prompt_to_continue() {
local RESPONSE
read -p "Continue? " RESPONSE
case "$RESPONSE" in
y|Y|yes|ano|ja|si|oui) ;;
*) exit 0 ;;
esac
}
find_last_release() {
if [ ! -z "$1" ]; then
echo "$1"
else
git tag -l | grep Pacemaker | grep -v rc | sort -Vr | head -n 1
fi
}
find_libs() {
find . -name "*.am" -exec grep "lib.*_la_LDFLAGS.*version-info" \{\} \; \
| sed -e 's/lib\(.*\)_la_LDFLAGS.*/\1/'
}
find_makefile() {
find . -name Makefile.am -exec grep -l "lib${1}_la.*version-info" \{\} \;
}
find_sources() {
local LIB="$1"
local AMFILE="$2"
local SOURCES
# Library makefiles should use "+=" to break up long sources lines rather
# than backslashed continuation lines, to allow this script to detect
# source files correctly. Warn if that's not the case.
if
grep "lib${LIB}_la_SOURCES.*\\\\" $AMFILE
then
echo -e "\033[1;35m -- Sources list for lib$LIB is probably truncated! --\033[0m"
echo "Edit to use '+=' rather than backslashed continuation lines"
prompt_to_continue
fi
SOURCES=$(grep "lib${LIB}_la_SOURCES" "$AMFILE" \
| sed -e 's/.*=//' -e 's/\\//' -e 's:\.\./gnu/:lib/gnu/:')
for SOURCE in $SOURCES; do
if
echo $SOURCE | grep -q "/"
then
echo "$SOURCE"
else
echo "$(dirname $AMFILE)/$SOURCE"
fi
done
}
extract_version() {
grep "lib${1}_la.*version-info" | sed -e 's/.*version-info\s*\(\S*\)/\1/'
}
shared_lib_name() {
local LIB="$1"
local VERSION="$2"
echo "lib${LIB}.so.$(echo $VERSION | cut -d: -f 1)"
}
process_lib() {
local LIB="$1"
local LAST_RELEASE="$2"
local AMFILE
local SOURCES
local CHANGE
local CHANGES
if [ -z "${HEADERS[$LIB]}" ]; then
echo "Can't check lib$LIB until this script is updated with its headers"
prompt_to_continue
fi
AMFILE="$(find_makefile "$LIB")"
# Get current shared library version
VER_NOW=$(cat $AMFILE | extract_version $LIB)
# Check whether library existed at last release
git cat-file -e $LAST_RELEASE:$AMFILE 2>/dev/null
if [ $? -ne 0 ]; then
echo "lib$LIB is new, not changing version ($VER_NOW)"
prompt_to_continue
echo ""
return
fi
# Check whether there were any changes to headers or sources
SOURCES="$(find_sources "$LIB" "$AMFILE")"
CHANGES=$(git diff -w $LAST_RELEASE..HEAD ${HEADERS[$LIB]} $SOURCES | wc -l)
if [ $CHANGES -eq 0 ]; then
echo "No changes to $LIB interface"
prompt_to_continue
echo ""
return
fi
# Show all header changes since last release
git diff -w $LAST_RELEASE..HEAD ${HEADERS[$LIB]}
# Show summary of source changes since last release
echo ""
echo "- Headers: ${HEADERS[$LIB]}"
echo "- Changed sources since $LAST_RELEASE:"
git diff -w $LAST_RELEASE..HEAD --stat $SOURCES
echo ""
# Ask for human guidance
# @TODO: change default based on intelligent analysis
echo "Are the changes to lib$LIB:"
read -p "[c]ompatible additions, [i]ncompatible additions/removals or [f]ixes? [None]: " CHANGE
# Get (and show) shared library version at last release
VER=$(git show $LAST_RELEASE:$AMFILE | extract_version $LIB)
VER_1=$(echo $VER | awk -F: '{print $1}')
VER_2=$(echo $VER | awk -F: '{print $2}')
VER_3=$(echo $VER | awk -F: '{print $3}')
echo "lib$LIB version at $LAST_RELEASE: $VER"
# Show current shared library version if changed
if [ $VER_NOW != $VER ]; then
echo "lib$LIB version currently: $VER_NOW"
fi
# Calculate new library version
case $CHANGE in
i|I)
echo "New backwards-incompatible version: x+1:0:0"
VER_1=$(expr $VER_1 + 1)
VER_2=0
VER_3=0
# Some headers define constants for shared library names,
# update them if the name changed
for H in ${HEADERS[$LIB]}; do
sed -i -e "s/$(shared_lib_name "$LIB" "$VER_NOW")/$(shared_lib_name "$LIB" "$VER_1:0:0")/" $H
done
;;
c|C)
echo "New version with backwards-compatible extensions: x+1:0:z+1"
VER_1=$(expr $VER_1 + 1)
VER_2=0
VER_3=$(expr $VER_3 + 1)
;;
F|f)
echo "Code changed though interfaces didn't: x:y+1:z"
VER_2=$(expr $VER_2 + 1)
;;
*)
echo "Not updating lib$LIB version"
prompt_to_continue
CHANGE=""
;;
esac
VER_NEW=$VER_1:$VER_2:$VER_3
if [ ! -z $CHANGE ]; then
if [ "$VER_NEW" != "$VER_NOW" ]; then
echo "Updating lib$LIB version from $VER_NOW to $VER_NEW"
prompt_to_continue
sed -i "s/version-info\s*$VER_NOW/version-info $VER_NEW/" $AMFILE
else
echo "No version change needed for lib$LIB"
prompt_to_continue
fi
fi
echo ""
}
echo "Definitions:"
echo "- Compatible additions: new public API functions, structs, etc."
echo "- Incompatible additions/removals: new arguments to public API functions,"
echo " new members added to the middle of public API structs,"
echo " removal of any public API, etc."
echo "- Fixes: any other code changes at all"
echo ""
echo "When possible, improve backward compatibility first:"
echo "- move new members to the end of structs"
echo "- use bitfields instead of booleans"
echo "- when adding arguments, create a new function that the old one can wrap"
echo ""
prompt_to_continue
LAST_RELEASE=$(find_last_release "$1")
for LIB in $(find_libs); do
process_lib "$LIB" "$LAST_RELEASE"
done
# Show all proposed changes
git diff -w