#!/usr/bin/ksh
#
# NAME: release.complete -f family -r releaseName
#       Where: family      is the CMVC family name.
#              releaseName is the active CMVC release.
# NOTES: 
#   * This script must be run by a SUPERUSER.
#
# PURPOSE:
#   To ensure that all the objects related to a release
#   such as tracks, approval records, fix records, test
#   records and levels are completed.
#   This script finds out the processes that are used
#   by the release, and then it will do:
#
#   * If the track subprocess is used, then it will 
#     try to integrate the Tracks in fixed state.
#
#   * If the approval subprocess is used, then it will
#     try to delete any Approval records in ready state.
#
#   * If the fix subprocess is used, then it will 
#     try to complete any Fix records in active or ready state.
#
#   * If the level subprocess is used, then it will 
#     try to remove any level members of uncommitted levels,
#     remove uncommitted levels, and create a "cleanup" level
#     to process all the remaining tracks in integrate state,
#     and commit and complete this level; finally, it tries
#     to complete any levels in committed state.
#
#   * If the test subprocess is used, then it will 
#     try to abstain any Test records in ready state.
#
# AUXILIARY FILES:
#  This script generates 2 files, one that has the details
#  of the processing, and another of the commands that failed.
#
# 5765-207 (C) COPYRIGHT International Business Machines Corp. 1993,1999
# 5765-202 (C) COPYRIGHT International Business Machines Corp. 1993,1999
# 5765-397 (C) COPYRIGHT International Business Machines Corp. 1994,1999
# All Rights Reserved
# Licensed Materials - Property of IBM
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
#           NOTICE TO USERS OF THE SOURCE CODE EXAMPLES
#
# INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THE SOURCE CODE
# EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, "AS IS" WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
# OF THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS,
# IS WITH YOU.  SHOULD ANY PART OF THE SOURCE CODE EXAMPLES PROVE
# DEFECTIVE, YOU (AND NOT IBM OR AN AUTHORIZED RISC System/6000* WORKSTATION
# DEALER) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR
# CORRECTION.
#
# * RISC System/6000 is a trademark of International Business Machines
#   Corporation.
#
# /usr/lpp/cmvc/samples/release.complete

#####################################################################

