dist.sh #6

  • //
  • guest/
  • perforce_software/
  • sdp/
  • tools/
  • dist.sh
  • View
  • Commits
  • Open Download .zip Download (14 KB)
#!/bin/bash
#------------------------------------------------------------------------------
# Copyright (c) Perforce Software, Inc., 2007-2014. All rights reserved
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1  Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE
# SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#------------------------------------------------------------------------------

#==============================================================================
# Declarations and Environment

# Allow override of P4U_HOME, which is set only when testing P4U scripts.
export P4U_HOME=${P4U_HOME:-/p4/common/bin}
export P4U_LIB=${P4U_LIB:-/p4/common/lib}
export P4U_ENV=$P4U_LIB/p4u_env.sh
export P4U_LOG="/tmp/dist.$(date +'%Y%m%d-%H%M%S').log"

# Environment isolation.  For stability and security reasons, prepend
# PATH to include dirs where known-good scripts exist.
# known/tested PATH and, by implication, executables on the PATH.
export PATH=$P4U_HOME:$PATH:~/bin:.
export P4CONFIG=${P4CONFIG:-.p4config}

[[ -r "$P4U_ENV" ]] || {
   echo -e "\nError: Cannot load environment from: $P4U_ENV\n\n"
   exit 1
}

source $P4U_ENV
source $P4U_LIB/libcore.sh
source $P4U_LIB/libp4u.sh
export VERBOSITY=3

