Files
secondo/CM-Scripts/cvs-make.sh
2026-01-23 17:03:45 +08:00

644 lines
15 KiB
Bash

# !/bin/bash
#
# cvs-make.sh:
#
# This bash-script checks out the last SECONDO sources
# and runs make to compile them.
#
# 03/02/28 M. Spiekermann: initial version
# 04/01/27 M. Spiekermann: port from csh to bash
# 05/01/27 M. Spiekermann: major revision, automatic test runs
# July 2005 M. Spiekermann: cvsDir was not set correctly.
#
# July-August 2005, M. Spiekermann: The script will now only
# compile SECONDO if there are changes in the CVS repository.
# Moreover, the CVS history will be shown and the users who made
# changes are extracted and their email addresses are retrieved.
#
# August 2005, M. Spiekermann: A new function makeSecondo was introduced. Now
# SECONDO will be compiled twice: first with all algebra modules activated
# and second with the algebras as defined in makefile.alsgebras.sample.
# Moreover, if the script is successful, a new tag LAST_STABLE will be set
# for the file's revision numbers.
#
# January 2006, M. Spiekermann: A backup dir for mails and test outputs
# was implemented.
#
# October 2006, M. Spiekermann: Support for multiple SDKs and cvs modules added.
#
# March 2007, M. Spiekermann: Support for tar files and module options implemented.
# Configuration Options
export OSTYPE=linux
# root for created local directories and files
opt_rootDir="/tmp"
# default gcc version str
opt_gccVersion=".undefined"
# cvs configuration
cvsDir=/home/spieker/tmp-cvs
opt_coTag="HEAD"
opt_cvsServer="zeppelin"
#opt_logRoot="/home/secondo/testrun-errors"
opt_logRoot="/var/tmp/cvs-make"
opt_waitMax=1800
opt_tarFile="none"
opt_tarMail="Thomas.Behr@Fernuni-Hagen.de Fabio.Valdes@fernuni-hagen.de"
opt_runTests="yes"
opt_mkStable="yes"
opt_earlyExit="no"
# options for automatic mails
LU_SENDMAIL="true"
LU_SENDMAIL_FROM="fabio.valdes@fernuni-hagen.de"
failedBuild_DefaultRecipients="Thomas.Behr@Fernuni-Hagen.de Fabio.Valdes@Fernuni-Hagen.de Christian.Duentgen@Fernuni-Hagen.de"
newTarFile_MailRecipients="fabio.valdes@fernuni-Hagen.de"
LU_LOG_SCREEN="true"
# define mail bodys
mailHeader="
This message was generated by $0!
"
mailFooter="
Please contact the involved people in order to find out
who should fix the problem! A history of the old error log
files is stored in $opt_logRoot on server $opt_cvsServer."
mailBody1="
$mailHeader
You will find the output of make in the attached file.
$mailFooter
"
mailBody2="
$mailHeader
You will find the log files of the failed tests in the attached file.
$mailFooter"
mailBody3="
$mailHeader
You will find the log file of make realclean in the attached file.
List of unremoved files:
"
mailBody4="
$mailHeader
A new public version was created as tar file in
"
#############################################################
# IMPLEMENTATION PART #
#############################################################
opt_sdkRootDir="$HOME"
opt_sdkDir="secondo-sdk"
opt_coModule="secondo"
opt_coModuleOpt="std"
# Include function definitions of libutil.sh. It must be in the same direcory
# as this script file or in the search path.
baseDir=$HOME/${0%/*}
if [ -s $baseDir/libutil.sh ];
then
if ! source $baseDir/libutil.sh; then exit 1; fi
else
if ! source libutil.sh; then exit 1; fi
fi
##
## Function Definitions
##
# checkOpt
#
function checkOpt()
{
local optName=$1
local val="$2"
shift
shift
for opt in $*; do
if [ "$val" == "$opt" ]; then
return 0
fi
done
echo "Error: Option \"$optName = $val\" is invalid. I must be one of [$*]."
exit 1
}
# cvsChanges
#
# $1 file last date
# $2 cvs module
function cvsChanges()
{
# retrieve date of last run and store it in the first
# line. This is more secure since time stamps of the file
# may be modified by backup-script etc.
local file=$1
local module=$2
lastDate="1-day-ago"
if [ -e $file ]; then
lastDate=$(tail -n1 $file)
fi
showValue lastDate
# Note: The -p"prefix" option of the history commands selects files starting with the
# given prefix. Since we have other repositories starting with "secondo" we need to filter
# the output using grep.
local cvsHistCmd="cvs history -xMAR -a -D\"$lastDate\" -p\"$module\" | sed -nre \"/$module[/ ]|No records/p\""
showValue cvsHistCmd
cvsHistory=$(eval $cvsHistCmd)
#showValue cvsHistory
# store current date in file
local currentDate=$(date +"%Y-%m-%d %H:%M")
echo $lastDateFileHeader > $file
echo $currentDate >> $file
cvsChanges="
-----------------------------------------------------------
${currentDate}: Changes since last run (${lastDate})
-----------------------------------------------------------
$cvsHistory"
echo -e "$cvsChanges" >> $cvsHistFile
# extract the 1st line of cvs history
local cvsHist_1st=$(echo $cvsHistory | head -n1)
#showValue cvsHist_1st
if [ "$cvsHist_1st" == "No records selected." ]; then
return 1
else
return 0
fi
}
# mkMailStr
# $1 body
function mkMailStr {
MAIL_STR="SECONDO_SDK=<"$SECONDO_SDK">
SECONDO_BUILD_DIR=<"$SECONDO_BUILD_DIR">
$cvsChanges
$1"
}
# mkMailStr2
# $1 body
# $2 variable text
function mkMailStr2 {
MAIL_STR="SECONDO_SDK=<"$SECONDO_SDK">
SECONDO_BUILD_DIR=<"$SECONDO_BUILD_DIR">
$1
$2"
}
# makeModule $1 $2
#
# $1 file name for make's output
# $2 subject for email
function makeModule() {
local msgFile=$1
local subject=$2
cd $cbuildDir
CM-Scripts/catvar.sh > $msgFile 2>&1
if isCmdPresent "nice"; then
local niceOpt="nice -n 19"
fi
checkCmd "$niceOpt make" >> $msgFile 2>&1
local rc=$?
# proceed if last command was successful
if [ $rc -ne 0 ]; then
printf "%s\n" "Problems during build, sending a mail."
mkMailStr "$mailBody1"
sendMail "$subject $gccMailSubject" "$mailRecipients $failedBuild_DefaultRecipients" "$MAIL_STR" "$cvsHistMailBackupDir" "$msgFile"
return $rc
fi
}
function cleanModule
{
if [ "$opt_tarFile" != "none" ]; then
return 0
fi
printSep "Cleaning $opt_coModule"
local logFile=$tmpDir/make-realclean.log
checkCmd "make realclean" > $logFile 2>&1
mk_rc=$?
printf "\n%s\n" "files unkown to CVS:"
grepCmd='cvs -nQ update | grep "^? "'
local leftFiles=$($grepCmd)
if [ "$leftFiles" != "" ]; then
mkMailStr "$mailBody3 $leftFiles"
sendMail "make realclean has left some files! $gccMailSubject" "$mailRecipients" "$MAIL_STR" "$cvsHistMailBackupDir" "$logFile"
else
echo "The command $grepCmd returned no files!"
fi
return $mk_rc
}
###
### MAIN PART
###
tmpDir=/tmp/cvs-make-$USER
mkdir -p $tmpDir
declare -i numOfArgs=$#
let numOfArgs++
while [ $# -eq 0 -o $numOfArgs -ne $OPTIND ]; do
getopts "behnm:r:w:c:s:t:d:g:f:o:" optKey
if [ "$optKey" == "?" ]; then
optKey="h"
fi
case $optKey in
h) showGPL
printf "\n%s\n" "Usage of ${0##*/}:"
printf "%s\n" "Global-Options:"
printf "%s\n" " -h print this message and exit."
printf "%s\n" " -n send no mails. Just print the message to stdout."
printf "%s\n" " -e exit before compile (for testing only)."
printf "%s\n" " -b build only, don't run tests."
printf "%s\n" "SDK-Settings:"
printf "%s\n" " -s<sdk-root> => \"${opt_sdkRootDir}\" "
printf "%s\n" " -d<sdk-dir> => \"${opt_sdkDir}\" "
printf "%s\n" " -g<gcc-version> => \"${opt_gccVersion}\" "
printf "%s\n" " -t<version-tag> => \"${opt_coTag}\" "
printf "%s\n" "Source-Definitions:"
printf "%s\n" " -m<cvs-module> => \"${opt_coModule}\" "
printf "%s\n" " -o<module-option> => \"${opt_coModuleOpt}\" "
printf "%s\n" " -f<tar-file> => \"${opt_tarFile}\" "
printf "%s\n" " -r<build-root> => \"${opt_rootDir}\" "
printf "%s\n" " -c<checkout-dir> => \"tmp_secondo_<date>\""
printf "%s\n" "Test-Run Options:"
printf "%s\n" " -w<seconds> (timeout for tests!) => \"${opt_waitMax}\" "
printf "%s\n" " -l<log-root> => \"${opt_logRoot}\" "
printf "%s\n" " -x<log-root> => \"${opt_logRoot}\" "
printf "%s\n\n" "The script checks out a local copy of <cvs-module> into the directoy"
printf "%s\n" "into <build-root>/<checkout-dir> and runs make, various tests, etc."
printf "%s\n\n" "In case of a failure an email will be sent to the CVS users."
exit 0;;
b) opt_runTests="no";;
r) opt_rootDir=$OPTARG;;
s) opt_sdkRootDir=$OPTARG;;
d) opt_sdkDir=$OPTARG;;
e) opt_earlyExit="true";;
t) opt_coTag=$OPTARG;;
g) opt_gccVersion=$OPTARG;;
c) opt_coDir=$OPTARG;;
o) opt_coModuleOpt=$OPTARG;;
m) opt_coModule=$OPTARG;;
f) opt_tarFile=$OPTARG;;
w) opt_waitMax=$OPTARG;;
n) LU_SENDMAIL="false";;
esac
done
checkOpt "-o" "$opt_coModuleOpt" "all" "std"
printSep "Variable values"
opt_coDir=${opt_coModule}_${date_ymd}_${date_HMS}.gcc${opt_gccVersion}
showValue opt_rootDir
showValue opt_sdkRootDir
showValue opt_sdkDir
showValue opt_gccVersion
showValue opt_coTag
showValue opt_coDir
showValue opt_coModule
showValue opt_coModuleOpt
showValue opt_tarFile
showValue opt_tarMail
if [ "$opt_tarFile" != "none" ]; then
opt_mkStable="no"
fi
showValue opt_mkStable
showValue opt_earlyExit
showValue opt_runTests
showValue opt_waitMax
showValue LU_SENDMAIL
showValue LU_SENDMAIL_FROM
showValue cvsDir
showValue tmpDir
if [ "$opt_coModule" == "" ]; then
echo -e "Error: a module needs to be specified!"
exit 1;
fi
if [ "$opt_gccVersion" != "" ]; then
gccMailSubject="(using gcc $opt_gccVersion)"
fi
# set up environment for secondo
source ~/.bashrc # this is needed when started by cron
# overwrite SECONDO_SDK and set up
# the compiler and other tools needed by secondo
if [ "$opt_sdkRootDir" == "" ]; then
echo -e "Error: The SDK root needs to be specified!"
exit 1;
fi
if [ "$opt_sdkDir" == "" ]; then
echo -e "Error: The SDK dir needs to be specified!"
exit 1;
fi
export SECONDO_SDK=$opt_sdkRootDir/$opt_sdkDir
showValue SECONDO_SDK
echo "OSTYPE <$OSTYPE>"
if ! source $SECONDO_SDK/secondorc; then exit 1; fi
# derive some other important directories
cbuildDir=${opt_rootDir}/${opt_coDir}
if [ "$opt_tarFile" != "none" ]; then
cbuildDir=${opt_rootDir}/${opt_coDir}/$opt_coModule
createDir $cbuildDir
fi
scriptDir=${cbuildDir}/CM-Scripts
startDate=$(date)
scriptFile="${PWD}/$0"
showValue startDate
showValue scriptFile
showValue scriptDir
showValue cbuildDir
## check if files in the module secondo were changed
## since the last run
if [ "$opt_tarFile" == "none" ]; then
opt_logRoot="$opt_logRoot/$opt_sdkDir/$opt_coModule"
else
opt_logRoot="$opt_logRoot/$opt_sdkDir/tarfile"
fi
lastDateFile="$opt_logRoot/lastrun"
lastDateFileHeader="#This file was generated by $0! It stores the date of the last run."
createDir $opt_logRoot
cvsHistFile="$opt_logRoot/cvs-make-history"
cvsHistMailBackupDir=$opt_logRoot/${date_ymd}_${date_HMS}
showValue opt_cvsServer
showValue opt_logRoot
showValue lastDateFile
showValue cvsHistFile
showValue cvsHistMailBackupDir
if [ "$opt_tarFile" == "none" ]; then
cvsChanges "$lastDateFile" "$opt_coModule"
cvsChanges_rc=$?
showValue cvsChanges_rc
if [ $cvsChanges_rc -ne 0 ]; then
printf "\nNo changes since ${lastDate}! \n\n"
exit 0;
else
echo -e "\n$cvsChanges"
cvsUsers=$( echo -e "$cvsHistory" |
awk '/./ { print $5 }' | sort | uniq | tr "\n" " " )
mailRecipients=""
for userName in $cvsUsers; do
mapStr "${cvsDir}/CVSROOT/users" "$userName" ":"
mailRecipients="$LU_MAPSTR $mailRecipients"
done
printf "\n%s\n" "CVS user(s) : $cvsUsers"
printf "%s\n" "Mail address(es): $mailRecipients"
fi
else
mailRecipients=$opt_tarMail
cvsChanges="Testing $opt_tarFile"
fi
## report host status
printSep "host status"
printf "%s\n" "uptime"
uptime
printf "\n%s\n" "disk free"
df -k
printf "\n%s\n" "memory usage"
free -m
## checkout work copy
printSep "Checking out source files"
setvar $cbuildDir
printSep "Environment settings"
catvar
printSep "Alias definitions"
alias
if [ "$opt_tarFile" == "none" ]; then
cd $opt_rootDir
checkCmd "cvs -Q checkout -d $opt_coDir -P $opt_coModule"
else
cd $opt_rootDir/$opt_coDir
checkCmd "tar -xzf $opt_tarFile"
checkCmd "rm $opt_tarFile"
fi
if [ "$opt_earlyExit" == "yes" ]; then
exit 0
fi
##
## Build the specified module
##
declare -i errors=0
cd $cbuildDir
printf "\n%s\n" "Changed to directory $PWD"
printSep "Compile $opt_coModule with option $opt_coModuleOpt"
moduleOptInit="false"
if [ "$opt_coModuleOpt" == "all" ]; then
echo "Setting Options for $opt_coModuleOpt ..."
export SECONDO_ACTIVATE_ALL_ALGEBRAS="true"
#export SECONDO_YACC="/usr/bin/bison"
logFile=$tmpDir/make-all-algebras.log
subject="Building $opt_coModule with all algebras failed!"
opt_runTests="no"
opt_mkStable="no"
moduleOptInit="true"
fi
if [ "$opt_coModuleOpt" == "std" ]; then
echo "Setting Options for $opt_coModuleOpt ..."
unset SECONDO_ACTIVATE_ALL_ALGEBRAS
logFile=$tmpDir/make-default-algebras.log
subject="Building $opt_coModule failed!"
moduleOptInit="true"
fi
if [ "$moduleOptInit" == "false" ]; then
echo "Error: Options are not initialized."
exit 1
fi
showValue logFile
showValue subject
makeModule "$logFile" "$subject"
mk_rc=$?
if [ $mk_rc -ne 0 ]; then
echo "*** Error during build! ***"
cleanModule
exit $mk_rc
fi
## run tests
if [[ ($mk_rc -eq 0) && ($opt_runTests == "yes") ]]; then
printSep "Running automatic tests"
cd $scriptDir
checkCmd "run-tests.sh -tty $opt_logRoot $opt_waitMax"
if [ $? -ne 0 ]; then
printf "%s\n" "Problems during test, sending a mail"
attachment2="$cbuildDir/failedTests.tar.gz"
subject2="Automatic tests failed! $gccMailSubject"
failedHist="
List of failed tests:
---------------------
$(find $opt_logRoot -name "_failed_*" -exec cat {} \;)
"
mkMailStr "$mailBody2 $failedHist"
sendMail "$subject2" "$mailRecipients" "$MAIL_STR" "$cvsHistMailBackupDir" "$attachment2"
let errors++
fi
cleanModule
if [[ ($[errors] == 0)
&& ("$opt_runTests" == "yes") && ("$opt_mkStable" == "yes") ]]; then
# Move label for stable version
cd $cbuildDir
tagSym="LAST_STABLE"
tagMsg="Moving CVS tag $tagSym"
printSep $tagMsg
echo -e "Automatic regression test was successful. ${tagMsg}!" >> $cvsHistFile
cvs -Q tag -d $tagSym
cvs -Q tag $tagSym
make tag=$tagSym src-archives
#Backup to /www switched of since the server has problems
#cp /tmp/make-$USER/secondo-$tagSym* $HOME/Backup
# send a notification
archive="/tmp/make-$USER/secondo-$tagSym.tar.gz"
mkMailStr2 "$mailBody4" $archive
sendMail "New public version source archives created" "$newTarFile_MailRecipients" "$MAIL_STR"
# clean up
rm -rf $cbuildDir
rm -rf $tmpDir
# rm -rf /tmp/make-$USER
fi
echo "*** The regression test finished with $errors errors ***"
exit $errors
fi