################################################################################
function usage
{
	print -u2 "USAGE: ${PROG} -f <FAMILY> -r <RELEASENAME>"
	print -u2 "WHERE: FAMILY      is the CMVC family to process"
	print -u2 "       RELEASENAME is the active CMVC release"
	print -u2 "NOTE : script must be run by a SUPERUSER"
	exit 1
}
################################################################################
function initialize
{
	RC=0
	if [ -z "${FAMILY}" ]
	  then	print -u2 "<<ERROR>> FAMILY name required"
		RC=1
	  else	CMVC_FAMILY=${FAMILY}
	fi
	WHOAMI=`id -u -n`
	SUPERUSER=`Report -view users -wh "login = '${WHOAMI}' AND superuser = 'yes'" -raw`
	if [ -z "${SUPERUSER}" ]
	  then	print -u2 "<<ERROR>> LOGIN invalid or not SUPERUSER"
		RC=1
	fi
	if [ -z "${RELEASE}" ]
	  then	print -u2 "<<ERROR>> RELEASE name required"
		RC=1
	  else	PROCESS=`Report -view releaseview -wh "dropdate is null AND name = '${RELEASE}'" -raw | cut -d\| -f3`
		if [ -z "${PROCESS}" ]
		  then	print -u2 "<<ERROR>>  RELEASE name INVALID or deleted"
			RC=1
		  else	SUBPROCESSES="none track approval fix level test"
		fi
	fi
	OUTFILE=/tmp/outfile.$$
	print "Completing release: ${RELEASE}" >${OUTFILE}
	BADFILE=/tmp/badfile.$$
}
################################################################################
function crank
{
	print "${cmd}" >>${OUTFILE}
	print "           ${cmd}"
	eval ${cmd} 2>/dev/null
	if [ $? -ne 0 ]  && [ "${PROCESS}" != "track" ]
	  then	print "${cmd}" >>${BADFILE}
	fi
}
################################################################################
function process_tracks
{
	# integrate tracks if possible
	print "<<STATUS>> processing tracks"
	Report -view trackview -where "releasename = '${RELEASE}' AND state = 'fix'" -raw |
	while read record
	  do
		defect=`print ${record} | cut -d\| -f2`
		cmd="Track -integrate -defect ${defect} -release ${RELEASE}"
		crank
	  done
}
################################################################################
function process_approvals
{
	# delete any approval records that have not been processed (state ready)
	print "<<STATUS>> processing approval records"
	Report -view approvalview -wh "releasename = '${RELEASE}' AND state = 'ready'" -raw |
	while read record
	  do
		defect=`print ${record} | cut -d\| -f2`
		approver=`print ${record} | cut -d\| -f4`
		cmd="Approval -delete -defect ${defect} -release ${RELEASE}"
		cmd="${cmd} -approver ${approver}"
		crank
	  done
}
################################################################################
function process_fixes
{
	# complete fix records that have associated work (state active/ready)
	print "<<STATUS>> processing fix records"
	Report -view fixview -wh "releasename = '${RELEASE}' AND state in ('active','ready')" -raw |
	while read record
	  do
		defect=`print ${record} | cut -d\| -f1`
		component=`print ${record} | cut -d\| -f3`
		cmd="Fix -complete -defect ${defect} -release ${RELEASE}"
		cmd="${cmd} -component ${component}"
		crank
	  done
}
################################################################################
function process_levels
{
	# remove levelmembers of uncommitted levels
	print "<<STATUS>> processing levelmembers"
	Report -view levelmemberview -wh "releasename = '${RELEASE}' AND levelname in (select name from levelview where commitdate is null)"   \
	 -raw | 
	while read record
	  do
		level=`print ${record} | cut -d\| -f1`
		defect=`print ${record} | cut -d\| -f3`
		cmd="LevelMember -delete -defect ${defect} -release ${RELEASE}"
		cmd="${cmd} -level ${level}"
		crank
	  done
	# remove uncommitted levels
	print "<<STATUS>> processing levels that are not needed"
	Report -view levelview -wh "releasename = '${RELEASE}' AND commitdate is NULL" -raw |
	while read record
	  do
		level=`print ${record} | cut -d\| -f1`
		cmd="Level -delete ${level} -release ${RELEASE}"
		crank
	  done
	# one biggie
	print "<<STATUS>> processing a cleanup level"
	LEVEL=`date "+%y%m%d"s`
	TYPE=`Report -view config -wh "type = 'leveltype'" -raw | head -1 | cut -d\| -f2`
	cmd="Level -create ${LEVEL} -release ${RELEASE} -type ${TYPE}"
	crank
	print "<<STATUS>> processing the cleanup levelmembers"
	Report -view trackview -wh "releasename = '${RELEASE}' AND state = 'integrate'" -raw |
	while read record
	  do
		defect=`print ${record} | cut -d\| -f2`
		cmd="LevelMember -create -level ${LEVEL} -release ${RELEASE}"
		cmd="${cmd} -defect ${defect}"
		crank
	  done
	print "<<STATUS>> processing the cleanup level commit"
	cmd="Level -commit ${LEVEL} -release ${RELEASE}"
	crank
	# commit to complete
	print "<<STATUS>> processing levels to be completed"
	Report -view levelview -wh "releasename = '${RELEASE}' AND state = 'commit'" -raw |
	while read record
	  do
		level=`print ${record} | cut -d\| -f1`
		cmd="Level -complete ${level} -release ${RELEASE}"
		crank
	  done
}
################################################################################
function process_test
{
	# abstain from all unprocessed test records (state ready)
	print "<<STATUS>> processing test recordss"
	Report -view testview -wh "releasename = '${RELEASE}' AND state = 'ready'" -raw |
	while read record
	  do
		defect=`print ${record} | cut -d\| -f3`
		environment=`print ${record} | cut -d\| -f4`
		tester=`print ${record} | cut -d\| -f8`
		cmd="Test -abstain -defect ${defect} -release ${RELEASE}"
		cmd="${cmd} -tester ${tester} -environment ${environment}"
		crank
	  done
}
################################################################################
function process
{
        print "Trying to complete the release: ${RELEASE}"
        print "Please take a look at the following files for more details:"
	print "OUTPUT FILE (lists all CMVC commands issued): ${OUTFILE}"
	print "FAILED CMDS (lists all failed CMVC commands): ${BADFILE}"
	for PROCESS in ${SUBPROCESSES}
	  do
		case "${PROCESS}" in
		  none)		;;
		  approval)	process_approvals
				;;
		  fix)		process_fixes
				;;
		  track)	process_tracks
					;;
		  level)	process_levels
				;;
		  test)		process_test
				;;
		esac
	  done
        print ""
        print "Please take a look at the following files for more details:"
	print "OUTPUT FILE (lists all CMVC commands issued): ${OUTFILE}"
	print "FAILED CMDS (lists all failed CMVC commands): ${BADFILE}"
        print "Done!"
}
################################################################################
# main processing
PROG=${0##*/}
while getopts :f:r: argument
  do
	case "${argument}" in
	  f)	FAMILY=${OPTARG}
	  	;;
	  r)	RELEASE=${OPTARG}
	  	;;
	  \?)	usage
		;;
	esac
  done
initialize
if [ "${RC}" -eq "0" ]
  then	process
  else	usage
fi

# end of file
