| #!/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 |