#!/bin/bash
# ==========
# $File: //guest/adam_morriss/scripts/stream-hierarchy.sh $
# $Revision: #1 $
# $Change: 23299 $
#
# $Author: amo $
# $DateTimeTZ: 2017/11/30 05:33:54 -0800 PST $
# ==========
# PURPOSE
# Identify and extract a streams hierarchy from one server, and creating them on another.
# -----------
# ASSUMPTIONS
# the machine on which the extraction is carried out has access to the server from which the data is to be extracted
# the machine on which the insertion is carried out has access to the server into which the data is inserted
# a 2016.1 or later 'p4' client application is on this machine (the '-F' flag requires '16.1+)
# -----------
# The extraction process is as follows:
# - create a directory into which various files will be written;
# - extract the depot spec;
# - find all streams that match a given streams path, and write each spec to a separate file;
# - find all 'mainline' streams (or those without parent) and write each stream name to a file;
# - find all streams with a parent in the previously-created file, and write each stream name to another file - repeat;
# - halt once all the streams have been recorded (an empty file is the last created, for example);
# - package up the directory containing these lists of streams and the stream-spec files.
# -----------
# The insertion process is more or less the reverse of the above:
# - deliver the 'transfer' archive to a location where the data can be added to the target server;
# - unpack the archive;
# - create the depot spec from the file created;
# - iterate through the lists of streams, again in hierarchical order, starting with the lowest numbered list.
# -----------
# These two sequences complete the task as expected, although the process is not perfect.
# It is less of a 'script' and more of a sequence of commands.
# Things to add (some nice-to-have, some required):
# - error/exception handling;
# - improved method for looping through the various lists;
# - consider a rewrite using a different scripting language with better Perforce-ness: 'P4Python', for example?
#
# ==========
# DATA EXTRACTION
# create directory and switch into this location
mkdir -p transfer/streamDepotName
cd transfer
# write depot spec to file
p4 depot -o streamDepotName > streamDepotName/streamDepotName.depot.spec
# identify streams, write each to file.
# A stream called "//streamDepotName/myStream" would be written to "streamDepotName/myStream.spec"
for X in `p4 -ztag -F %Stream% streams //streamDepotName/...`; do p4 stream -o $X > `echo $X | sed -e 's/^\/\///g'`.spec; done
# write a list of 'mainline' streams - those without parent stream
# Note: to include task streams with no parent, change "-F Type=mainline" for "-F Parent=none"
p4 -ztag -F %Stream% streams -F Type=mainline //streamDepotName/... > streamspecs.0
# read the previous 'streamspecs' file, identifying all those with a parent in the aforementioned file
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.0 > streamspecs.1
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.1 > streamspecs.2
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.2 > streamspecs.3
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.3 > streamspecs.4
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.4 > streamspecs.5
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.5 > streamspecs.6
while read STREAM; do p4 -ztag -F %Stream% streams -F Parent=$STREAM; done < streamspecs.6 > streamspecs.7
# up one level, and package up the 'transfer' folder
cd ..
tar -czvf transfer.tgz transfer
# DATA INSERTION
# unpack the files
tar -zxvf transfer.tgz
# change to the 'transfer' directory created by the above command
cd transfer
# create the 'streamDepotName' depot from the depot spec saved
p4 depot -i < streamDepotName/streamDepotName.depot.spec
# starting with 'mainline' streams, create streams specs from the spec files
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.0
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.1
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.2
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.3
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.4
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.5
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.6
while read STREAM; do SPEC=`echo $STREAM | sed -e 's/^\/\///g'`.spec; cat $SPEC | p4 stream -i; done < streamspecs.7