declare Version=1.2.0
declare -i SilentMode=0
declare AppHome=${PWD%/*}
declare ExcludesCfg=$AppHome/tools/excludes.dist.cfg
declare CommonFilesList=$AppHome/tools/common_files.txt

#==============================================================================
# Local Functions

#------------------------------------------------------------------------------
# Function: terminate
function terminate
{
   # Disable signal trapping.
   trap - EXIT SIGINT SIGTERM

   # Don't litter.
   cleanTrash

   vvmsg "$THISSCRIPT: EXITCODE: $OverallReturnStatus"

   # Stop logging.
   [[ "${P4U_LOG}" == off ]] || stoplog

   # With the trap removed, exit.
   exit $OverallReturnStatus
}

#------------------------------------------------------------------------------
# Function: usage (required function)
#
# Input:
# $1 - style, either -h (for short form) or -man (for man-page like format).
#------------------------------------------------------------------------------
function usage
{
   declare style=${1:--h}

   echo "USAGE for $THISSCRIPT v$Version:

$THISSCRIPT [-f] [-s] [-L <log>] [-si] [-v<n>] [-n] [-D]

or

$THISSCRIPT [-h|-man]
"
   if [[ $style == -man ]]; then
      echo -e "
DESCRIPTION:
	Create an SDP distribution tar file from the latest
	files in the main branch.

	An exclusion config file defines files and directories
	to be excluded from packaging.  This exclusion config
	file has file name per line, which may include the
	'*' wild car.

	The exclusion config file can also specify
	directories to be excluded, which start with a 'D:'
	prefix.

	The exclusion config file is:
	$ExcludesCfg

OPTIONS:
 -f	Force creation of target tar/zip file, replacing an existing
	one if necessary.  The default behavior is to abort if
	the target tar file already exists.

 -o	Proceed even if files are opened in Perforce and/or not synced
  to the head revision.  This may be useful for testing purposes.

	By default, we abort if any files are checked out, or if files
  are not syncd to the head revision.  This option is not suitable
  for creating a distribution file that will be submitted.

 -s	Show tar file contents using 'tar -tzf'.

 -v<n>	Set verbosity 1-5 (-v1 = quiet, -v5 = highest).

 -L <log>
	Specify the path to a log file, or the special value 'off' to disable
	logging.  By default, all output (stdout and stderr) goes to:
	$(dirname ${P4U_LOG}).

	NOTE: This script is self-logging.  That is, output displayed on the screen
	is simultaneously captured in the log file.  Do not run this script with
	redirection operators like '> log' or '2>&1', and do not use 'tee.'

-si	Operate silently.  All output (stdout and stderr) is redirected to the log
	only; no output appears on the terminal.  This cannot be used with
	'-L off'.
      
 -n	No-Op.  Prints commands instead of running them.

 -D     Set extreme debugging verbosity.

HELP OPTIONS:
 -h	Display short help message
 -man	Display man-style help message

FILES:

EXAMPLES:

SEE ALSO:
"
   fi

   exit 1
}

#==============================================================================
# Command Line Processing

declare -i shiftArgs=0
declare SDPUnixVersion=
declare -i ForceTarCreation=0
declare -i AllowOpenedFiles=0
declare -i ShowTarContents=0
declare TarFile=

set +u
while [[ $# -gt 0 ]]; do
   case $1 in
      (-f) ForceTarCreation=1;;
      (-o) AllowOpenedFiles=1;;
      (-s) ShowTarContents=1;;
      (-h) usage -h;;
      (-man) usage -man;;
      (-v1) export VERBOSITY=1;;
      (-v2) export VERBOSITY=2;;
      (-v3) export VERBOSITY=3;;
      (-v4) export VERBOSITY=4;;
      (-v5) export VERBOSITY=5;;
      (-L) export P4U_LOG=$2; shiftArgs=1;;
      (-si) SilentMode=1;;
      (-n) export NO_OP=1;;
      (-D) set -x;; # Debug; use 'set -x' mode.
      (*) usageError "Unknown arg ($1).";;
   esac

   # Shift (modify $#) the appropriate number of times.
   shift; while [[ $shiftArgs -gt 0 ]]; do
      [[ $# -eq 0 ]] && usageError "Bad usage."
      shiftArgs=$shiftArgs-1
      shift
   done
done
set -u

#==============================================================================
# Command Line Verification

[[ $SilentMode -eq 1 && $P4U_LOG == off ]] && \
   usageError "Cannot use '-si' with '-L off'."

#==============================================================================
# Main Program

trap terminate EXIT SIGINT SIGTERM

declare -i OverallReturnStatus=0

if [[ "${P4U_LOG}" != off ]]; then
   touch ${P4U_LOG} || bail "Couldn't touch log file [${P4U_LOG}]."

   # Redirect stdout and stderr to a log file.
   if [[ $SilentMode -eq 0 ]]; then
      exec > >(tee ${P4U_LOG})
      exec 2>&1
   else
      exec >${P4U_LOG}
      exec 2>&1
   fi

   initlog
fi

SDPVersion=$(cat ../main/Version|cut -d '/' -f 3).$(cat ../main/Version|cut -d '/' -f 4|cut -d ' ' -f 1)
SDPVersion=$(echo $SDPVersion)
SDPUnixVersion=sdp.Unix.$SDPVersion
SDPWindowsVersion=sdp.Windows.$SDPVersion
TarFile=$AppHome/dist/$SDPUnixVersion.tgz
ZipFile=$AppHome/dist/$SDPWindowsVersion.zip
UnixWorkingDir=/tmp/$SDPUnixVersion
WindowsWorkingDir=/tmp/$SDPWindowsVersion

runCmd "p4 -ztag -F %TicketExpiration% login -s" \
   "Checking login status."

if [[ -n "$CMDOUTPUT" ]]; then
   msg "Verified: Logged into Perforce."
else
   bail "Not logged into Perforce."
fi

runCmd "p4 -F %depotFile% -ztag opened ../main/..." \
   "Checking for opened files in main."

if [[ -n "$CMDOUTPUT" ]]; then
   if [[ $AllowOpenedFiles -eq 1 ]]; then
      msg "Proceeding despite opened files being detected, due to -o flag."
   else
      if [[ $CMDOUTPUT == *"//"* ]]; then
         bail "These files are checked out in main:\n$CMDOUTPUT\n\nAborting."
      else
         bail "Could not determine if files are checked out in main. Output was:\n$CMDOUTPUT\n\nAborting."
      fi
   fi
else
   msg "Verified: No files checked out in SDP main."
fi

runCmd "p4 -F %depotFile% -ztag sync -n ../..." \
   "Checking for unsynced SDP files."

if [[ -n "$CMDOUTPUT" ]]; then
   if [[ $AllowOpenedFiles -eq 1 ]]; then
      msg "Proceeding despite unsynced files, due to -o flag."
   else
      if [[ $CMDOUTPUT == *"//"* ]]; then
         bail "These files need to be synced:\n$CMDOUTPUT\n\nAborting."
      else
         bail "Could not determine if files need to be synced. Output was:\n$CMDOUTPUT\n\nAborting."
      fi
   fi
else
   msg "Verified: No unsynced SDP files."
fi

msg "AppHome=[$AppHome] TF=[$TarFile] ZF=[$ZipFile] UWD=[$UnixWorkingDir] WWD=[$WindowsWorkingDir]."

if [[ -r $TarFile ]]; then
   if [[ $ForceTarCreation -eq 1 ]]; then
      runCmd "/bin/rm -f $TarFile" \
         "Removing existing tar file [$TarFile] due to '-f'." ||\
            bail "Failed to remove existing tar file [$TarFile].  Aborting."
   else
      bail "Tar file already exists: [$TarFile].  Use '-f' to forcibly replace.  Aborting."
   fi
fi

if [[ -r $ZipFile ]]; then
   if [[ $ForceTarCreation -eq 1 ]]; then
      runCmd "/bin/rm -f $ZipFile" \
         "Removing existing zip file [$ZipFile] due to '-f'." ||\
            bail "Failed to remove existing zip file [$ZipFile].  Aborting."
   else
      bail "Zip file already exists: [$ZipFile].  Use '-f' to forcibly replace.  Aborting."
   fi
fi

msg "Creating working directories."
for workingDir in $UnixWorkingDir $WindowsWorkingDir; do
   if [[ -d "$workingDir" ]]; then
      runCmd "/bin/rm -rf $workingDir" \
         "Removing old working dir [$workingDir]." ||\
         bail "Failed to remove old working dir [$workingDir]. Aborting."
   fi

   runCmd "/bin/mkdir -p $workingDir" "Initializing working dir [$workingDir]." 0 ||\
      bail "Failed to create empty working dir [$workingDir]. Aborting."
done

#------------------------------------------------------------------------------
# Unix *.tgz file.
SDPRoot="$UnixWorkingDir/sdp"

runCmd "/bin/cp -pr ${AppHome}/main $SDPRoot" \
   "Copying SDP package to Unix working dir." 0 ||\
   bail "The copy to the working dir failed.  Aborting."

cd "$SDPRoot" || bail "Failed to cd to sdp root in Working Dir [$SDPRoot]."

if [[ -r "$ExcludesCfg" ]]; then
   while read excludeFile; do
      [[ "$excludeFile" == "" || "$excludeFile" == "#"* ]] && continue
      if [[ "$excludeFile" == "D:"* ]]; then
         excludeDir=${excludeFile#D:}
         msg "/usr/bin/find $SDPRoot -type d -name \"$excludeDir\" -print -exec /bin/rm -r -f {} \\;"
         /usr/bin/find $SDPRoot -type d -name "$excludeDir" -print -exec /bin/rm -r -f {} \;
      else
         msg "/usr/bin/find $SDPRoot -type f -name \"$excludeFile\" -print -exec /bin/rm -f {} \\;"
         /usr/bin/find $SDPRoot -type f -name "$excludeFile" -print -exec /bin/rm -f {} \;
      fi
   done < $ExcludesCfg
fi

cd "$UnixWorkingDir" || bail "Failed to cd to Working Dir [$UnixWorkingDir]."

runCmd "/usr/bin/tar -czf $TarFile sdp" ||\
   bail "Failed to create tar file [$TarFile]. Aborting."
#------------------------------------------------------------------------------
# Windows *.zip file.
SDPRoot="$WindowsWorkingDir/sdp"

runCmd "/bin/cp -pr ${AppHome}/main $SDPRoot" \
   "Copying SDP package to Windows working dir." 0 ||\
   bail "The copy to the working dir failed.  Aborting."

cd "$SDPRoot" || bail "Failed to cd to sdp root in Working Dir [$SDPRoot]."

if [[ -r "$ExcludesCfg" ]]; then
   while read excludeFile; do
      [[ "$excludeFile" == "" || "$excludeFile" == "#"* ]] && continue
      # For Windows, exclude Unix stuff in places where Windows would otherwise be excluded.
      excludeFile=$(echo $excludeFile|sed "s:Windows:Unix:g")
      if [[ "$excludeFile" == "D:"* ]]; then
         excludeDir=${excludeFile#D:}
         msg "/usr/bin/find $SDPRoot -type d -name \"$excludeDir\" -print -exec /bin/rm -r -f {} \\;"
         /usr/bin/find $SDPRoot -type d -name "$excludeDir" -print -exec /bin/rm -r -f {} \;
      else
         msg "/usr/bin/find $SDPRoot -type f -name \"$excludeFile\" -print -exec /bin/rm -f {} \\;"
         /usr/bin/find $SDPRoot -type f -name "$excludeFile" -print -exec /bin/rm -f {} \;
      fi
   done < $ExcludesCfg
fi

cd "$WindowsWorkingDir" || bail "Failed to cd to Working Dir [$WindowsWorkingDir]."

# Copy common files.
if [[ -r "$CommonFilesList" ]]; then
   while read srcFileSpec; do
      [[ "$srcFileSpec" == "" || "$srcFileSpec" == "#"* ]] && continue
      # Prefix Unix working dir to relative path specified in the Common Files List file.
      srcFileSpec=$UnixWorkingDir/sdp/$srcFileSpec
      tgtDir=$(echo "$srcFileSpec" | sed "s:Unix:Windows:g")
      msg "SFS=[$srcFileSpec] TD=[$tgtDir]"
      tgtDir=${tgtDir%\*}
      msg "TD2=[$tgtDir]"
      tgtDir=${tgtDir%\/*}
      msg "TD3=[$tgtDir]"
      for srcFile in $srcFileSpec; do
         msg "Copying [$srcFile] to [$tgtDir]."
         /bin/cp -p "$srcFile" "$tgtDir" ||\
            bail "Failure performing copy of common files. Aborting."
      done
   done < $CommonFilesList
else
   warnmsg "Skipping copy of common files from Unix to Windows, due to missing common files list [$CommonFilesList]."
   OverallReturnStatus=1
fi

# Convert ASCII text files to Windows line endings before packaging.
for textFile in $(/usr/bin/find . -type f -print | xargs file | egrep -i '(ascii|text)'| cut -d: -f1); do
   convertedTextFile=.tmp.converted
   /usr/bin/awk 'sub("$", "\r")' $textFile > $convertedTextFile
   /bin/mv -f "$convertedTextFile" "$textFile"
done

runCmd "/usr/bin/zip -r $ZipFile sdp" ||\
   bail "Failed to create tar file [$ZipFile]. Aborting."

if [[ $ShowTarContents -eq 1 ]]; then
   runCmd "/usr/bin/tar -tzf $TarFile" \
      "Tar file [$TarFile] contains these elements:"
fi

if [[ $OverallReturnStatus -eq 0 ]]; then
   msg "${H}\nAll processing completed successfully.\n"
else
   msg "${H}\nProcessing completed, but with errors.  Scan above output carefully.\n" 
fi

# Illustrate using $SECONDS to display runtime of a script.
msg "That took about $(($SECONDS/3600)) hours $(($SECONDS%3600/60)) minutes $(($SECONDS%60)) seconds.\n"

# See the terminate() function, which is really where this script exits.
exit $OverallReturnStatus
# Change User Description Committed
#10 16339 C. Thomas Tyler Adjusted to use 'downloads' rather than 'dist'.

Enhanced docs.

Fixed bug where script failed if 'downloads' directory
didn't already exist.

Removed '-s' (show tarfile contents) flag, and made
showing contents the default behavior (thus making it
behavve the same for UNIX/Linux and Windows, which
always shows *.zip file contents.).
#9 12391 C. Thomas Tyler Fixed cosmetic typos in comments and output.
Fixed bug that preventd proper operation of '-n' no-op mode.
Added missing reference to '-o' in usage.
#8 11526 Russell C. Jackson (Rusty) Removed p4verify.pl from common files
 Updated dist.sh to work with relative paths and removed hard coding on tar path
 Created new distribution files.
#7 11525 Russell C. Jackson (Rusty) Updated Version and Release notes.
#6 10959 C. Thomas Tyler Added check for unsync'd files.
#5 10872 C. Thomas Tyler Added Windows SDP into The Workshop:
* Combined (back) into Unix SDP structure.
* Avoided adding duplicate files p4verify.pl, p4review.(py,cfg).
* Upgraded 'dist.sh' utility to produce both Unix and Windows
packages (*.tgz and *.zip), adjusting line endings on text
files to be appropriate for Windows prior to packaging.

To Do:
* Resolve duplication of [template_]configure_new_server.bat.
* Merge test suites for Windows and Unix into a cohesive set.
#4 10753 C. Thomas Tyler Exlcuding cruft files.
#3 10751 C. Thomas Tyler More cleanup.
#2 10748 C. Thomas Tyler Added safety check for checked out files.
 Updated exlcudes.
#1 10737 C. Thomas Tyler Added helper script to create SDP distro tar file.