#!/bin/bash NAME=$(basename $0) MONO_API_INFO="mono-api-info" MONO_API_DIFF="mono /usr/lib/mono/4.5/mono-api-diff.exe" KEEP=0 if [ "$1" = "-k" ]; then KEEP=1 KEEP_PARAM="-k" shift fi ABI= if [ "$1" = "-a" ]; then ABI=1 ABI_PARAM="-a" MONO_API_INFO_PARAMS=--abi shift fi if [ $# -lt 2 ]; then echo "usage: $NAME [-k] [-a] old.dll|deb|changes new.dll|deb|changes" exit 1 fi if [ ! -r $1 ]; then echo "Error: $1 does not exist or is not readable" exit 1 fi if [ ! -r $2 ]; then echo "Error: $2 does not exist or is not readable" exit 1 fi if ! [ "$1" = "${1%.deb}" ]; then DEB_TMP_DIR1=/tmp/$NAME-$$-$RANDOM DEB_TMP_DIR2=/tmp/$NAME-$$-$RANDOM mkdir $DEB_TMP_DIR1 if [ $? != 0 ]; then echo "Error: could not create: $DEB_TMP_DIR1" exit 1 fi mkdir $DEB_TMP_DIR2 if [ $? != 0 ]; then echo "Error: could not create: $DEB_TMP_DIR2" exit 1 fi dpkg -x $1 $DEB_TMP_DIR1 if [ $? != 0 ]; then echo "Error: could extract: $1" exit 1 fi dpkg -x $2 $DEB_TMP_DIR2 if [ $? != 0 ]; then echo "Error: could extract: $2" exit 1 fi DLLS=$(find $DEB_TMP_DIR1 -type f -name "*.dll") for DLL1 in $DLLS; do FILE=${DLL1#$DEB_TMP_DIR1/} DLL2=$DEB_TMP_DIR2/$FILE #echo $DLL1 #echo $DLL2 echo -e "Library:\t\t/$FILE" $0 $RUNTIME_VERSION_PARAM $KEEP_PARAM $ABI_PARAM $DLL1 $DLL2 echo done rm -rf $DEB_TMP_DIR1 rm -rf $DEB_TMP_DIR2 exit 0 fi if ! [ "$1" = "${1%.changes}" ]; then DEB_DIR1=$(dirname $1) DEB_DIR2=$(dirname $2) DEBS=$(grep ".deb$" $2 | cut -d ' ' -f 6) for DEB in $DEBS; do PKG_VERSION2=$(dpkg -I $DEB_DIR2/$DEB | grep Version: | cut -d ':' -f 2 | sed -e 's/^ *//') break done DEBS=$(grep ".deb$" $1 | cut -d ' ' -f 6) for DEB1 in $DEBS; do PKG_NAME=$(dpkg -I $DEB_DIR1/$DEB1 | grep Package: | cut -d ':' -f 2 | sed -e 's/^ *//') PKG_ARCH=$(dpkg -I $DEB_DIR1/$DEB1 | grep Architecture: | cut -d ':' -f 2 | sed -e 's/^ *//') DEB2=$DEB_DIR2/${PKG_NAME}_${PKG_VERSION2}_${PKG_ARCH}.deb echo -e "Package:\t\t$PKG_NAME" echo "------------------------------------------------------" $0 $RUNTIME_VERSION_PARAM $KEEP_PARAM $ABI_PARAM $DEB1 $DEB2 echo done exit 0 fi ASM_NAME=$(basename $1) API_OLD=$(tempfile --suffix=_$ASM_NAME.api-old) API_NEW=$(tempfile --suffix=_$ASM_NAME.api-new) API_DIFF=$(tempfile --suffix=_$ASM_NAME.api-diff) ${MONO_API_INFO} $MONO_API_INFO_PARAMS "$1" > ${API_OLD} 2> /dev/null if [ $? != 0 ]; then echo "Error: ${MONO_API_INFO} on $1 failed!" exit 1 fi ${MONO_API_INFO} $MONO_API_INFO_PARAMS "$2" > ${API_NEW} 2> /dev/null if [ $? != 0 ]; then echo "Error: ${MONO_API_INFO} on $2 failed!" exit 1 fi ${MONO_API_DIFF} ${API_OLD} ${API_NEW} > ${API_DIFF} 2> /dev/null if [ $? != 0 ]; then echo "Error: ${MONO_API_DIFF} failed!" exit 1 fi version_changed=0 grep -q 'Assembly version not equal: ' ${API_DIFF} if [ $? = 0 ]; then version_changed=1 fi name=$(head -n3 ${API_DIFF} | tail -n1 | sed 's;\ ;\n;g' | grep ^name | cut -d\= -f2 | sed 's;\";;g') missing_total=$(head -n3 ${API_DIFF} | tail -n1 | sed 's;\ ;\n;g' | grep ^missing_total | cut -d\= -f2 | sed 's;\";;g') extra_total=$(head -n3 ${API_DIFF} | tail -n1 | sed 's;\ ;\n;g' | grep ^extra_total | cut -d\= -f2 | sed 's;\";;g') if [ -z $missing_total ]; then missing_total=0 fi if [ -z $extra_total ]; then extra_total=0 fi echo "CLI API Check" echo -e "Assembly Name:\t\t$name" echo -e "Missing Interfaces:\t$missing_total" echo -e "Additional Interfaces:\t$extra_total" if [ $missing_total ] then if [ $missing_total -gt 0 ] then echo echo "The two assemblies you compared are NOT API compatible!" echo "You must use a new package name!" fi fi if [ $extra_total ] then if [ $extra_total -gt 0 ] then echo echo "The new assembly has additional interfaces. You must raise" echo "the minimal version in clilibs!" fi fi if [ $version_changed = 1 ]; then echo echo "The assembly versions do NOT MATCH!" echo "If they are API compatible you MUST generate and install a GAC policy file!" fi rm -f ${API_OLD} ${API_NEW} if [ $KEEP = 1 ]; then echo "API diff file: ${API_DIFF}" else rm -f ${API_OLD} ${API_NEW} fi