#!/bin/bash
#------------------------------------------------------------------------------
# Sample script illustratring Protections table entries to deny ability to
# branch from a particular path. It generates a disposable micro-repo
# for playing with the feature.
set -u
# Sample Usage:
# ./illustrate_branch_deny.sh -f 2>&1 | tee illustrate_branch_deny.log
#
# Then you can play with the resulting sample.
# export P4CONFIG=.p4config
# cd /tmp/illustrate_branch_deny
# p4 info
#
export P4CONFIG=.p4config
export P4ENVIRO=/dev/null/.p4enviro
declare Version=1.0.1
# Micro functions.
function msg () { echo -e "${1:-Hi}"; }
function bail () { msg "Error: ${1:-Unknown Error}"; exit ${2:-1}; }
function cmd () { msg "${2:-Executing command: $1}"; $1; return $?; }
declare -i shiftArgs=0
declare ScenarioTitle="Branch Deny"
declare -i Force=0
#------------------------------------------------------------------------------
# Command Line Args
set +u; while [[ $# -gt 0 ]]; do
case $1 in
(-f) Force=1;;
(*) 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
ReproDir=/tmp/illustrate_branch_deny
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. To remove it, run again using -f."
mkdir $ReproDir || bail "Failed to create dir: $ReproDir"
cd $ReproDir || bail "Failed to cd to $ReproDir."
msg "==============================================================================\nScenario: $ScenarioTitle\n"
msg "\nPreliminary info: Show versions of p4/p4d on the PATH:"
cmd "p4 -V"
cmd "p4d -V"
msg "\nPreliminary setup: Spin up a local repo."
cmd "p4 init -C0 -n" || bail "Failed to set up repo. Ensure p4 and p4d are on path, the same version, and that version should be 2015.1 or later."
echo ".*.p4s" >> .p4ignore
msg "Showing initial protections."
p4 protect -o | grep -v ^#
p4 protect -o | grep -v ^# > .protect.p4s
msg "\nAdd some files."
cmd "mkdir Public Private"
echo -e "// ONE_H\n#ifndef ONE_H\n#define ONE_H 1\n\n//Stuff goes here\n\n#endif //ONE_H\n" > Public/One.h
echo -e "// TWO_H\n#ifndef TWO_H\n#define TWO_H 1\n\n//Stuff goes here\n\n#endif //TWO_H\n" > Private/Two.h
cmd "p4 status"
msg "Reconcile and submit."
p4 rec && p4 submit -d "Added Public/One.h and Private/Two.h in main."
msg "\n== Release r1 (Before implementing branch deny) =="
p4 stream -t release -P //stream/main -o //stream/r1 | p4 stream -i
cmd "p4 populate -f -o -r -S //stream/r1"
msg "\nYikes: Both Public and Private are branched. Not what we want! So let's fix it."
msg "\n== Update protections: Add Branch Deny for Private/... =="
echo -e "\t=branch user * * -//stream/main/Private/....h" >> .protect.p4s
p4 protect -i < .protect.p4s || bail "Failed to update these protections:\n$(cat protect.p4s)\n"
msg "Showing updated protections."
p4 protect -o | grep -v ^#
msg "\n== Release r2 =="
p4 stream -t release -P //stream/main -o //stream/r2 | p4 stream -i
cmd "p4 populate -f -o -r -S //stream/r2"
msg "\n\nThere we go! See that now the Private stuff did not branch.\n\n"
msg "\n\nSummary: Use something like this snippet in the Protections table:
\twrite user * * //path/to/allow/write/but/deny/branching/...
\t=branch user * * -//path/to/allow/write/but/deny/branching/...
The '=branch' with the exclusion must appear below the entry granting write access to the given path.\n"
exit 0