# # aegis - project change supervisor # Copyright (C) 2004 Peter Miller; # All rights reserved. # # As a specific exception to the GPL, you are allowed to copy # this source file into your own project and modify it, without # releasing your project under the GPL, unless there is some other # file or condition which would require it. # # MANIFEST: shell script to commit changes to Subversion # # This script is expected to be run by the integrate_pass_notify_command # and as such the baseline has already assumed the shape asked for by # the change. # # integrate_pass_notify_command = # "$bin/ae-svn-ci $project $change http://svn.site.com/svn/trunk --username svn_user"; # # Alternatively, you may wish to tailor this script to the individual # needs of your project. Make it a source file, e.g. "etc/ae-svn-ci.sh" # and then use the following: # # integrate_pass_notify_command = # "$sh ${s etc/ae-svn-ci} $project $change http://svn.site.com/svn/trunk --username svn_user"; # USAGE="Usage: $0 [-hnq] []" PRINT="echo" EXECUTE="eval" while getopts "hnq" FLAG do case ${FLAG} in h ) echo "${USAGE}" exit 0 ;; n ) EXECUTE=":" ;; q ) PRINT=":" ;; * ) echo "$0: unknown option ${FLAG}" >&2 exit 1 ;; esac done shift `expr ${OPTIND} - 1` case $# in [012]) echo "${USAGE}" 1>&2 exit 1 ;; *) project=$1 change=$2 svn_url=$3 shift 3 svn_co_flags=$* ;; esac here=`pwd` AEGIS_PROJECT=$project export AEGIS_PROJECT AEGIS_CHANGE=$change export AEGIS_CHANGE module=`echo $project | sed 's|[.].*||'` baseline=`aegis -cd -bl` if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi TMP=${TMPDIR}/ae-svn-ci.$$ mkdir ${TMP} cd ${TMP} PWD=`pwd` if test X${PWD} != X${TMP}; then echo "$0: ended up in ${PWD}, not ${TMP}" >&2 exit 1 fi fail() { set +x cd $here rm -rf ${TMP} echo "FAILED" 1>&2 exit 1 } trap "fail" 1 2 3 15 Command() { ${PRINT} "$*" ${EXECUTE} "$*" } # # Create a new Subversion work area. # # Note: this assumes the module is checked-out into a directory of the # same name. Is there a way to ask Subversion where it is going to put a # module, so we can always get the "cd" right? # ${PRINT} svn co $svn_url $module $svn_co_flags ${EXECUTE} svn co $svn_url $module $svn_co_flags > LOG 2>&1 if test $? -ne 0; then cat LOG; fail; fi ${EXECUTE} cd $module # # Now we need to extract the sources from Aegis and drop them into the # Subversion work area. There are two ways to do this. # # The first way is to use the generated tarball. # This has the advantage that it has the Makefile.in file in it, and # will work immediately. # # The second way is to use aetar, which will give exact sources, and # omit all derived files. This will *not* include the Makefile.in, # and so will not be readily compilable. # # gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - aetar -send -comp-alg=gzip -o - | tar xzf - # # If any new directories have been created we will need to add them # to Subversion before we can add the new files which we know are in them, # or they would not have been created. Do this only if the -n option # isn't used, because if it is, we won't have actually checked out the # source and we'd erroneously report that all of them need to be added. # if test "X${EXECUTE}" != "X:" then find . -name .svn -prune -o -type d -print | xargs --max-args=1 | while read dir do if [ ! -d "$dir/.svn" ] then Command svn add -N "$dir" fi done fi # # Use the Aegis meta-data to perform some commands that Subversion can't # figure out for itself. We use an inline "aer" report script to identify # when a remove-create pair are actually due to a move. # aegis -rpt -nph -f - <<_EOF_ | auto cs; cs = project[project_name()].state.branch.change[change_number()]; columns({width = 1000;}); auto file, moved; for (file in cs.src) { if (file.move != "") moved[file.move] = 1; } auto action; for (file in cs.src) { if (file.action == "remove" && file.move != "") action = "move"; else action = file.action; /* * Suppress printing of any files created as the result of a move. * These are printed as the destination when printing the line for * the file that was *removed* as a result of the move. */ if (action != "create" || ! moved[file.file_name]) print(sprintf("%s %s \\"%s\\" \\"%s\\"", file.usage, action, file.file_name, file.move)); } _EOF_ while read line do eval set -- "$line" usage="$1" action="$2" srcfile="$3" dstfile="$4" case $action in create) Command svn add $srcfile ;; remove) Command rm -f $srcfile Command svn remove $srcfile ;; move) Command mv $dstfile $dstfile.move Command svn move $srcfile $dstfile Command cp $dstfile.move $dstfile Command rm -f $dstfile.move ;; *) ;; esac done # # Extract the brief description. We'd like to do this using aesub # or something, like so: # # message=`aesub '${version} - ${change description}'` # # but the expansion of ${change description} has a lame hard-coded max of # 80 characters, so we have to do this by hand. (This has the slight # benefit of preserving backslashes in front of any double-quotes in # the text; that will have to be handled if we go back to using aesub.) # description=`aegis -ca -l | sed -n 's/brief_description = "\(.*\)";$/\1/p'` version=`aesub '${version}'` message="$version - $description" # # Now commit all the changes. # Command svn commit -m \"$message\" # # All done. Clean up and go home. # cd $here rm -rf ${TMP} exit 0