#! /bin/sh # # Cut a snapshot of a module in CVS # # Example Invocations: # # TBD # usage() { echo "$0 [options]" echo " options:" echo " -c release -- current release (required)" echo " -p release -- previous release (NA == none)" echo " -m module -- CVS module name (required)" echo " -r release_name -- base of release image name" echo " -d directory -- release directory (required)" echo " -z -- use gzip not bzip2 for archives" echo " -V -- generate file Version report" echo " -v -- be verbose" echo echo "Must be run from top level directory of checked out source." echo exit 1 } fatal() { echo $* usage } previous=NA current=NOT_SET reldir_base=NOT_SET module_name=NOT_SET release_name=NOT_SET verbose=no zipper=bzip2 unzipper=bunzip2 zext=bz2 do_version_report=no while test $# -ge 1; do case $1 in -c) shift ; current=$1 ;; -p) shift ; previous=$1 ;; -m) shift ; module_name=$1 ;; -r) shift ; release_name=$1 ;; -d) shift ; reldir_base=$1 ;; -z) zipper=gzip ; unzipper=gunzip ; zext=gz ;; -V) do_version_report=yes ;; -v) verbose=yes ;; *) fatal "invalid option $1" ;; esac shift done if test ${module_name} = NOT_SET ; then grep "/" CVS/Repository >/dev/null if test $? -eq 0 ; then fatal "Module name not specified." fi module_name=`cat CVS/Repository` fi if test ${reldir_base} = NOT_SET ; then reldir_base=/home/releases/${module_name} if test ! -d ${reldir_base} ; then fatal "Release directory not specified and ${reldir_base} does not exist." fi module_name=`cat CVS/Repository` else if test ! -d ${reldir_base} ; then fatal "Release directory (${reldir_base}) does not exist." fi fi if test ${verbose} = yes ; then echo "===========================================" echo "Current Release :" ${current} echo "Previous Release :" ${previous} echo "Module Name :" ${module_name} echo "Release Base Name :" ${release_name} echo "Release Directory :" ${reldir_base} echo "Compression :" ${zipper} ${unzipper} ${zext} echo "Generate Version Report :" ${do_version_report} echo "===========================================" exit 0 fi # Now check the arguments if test ${current} = NOT_SET ; then fatal "Current release not specified." fi if test ${release_name} = NOT_SET ; then echo "Using module_name (${module_name}) as release name.". release_name=${module_name} fi ##### setup some directory assumptions reldir_prev=${reldir_base}/${previous} reldir_curr=${reldir_base}/${current} export_dir=${reldir_base}/export base=`pwd` cvs_root=`cat ${base}/CVS/Root` cvs_repository=`cat ${base}/CVS/Repository` cvs_module=`basename ${cvs_repository}` # Make sure we are at the top of a checked out tree if [ "${cvs_module}"X != "${module_name}"X ] ; then echo You do not appear to be in the top level of a checked out ${module_name} tree exit 1 fi # Test if we generate diffs and the old release is there. if [ ${previous} != "NA" ] ; then if [ ! -d ${reldir_prev} ] ; then echo Previous release ${previous} not found exit 1 fi fi # Check that the export directory exists test -d ${export_dir} || mkdir ${export_dir} # turn the version string into a valid cvs tag mk_version_tag() { echo ${release_name}-${1} | tr "." "-" } current_tag=`mk_version_tag ${current}` previous_tag=`mk_version_tag ${previous}` if [ ${previous} != "NA" ] ; then echo Using $previous_tag as the tag for the previous version else echo No previous version fi echo Using $current_tag as the tag for the current version # Changing the version string cd ${base} Pname=${module} if test -x ${base}/release_support ; then Pname=`${base}/release_support name` test $? -ne 0 && (echo "release support (name) script failed." ; exit 1) fi # make sure certain special files are there prior to a release if [ ! -r VERSION -o ! -r SUPPORT ] ; then echo Error unable to find VERSION or SUPPORT in the working tree. exit 1 fi # We often need to know who is cutting the release if test "X${LOGNAME}" = "X" ; then echo "LOGNAME not set" usage fi user_name=`grep ^$LOGNAME /etc/passwd | cut -d':' -f5 | cut -d',' -f1` # If you don't have user information, then we won't commit anything. if test "X${user_name}" = "X" ; then echo "User information not set" usage fi # before we tag anything make sure it hasn't previously been exported if [ -d ${export_dir}/${release_name}-${current} ] ; then echo You must have run this before. echo Removing ${release_name}-${current} rm -rf ${export_dir}/${release_name}-${current} fi # This is where the module has the opportunity to do actions before we tag. if test -x ${base}/release_support ; then ${base}/release_support pretag ${release_name} ${current} test $? -ne 0 && (echo "release support (pretag) script failed." ; exit 1) fi # # Whether or not there were special considerations, there might be a # version file. # version_file=VERSION if [ -r ${version_file} ] ; then if test "X${user_name}" = "X" ; then echo "ERROR: User information not set in password file" usage fi ( echo "#" ; echo "# This file is automatically generated -- DO NOT EDIT!!!" ; echo "#" ; echo "# \$Id\$" ; echo "#" ; echo ; echo ${Pname} "Version ${current}" ) >$version_file ( echo `date +"%Y-%m-%d"`" ${user_name}" ; echo ; echo " * ${version_file}: Updated to ${release_name}-${current}." ; echo ) >YYY if [ -r ChangeLog ] ; then cat YYY ChangeLog >XXX mv XXX ChangeLog cvs -d ${cvs_root} commit -F YYY ChangeLog ${version_file} rm -f YYY else cvs -d ${cvs_root} commit -m \ "changed version to ${current}" ${version_file} fi fi # tag the current source cd ${base} cvs -d ${cvs_root} tag ${current_tag} `grep -v "^D$" CVS/Entries | cut -d'/' -f2` if test $? -ne 0 ; then echo Unable to tag source exit 1 fi # export the current source cd ${export_dir} cvs -d ${cvs_root} export -r ${current_tag} -d ${release_name}-${current} ${module_name} if test $? -ne 0 ; then echo Unable to export source exit 1 fi # Now start dealing with the exported source cd ${release_name}-${current} #if [ ! -r VERSION -o ! -r SUPPORT ] ; then # echo Error unable to find VERSION or SUPPORT in the exported tree. # exit 1 #fi # This is where the module has the opportunity to do actions after we export. if test -x ${base}/release_support ; then ${base}/release_support postexport test $? -ne 0 && (echo "release support (postexport) script failed." ; exit 1) fi # cut the release files test -d ${reldir_curr} || mkdir ${reldir_curr} # Generate tar and compress it. cd .. tar cf ${reldir_curr}/${release_name}-${current}.tar ${release_name}-${current} ${zipper} ${reldir_curr}/${release_name}-${current}.tar # generate diffs if requested if [ ${previous} != "NA" ] ; then if [ -r ${reldir_prev}/${release_name}-${previous}.tgz ] ; then tar xzf ${reldir_prev}/${release_name}-${previous}.tgz fi if [ -r ${reldir_prev}/${release_name}-${previous}.tar.gz ] ; then tar xzf ${reldir_prev}/${release_name}-${previous}.tar.gz fi if [ -r ${reldir_prev}/${release_name}-${previous}.tar.bz2 ] ; then bzcat ${reldir_prev}/${release_name}-${previous}.tar.bz2 | tar xf - fi diff -N -P -r -u ${release_name}-${previous} ${release_name}-${current} \ >${reldir_curr}/${release_name}-${previous}-${current}.diff ls -l ${reldir_curr}/${release_name}-${previous}-${current}.diff ${zipper} ${reldir_curr}/${release_name}-${previous}-${current}.diff ls -l ${reldir_curr}/${release_name}-${previous}-${current}.diff.${zext} fi # This is where the module has the opportunity to do actions after # the tarball is made. This can be used to capture host information, # sign the tarball, etc. # # NOTE: The contents are virgin before this is executed and it is OK # if the script generates files in the tree. This is commonly # where documentation might be automatically generated. cd ${release_name}-${current} if test -x ${base}/release_support ; then ${base}/release_support after_tar ${current} ${reldir_curr} fi # generate a ChangeLog difference # # NOTE: Removes ALL files not named ChangeLog. Export directory is # useless past this point. cd .. if [ ${previous} != "NA" ] ; then if [ -r ${release_name}-${current}/ChangeLog ] ; then find ${release_name}-${previous} ${release_name}-${current} -type f | \ grep -v ChangeLog | xargs -e rm -rf diff -N -P -r -c ${release_name}-${previous} ${release_name}-${current} \ >${reldir_curr}/${release_name}-ChangeLog-${previous}-${current}.diff fi fi # generate the version report cd ${base} if [ ${do_version_report} = yes ] ; then # trace output from here down is EXTREMEMLY noisy set +x find . -type d -name "CVS" | while read d do D=`dirname $d` cat $d/Entries | grep -v ^D | while read entry do # echo $entry file=`echo $entry | cut -d'/' -f2` ffile=`echo $D/$file | sed -e 's/^\.\///'` version=`echo $entry | cut -d'/' -f3` modified=`echo $entry | cut -d'/' -f4` # printf "%s\t%s\t%s\n" $D/$file $version "$modified" printf "%s\t%s\t%s\n" $version "$modified" $ffile done done >${reldir_curr}/${release_name}-${current}-FILES fi # generate md5 checksums cd ${reldir_curr} find `pwd` -type d | while read d do cd $d rm -f md5sum.txt files=`find . -maxdepth 1 -type f | wc -l` if [ ${files} -eq 0 ] ; then echo $d is empty so no checksum generated else echo Checksum generated for $d md5sum `find . -maxdepth 1 -type f` >md5sum.txt fi done # remove the exported source to save space rm -rf ${export_dir} echo ${reldir_curr}/${release_name}-${current}.tar* exit 0