Page MenuHomeClusterLabs Projects

bumplibs.in
No OneTemporary

bumplibs.in

#!@BASH_PATH@
#
# Copyright 2012-2024 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
# This source code is licensed under the GNU General Public License version 2
# or later (GPLv2+) WITHOUT ANY WARRANTY.
#
# List regular expressions (not globs) that match all of a library's public API
# headers. Any files ending in "internal.h" will be excluded from matches.
declare -A HEADERS
HEADERS[cib]="include/crm/cib.*.h
include/crm/cib/.*.h"
HEADERS[crmcluster]="include/crm/cluster.h
include/crm/cluster/.*.h"
HEADERS[crmcommon]="include/crm/crm.*.h
include/crm/msg_xml.h
include/crm/common/.*.h"
HEADERS[crmservice]="include/crm/services.*.h"
HEADERS[lrmd]="include/crm/lrmd.*.h"
HEADERS[pacemaker]="include/pacemaker.*.h"
HEADERS[pe_rules]="include/crm/pengine/ru.*.h"
HEADERS[pe_status]="include/crm/pengine/.*.h"
HEADERS[stonithd]="include/crm/stonith-ng.h include/crm/fencing/.*.h"
yesno() {
local RESPONSE
read -p "$1 " RESPONSE
case $(echo "$RESPONSE" | tr '[:upper:]' '[:lower:]') in
y|yes|ano|ja|si|oui) return 0 ;;
*) return 1 ;;
esac
}
prompt_to_continue() {
yesno "Continue?" || exit 0
}
sed_in_place() {
cp -p "$1" "$1.$$"
sed -e "$2" "$1" > "$1.$$"
mv "$1.$$" "$1"
}
find_last_release() {
if [ -n "$1" ]; then
echo "$1"
else
git tag -l | grep Pacemaker | grep -v rc | sort -Vr | head -n 1
fi
}
find_libs() {
find lib -name "*.am" -exec grep "lib.*_la_LDFLAGS.*version-info" \{\} \; \
| sed -e 's/lib\(.*\)_la_LDFLAGS.*/\1/'
}
find_makefile() {
find lib -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
}
find_headers_as_of() {
local TAG
local LIB
local FILE
local PATTERN
TAG="$1"
LIB="$2"
for FILE in $(git ls-tree -r --name-only "$TAG"); do
for PATTERN in ${HEADERS[$LIB]}; do
if [[ $FILE =~ $PATTERN ]] && [[ ! $FILE =~ internal.h$ ]]; then
echo "$FILE"
break
fi
done
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 HEADERS_LAST
local HEADERS_HEAD
local HEADERS_DIFF
local HEADERS_GONE
local HEADERS_ADDED
local CHANGE
local DEFAULT_CHANGE
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=$(extract_version "$LIB" < "$AMFILE")
# Check whether library existed at last release
if ! git cat-file -e "$LAST_RELEASE:$AMFILE" 2>/dev/null; then
echo "lib$LIB is new, not changing version ($VER_NOW)"
prompt_to_continue
echo ""
return
fi
HEADERS_LAST="$(find_headers_as_of "$LAST_RELEASE" "$LIB")"
HEADERS_HEAD="$(find_headers_as_of "HEAD" "$LIB")"
HEADERS_DIFF="$(diff <(echo "$HEADERS_LAST") <(echo "$HEADERS_HEAD"))"
HEADERS_GONE="$(echo "$HEADERS_DIFF" | sed -n -e 's/^< //p')"
HEADERS_ADDED="$(echo "$HEADERS_DIFF" | sed -n -e 's/^> //p')"
# Check whether there were any changes to headers or sources
SOURCES="$(find_sources "$LIB" "$AMFILE")"
if [ -n "$HEADERS_GONE" ]; then
DEFAULT_CHANGE="i" # Removed public header is incompatible change
elif [ -n "$HEADERS_ADDED" ]; then
DEFAULT_CHANGE="c" # Additions are likely compatible
elif git diff --quiet -w "$LAST_RELEASE..HEAD" $HEADERS_HEAD $SOURCES ; then
echo "No changes to $LIB interface"
prompt_to_continue
echo ""
return
else
DEFAULT_CHANGE="f" # Sources changed, so it's at least a fix
fi
# Show all header changes since last release
echo "- Changes in lib$LIB public headers since $LAST_RELEASE:"
if [ -n "$HEADERS_GONE" ]; then
for HEADER in $HEADERS_GONE; do
echo "-- $HEADER was removed"
done
fi
if [ -n "$HEADERS_ADDED" ]; then
for HEADER in $HEADERS_ADDED; do
echo "++ $HEADER is new"
done
fi
git --no-pager diff --color -w "$LAST_RELEASE..HEAD" $HEADERS_HEAD
echo ""
if yesno "Show commits (minus refactor/build/merge) touching lib$LIB since $LAST_RELEASE [y/N]?"
then
git log --color "$LAST_RELEASE..HEAD" -z $HEADERS_HEAD $SOURCES "$AMFILE" \
| grep -vzE "Refactor:|Build:|Merge pull request"
echo
prompt_to_continue
fi
# @TODO this seems broken ...
#echo ""
#if yesno "Show merged PRs touching lib$LIB since $LAST_RELEASE [y/N]?"
#then
# git log --merges $LAST_RELEASE..HEAD $HEADERS_HEAD $SOURCES $AMFILE
# echo
# prompt_to_continue
#fi
# Show summary of source changes since last release
echo ""
echo "- Headers: $HEADERS_HEAD"
echo "- Changed sources since $LAST_RELEASE:"
git --no-pager diff --color -w "$LAST_RELEASE..HEAD" --stat $SOURCES
echo ""
# Ask for human guidance
echo "Are the changes to lib$LIB:"
read -p "[c]ompatible additions, [i]ncompatible additions/removals or [f]ixes? [$DEFAULT_CHANGE]: " CHANGE
[ -z "$CHANGE" ] && CHANGE="$DEFAULT_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++ ))
VER_2=0
VER_3=0
# Some headers define constants for shared library names,
# update them if the name changed
for H in $HEADERS_HEAD; do
sed_in_place "$H" "s/$(shared_lib_name "$LIB" "$VER_NOW")/$(shared_lib_name "$LIB" "$VER_1:0:0")/"
done
;;
c|C)
echo "New version with backwards-compatible extensions: x+1:0:z+1"
(( VER_1++ ))
VER_2=0
(( VER_3++ ))
;;
F|f)
echo "Code changed though interfaces didn't: x:y+1:z"
(( VER_2++ ))
;;
*)
echo "Not updating lib$LIB version"
prompt_to_continue
CHANGE=""
;;
esac
VER_NEW=$VER_1:$VER_2:$VER_3
if [ -n "$CHANGE" ]; then
if [ "$VER_NEW" != "$VER_NOW" ]; then
echo "Updating lib$LIB version from $VER_NOW to $VER_NEW"
prompt_to_continue
sed_in_place "$AMFILE" "s/version-info\s*$VER_NOW/version-info $VER_NEW/"
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 --no-pager diff --color -w

File Metadata

Mime Type
text/plain
Expires
Thu, Jun 26, 6:09 PM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1942920
Default Alt Text
bumplibs.in (8 KB)

Event Timeline