#!/bin/bash
#------------------------------------------------------------------------------
# Repro for: N/A, this is a demo, not a bug repro.
set -u
# Usage:
# ./repro.sh [-f] 2>&1 | tee repro.log
#
# Scenario: Shelved CL Disappeared
export P4CONFIG=.p4config
export P4ENVIRO=/dev/null/.p4enviro
declare Version=1.2.0
declare -i ErrorCount=0
declare H1="=============================================================================="
declare TmpFile=
# Micro functions.
function msg () { echo -e "${1:-}"; }
function errmsg () { msg "\nError: ${1:-Unknown Error}"; ErrorCount+=1; }
function bail () { errmsg "${1:-Unknown Error}"; exit "$ErrorCount"; }
function cmd () { msg "${2:-}"; msg "Executing command: $1"; $1; return $?; }
declare -i shiftArgs=0
declare -i Force=0
declare -i Scenario=1
declare ScenarioTitle="Smart Sync Demo"
#------------------------------------------------------------------------------
# Command Line Args
set +u; while [[ $# -gt 0 ]]; do
case $1 in
(-f) Force=1;;
(-*) bail "Usage error: Unknown option ($1).";;
(*) bail "Usage error: Unknown parameter ($1).";;
esac
# Shift (modify $#) the appropriate number of times.
shift; while [[ $shiftArgs -gt 0 ]]; do
[[ $# -eq 0 ]] && bail "Bad usage."
shiftArgs=$shiftArgs-1
shift
done
done
set -u
ReproDir=/tmp/repro
TmpFile=$(mktemp)
msg "Started ${0##*/} v$Version at $(date)."
msg "ReproDir=$ReproDir"
[[ -d "$ReproDir" && "$Force" -eq 1 ]] && /bin/rm -rf "$ReproDir"
[[ -d "$ReproDir" ]] && bail "Old repro dir [$ReproDir] exists."
mkdir "$ReproDir" || bail "Could not do: mkdir \"$ReproDir\""
cd "$ReproDir" || bail "Could not do: cd \"$ReproDir\""
msg "==============================================================================\nScenario $Scenario: $ScenarioTitle\n"
msg "\nPreliminary info: Show versions of p4/p4d on the PATH:"
cmd "p4 -V"
cmd "p4d -V"
msg "\nPreliminary setup: Spin up local repo."
cmd "mkdir $ReproDir"
cd "$ReproDir" || bail "Could not do: cd \"$ReproDir\""
msg "Operating in: $PWD"
cmd "p4 init -C0 -n"
msg "\nAdd some files."
echo -e "// ONE_H\n#ifndef ONE_H\n#define ONE_H 1\n\n//Stuff goes here\n\n#endif //ONE_H\n" > One.h
cmd "p4 status"
msg "Reconcile and submit."
p4 rec && p4 submit -d "Added One.h."
msg "Executing: p4 stream -t release -P //stream/main -o //stream/release > $TmpFile"
p4 stream -t release -P //stream/main -o //stream/release > "$TmpFile" ||\
bail "Failed to create release stream spec."
msg "Executing: p4 stream -i < $TmpFile"
p4 stream -i < "$TmpFile" ||\
bail "Failed to load release stream spec:\n\n$(grep -v ^# "$TmpFile")\n\n"
msg "Executing: p4 stream -t mainline -o //stream/main_compiled > $TmpFile"
p4 stream -t mainline -o //stream/main_compiled > "$TmpFile" ||\
bail "Failed to create main_compiled stream spec."
msg "Executing: p4 stream -i < $TmpFile"
p4 stream -i < "$TmpFile" ||\
bail "Failed to load main_compiled stream spec:\n\n$(grep -v ^# "$TmpFile")\n\n"
cmd "p4 populate -r -S //stream/release" "Pouplate the new release stream."
cmd "p4 switch -l" "\nList streams."
cmd "p4 client -s -S //stream/release" "\nSwitch the stream this workspace is associated with to //stream/release."
cmd "p4 have" "\nThis is to illustrate that 'p4 client -s -S' didn't update the 'have' list automatically - it still references //stream/main."
cmd "p4 sync" "\nThis is the smart sync. The magic is indicated by the word 'replacing' meaning no files contents are udpated, so it's fast."
cmd "p4 have" "\nAfter the smart sync, the 'have' list was updated (even though the content wasn't because it didn't need to be)."
cmd "p4 sync @0" "\nJust clean up the files."
cmd "p4 sync" "\nThe smarts don't apply to a sync if we don't already have the files. So we don't see 'replacing', instead we see 'updating'."
cmd "p4 sync @0" "\nClean up the files to prep for the next part of the demo."
cmd "p4 client -s -S //stream/main_compiled" "\nSwitch the stream this workspace is associated with to //stream/main_compiled."
msg "\nAdd a diffferent One.h file with no historical connection (i.e. no integration history connection) to the other One.h, but same name, contents, and same location relative to the workspace root. Also add an extra file One.compiled.\n"
echo -e "// ONE_H\n#ifndef ONE_H\n#define ONE_H 1\n\n//Stuff goes here\n\n#endif //ONE_H\n" > One.h
echo -e "// ONE_H\n#ifndef ONE_H\n#define ONE_H 1\n\n//Stuff goes here\n\n#endif //ONE_H\n**COMPILED**" > One.compiled
cmd "p4 status"
msg "Reconcile and submit."
p4 rec && p4 submit -d "Added One.h."
cmd "p4 filelog -i //stream/main/One.h" "\nShow history for //stream/main/One.h"
cmd "p4 filelog -i //stream/main_compiled/One.h" "\nShow history for //stream/main_compiled/One.h (unrelated to the one in main)."
cmd "p4 client -s -S //stream/main" "\nSwitch the stream this workspace is associated with to //stream/main."
cmd "p4 have" "\nThis is to illustrate that 'p4 client -s -S' didn't update the 'have' list automatically - it still references //stream/release."
cmd "p4 sync" "\nThis is the smart sync. The magic is indicated by the word 'replacing' meaning no files contents are udpated, so it's fast."
msg "\nCONCLUSION: If the above line says 'replacing', SmartSync is in effect. (Should be true for P4D 2011.2+). So it actually doesn't depend on integration history, it only depends on files having the same name and location relative to the workspace root, and same MD5 checksum on the server.\n"
rm -f "$TmpFile"
if [[ "$ErrorCount" -eq 0 ]]; then
msg "${H1}\nTest completed with no errors. Results are valid."
else
errmsg "${H1}\nTest completed with $ErrorCount errors. Results may be invalid."
fi
exit "$ErrorCount"