#!/bin/sh
#
# svn-to-svn - Subversion dump on stdin to dump on stdout
#
# With the -c option, build the repo and check it out to a working
# copy.  The name of the working copy is the repo name suffixed with
# '-checkout'.
#
# With the -d option, expect the repo to exist, undump the repo to
# a Subversion dump file; then do not delete the repo.
#
# With the -e option, edit a Subversion dumpfile and rebuild it, fixing
# the checksum headers.
#
# With the -g option, make a Git repo from the Subversion dump and view
# it in gitk
#
# Any -l option argument will be used to set reposurgeon's log option.
#
# With the -n option, create a repo corresponding to the input stream;
# do not stream the result to stdout and do not delete the repo.
#
# With the -o option, expect the repo to exist, pick it up with
# reposurgeon, and throw the result to stdout as an import stream;
# then do not delete the repo.
#
# With the -q option. suppress progress messages from svnadmin load
# and checkout.
#
# With the -r option, limit the number of Subversion revisions processed
# from the input dump; the specified argument is the humber of the last
# revision emitted.
#
# The -s option strips out generated time-varying headers - the UUID and
# the timestamp in revision zero.  This is necessary for file comparisons 
# in regression tests.
#
# The -t option allows property extensions to be generated.  It's turned
# off by default because git-import chokes on it.
#
# If an argument is specified after the options, it is used as the repository
# directory name; otherwise 'test-repo' is used.
#
# To add complexity to a test load, do -n, then edit the test repo with
# Subversion, then use -d. Note: you must commit to force the repo to
# be up to date before streaming it. Also note that any embedded comments
# will be lost.
#
# The REPOSURGEON environment variable can be used to substitute in a
# different implementation.
#
# The TESTOPT variable can be used to pass an early command or option setting
# to reposurgeon.
#
. ./common-setup.sh

PATH=$PATH:./..

build=T
view=F
edit=F
stream=F
undump=T
cleanup=T
strip=F
co=F
log=""
quiet=""
limit=""
# Suppress legacy emission by default
streamopts='prefer git'

# Built-in echo insidiously expands backslash escapes.  This is a problem
# when stripping... 
ECHO=/bin/echo

while getopts cdegl:noqr:st opt
do
    case $opt in
        e) build=F; view=F; edit=T; stream=F; dump=F; cleanup=T; strip=F; co=F;;
	c) build=T; view=F; edit=F; stream=F; dump=F; cleanup=F; strip=F; co=T;;
	n) build=T; view=F; edit=F; stream=F; dump=F; cleanup=F; strip=F; co=F;;
        g) build=F; view=T; edit=F; stream=F; dump=F; cleanup=F; strip=F; co=F;;
        o) build=F; view=F; edit=F; stream=T; dump=F; cleanup=F; strip=F; co=F;;
        d) build=F; view=F; edit=F; stream=F; dump=T; cleanup=F; strip=F; co=F;;
        s) build=F; view=F; edit=F; stream=F; dump=F; cleanup=F; strip=T; co=F;;
	t) streamopts="" ;;
	q) quiet=-q ;;
	r) limit="$OPTARG" ;;
	l) log="log $OPTARG" ;;
    esac
done
shift $(($OPTIND - 1))

tmpdir=${TMPDIR:-/tmp}

# This lets us set the repo location 
testrepo=`realpath \`dirname ${1:-test-repo$$}\``/`basename ${1:-test-repo$$}`

# Should we strip time-varying headers out of the input dump file?
if [ $strip = T ]
then
    seen_uuid=F
    seen_date=F
    while IFS= read -r line
    do
	case $line in
	    [0-9]*)
		if [ $seen_date = T ]; then $ECHO "$line"; fi ;  
		seen_date=T ;;
	    UUID*)  
		if [ $seen_uuid = T ]; then $ECHO "$line"; fi ; 
		seen_uuid=T ;;
	    *) $ECHO "$line" ;;
	esac
    done
fi

# Was there a limit option?
if [ -z "$limit" ]
then
    source=/dev/stdin
else
    source="${tmpdir}/svn-to-svn-$$"
    ../repocutter -r "0:${limit}" select >$source
fi

# Should we build a repo from a dump presented on standard input?
if [ $build = T ]
then
    rm -fr $testrepo $testrepo-checkout
    svnadmin create $testrepo
    if svnadmin load ${quiet} $testrepo <$source
    then
	:
    else
	exit 1
    fi
fi

if [ $co = T ]
then
    svn co ${quiet} file://$testrepo ${testrepo}-checkout >/dev/null
fi

# Should we edit the streamfile?
if [ $edit = T ]
then
    dump=$1
    if [ -z $dump ]
    then
	echo "svn-to-svn: a file argument is required" >&2
	exit 1
    elif $EDITOR $1
    then
	rm -fr $testrepo test-checkout
	svnadmin create $testrepo
	sed  <$dump \
	    -e '/Text-content-md5: /d' -e '/Text-content-sha1: /d' \
	    -e '/Text-copy-source-md5: /d' -e '/Text-copy-source-sha1: /d' \
	    | svnadmin load $testrepo >/dev/null
	svnadmin dump $testrepo >$dump
    fi
fi

# Should we view the repo?
if [ $view = T ]
then
    (cd $testrepo >/dev/null; {BIN}/${REPOSURGEON:-reposurgeon} "${log}" "${TESTOPT}" "read ." "prefer git" "rebuild ${tmpdir}/testrepo$$"; cd ${tmpdir}/testrepo$$; gitk --all --tags)
fi

# Should we dump a conversion of the repo as a fast-import stream?
if [ $stream = T ]
then
    ${REPOSURGEON:-reposurgeon} "${log}" "${TESTOPT}" "read $testrepo" "$streamopts" "write"
fi

# Should we dump the repo as a Subversion stream?
if [ $dump = T ]
then
    svnadmin dump $testrepo
fi

# Should we clean up the test directory
if [ $cleanup = T ]
then
    rm -fr $testrepo test-checkout
fi
