Yuan Yijun (bbbush) wrote,
Yuan Yijun
bbbush

sawvcmd.sh



#!/bin/sh
## sawvcmd.sh, a wrapper for Dynamsoft SourceAnywhere for VSS Professional
## Client SAWVCMD.EXE (a cmdline tool). The script can be used in cygwin.
## This script is based on publically available document and has nothing to
## do with Dynamsoft or Morningstar, except for the help strings.
## This script except for the help strings is released under XXXXX with no warranty.
## Fill "required args" before using it.

SAWVCMD="/cygdrive/c/Program Files/DynamSoft/SourceAnywhere for VSS Professional Client/SAWVCmd.exe"

# required args
SAWSERVER=
SAWPORT=
SAWUSER=
SAWPASSWD=
SAWDBALIAS=

SAWPROJBASE="/cygdrive/d" ## the folder that maps to $

SAWROOTFILE=".sawroot"

# read the first line of file
function do_readsawroot()
{
		SAWROOT=`head -n 1 "$1"`
		echo -n "${SAWROOT%/}"
}

# find sawroot with a loop, omit root folder
function findsawroot()
{
		PWD="$1"
		shift
		if [ -z "$PWD" ]; then
			PWD=`pwd | sed -e s,^/mnt,/cygdrive,`
		fi

		PUSHD=
		while ! [ -z "$PWD" ] && [ "$PWD" != "/" ]; do
				SAWROOTFILEPATH="${PWD}/${SAWROOTFILE}"
				if [ -f "$SAWROOTFILEPATH" ]; then # read only the first line
						SAWROOT=`do_readsawroot "$SAWROOTFILEPATH"`
						echo -n "${SAWROOT}/${PUSHD}"
						break
				else
						CURRENTD=`basename "$PWD"`
						PUSHD="${CURRENTD}/${PUSHD}"
						PWD=`dirname "$PWD"`
				fi
		done
}

# read specified sawroot file
function readsawroot()
{
		PWD="$1"
		shift
		if [ -z "$PWD" ]; then
			PWD=`pwd | sed -e s,^/mnt,/cygdrive,`
		fi

		if [ -d "$SAWROOTFILEPATH" ]; then
				SAWROOTFILEPATH="${SAWROOTFILEPATH%/}/${SAWROOTFILE}"
		fi

		if [ -f "$SAWROOTFILEPATH" ]; then
				ROOTD=`cd $(dirname "$SAWROOTFILEPATH"); pwd | sed -e s,^/mnt,/cygdrive,`
				SAWROOT=`do_readsawroot "$SAWROOTFILEPATH"`
				echo "${SAWROOT}${PWD##$ROOTD}"
		fi
}



## here in SAW system, -prj means remote folder and -file means a single file
## name, -workdir means local folder (to search for the file)
if [ -z "$SAWPROJ" ]; then
		if [ -e "$SAWROOTFILEPATH" ]; then ## define this to specify sawroot
				SAWPROJ=`readsawroot`
		elif ! [ -z "$SAWSEARCHROOT" ]; then ## define this to search
				SAWPROJ=`findsawroot`
		else
				PWD=`pwd | sed -e s,^/mnt,/cygdrive,`
				if [[ "$PWD" =~ "${SAWPROJBASE}" ]]; then ## in SAWPROJBASE folder
						SAWPROJ=`echo -n "$PWD" | sed -e "s,^${SAWPROJBASE}/*,$/,"` ## map local folder to remote
				fi
		fi

		SAWPROJ="${SAWPROJ%/}"

		if ! [ -z "$SAWPROJ" ]; then
				echo "SAWPROJ='${SAWPROJ}'" > /dev/stderr
		fi
fi

SAWPROXYTYPE=
SAWPROXYSERVER=
SAWPROXYPORT=
SAWPROXYUSER=
SAWPROXYPASSWD=
SAWPROXYNEEDAUTH=

# combined args
SAWSERVERPORT=("-server" "$SAWSERVER" "-port" "$SAWPORT")
SAWAUTH=("-username" "$SAWUSER" "-pwd" "$SAWPASSWD")
SAWPROXY=()
if [ ! -z "$SAWPROXYTYPE" ] \
		&& [ ! -z "$SAWPROXYSERVER" ] \
		&& [ ! -z "$SAWPROXYPORT" ]; then
		SAWPROXY=("-ptype" "$SAWPROXYTYPE" "-pserver" "$SAWPROXYSERVER" "-pport" "$SAWPROXYPORT")
		if [ ! -z "$SAWPROXYNEEDAUTH" ] \
				&& [ ! -z "$SAWPROXYUSER" ] \
				&& [ ! -z "$SAWPROXYPASSWD" ]; then
				SAWPROXY=("${SAWPROXY[@]}" "-puser" "$SAWPROXYUSER" "-ppwd" "$SAWPROXYPASSWD")
		fi
fi

# choice between -windows, -unix and -mac
SAWLINETERMINATOR="-windows"

SAWCOMMANDS=`cat << END
	AddFile GetFile GetFileHistory GetFileInfo CheckInFile CheckOutFile UndoCheckOutFile
	AddFolder GetProject GetProjectHistory CheckInProject CheckOutProject UndoCheckOutProject
	AddLabel ShareFile ShareProject BranchFile Rename Delete
	CreateProject GetFileList GetProjectTree Dir GetDatabases Interactive
END`

# main entry
function sawvcmd()
{
		## first prompt help string
		if [ -z "$1" ] \
				|| ( [[ "$1" =~ "help" ]] && [ -z "$2" ] ) \
				|| ( ! [[ "$1" =~ "help" ]] && ! echo "$SAWCOMMANDS" | grep -ie "\b$1\b" -q ) \
				; then
				echo "Valid commands:" > /dev/stderr
				echo "$SAWCOMMANDS" > /dev/stderr
				return;
		fi

		if [[ "$2" =~ "help" ]] && [ ! -z "$1" ]; then sawhelp "$1"; return; fi
		if [[ "$1" =~ "help" ]] && [ ! -z "$2" ]; then sawhelp "$2"; return; fi

		SAWCOMMAND="$1"
		shift



		## set flags according to commands

		SAWNEEDSERVER=1
		SAWNEEDAUTH=1
		SAWNEEDPROXY=1
		SAWCANCOMMENT=1
		SAWACCEPTLINETERMINATOR=1
		SAWNEEDDBALIAS=1
		SAWNEEDPROJ=1
		case "$SAWCOMMAND" in
				"AddLabel"):
				SAWACCEPTLINETERMINATOR=
				;;
				"BranchFile"):
				SAWACCEPTLINETERMINATOR=
				;;
				"CreateProject"):
				SAWACCEPTLINETERMINATOR=
				;;
				"Delete"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=

				## TODO: split the file list in "-file" and prompt for each one
				echo "This command eats babies!" > /dev/stderr
				return
				;;
				"Dir"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"GetDatabases"):
				SAWNEEDAUTH= #special because it does not require auth
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				SAWNEEDALIAS=
				SAWNEEDPROJ=
				;;
				"GetFile"):
				SAWCANCOMMENT=
				;;
				"GetFileHistory"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"GetFileInfo"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"GetFileList"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"GetProject"):
				SAWCANCOMMENT=
				;;
				"GetProjectHistory"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"GetProjectTree"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"Interactive"): # special because it does not require prj
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				SAWNEEDPROJ=
				;;
				"Rename"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"ShareFile"):
				SAWCANCOMMENT=
				SAWACCEPTLINETERMINATOR=
				;;
				"ShareProject"):
				SAWACCEPTLINETERMINATOR=
				;;
				"UndoCheckOutProject"):
				SAWCANCOMMENT=
				;;
				"UndoCheckOutFile"):
				SAWCANCOMMENT=
				;;
		esac



		# set params according to flags

		if [ ! -z "$SAWNEEDAUTH" ]; then
				SAWPARAMS=("${SAWPARAMS[@]}" "${SAWSERVERPORT[@]}" "${SAWAUTH[@]}")
		elif [ ! -z "$SAWNEEDSERVER" ]; then
				SAWPARAMS=("${SAWPARAMS[@]}" "${SAWSERVERPORT[@]}")
		fi

		if [ ! -z "$SAWACCEPTLINETERMINATOR" ]; then
				SAWPARAMS=("${SAWPARAMS[@]}" "$SAWLINETERMINATOR")
		fi

		if [ ! -z "$SAWNEEDPROXY" ]; then
				SAWPARAMS=("${SAWPARAMS[@]}" "${SAWPROXY[@]}")
		fi

		if [ ! -z "$SAWCANCOMMENT" ]; then
				SAWPARAMS=("${SAWPARAMS[@]}" "-comment" "")
		fi

		if [ ! -z "$SAWNEEDDBALIAS" ] && [ ! -z "$SAWDBALIAS" ]; then
				SAWPARAMS=("${SAWPARAMS[@]}" "-alias" "$SAWDBALIAS")
				if  [ ! -z "$SAWNEEDPROJ" ] && [ ! -z "$SAWPROJ" ]; then
						SAWPARAMS=("${SAWPARAMS[@]}" "-prj" "$SAWPROJ")
				fi
		fi



		## execute commands
		if ! [ -z "$DEBUGINFO" ]; then
				echo "$SAWVCMD" "$SAWCOMMAND" "${SAWPARAMS[@]}" "$@" > /dev/stderr
				echo "${#SAWPARAMS[@]}" > /dev/stderr
				for i in "${SAWPARAMS[@]}"; do echo "$i" > /dev/stderr; done
		fi
		"$SAWVCMD" "$SAWCOMMAND" "${SAWPARAMS[@]}" "$@"
}

# help documents
function sawhelp()
{
	SAWCOMMAND="$1"
	shift

	case "$SAWCOMMAND" in
			"AddFile"):
			Message=`cat << END
Adds one or multiple files to a project. The path of the file on the local
machine is specified by the -workdir parameter.

Required Params: -file, -workdir
Optional Params: -tempdir, -auto or -text or -bin,-zoneoff, -notreadonly,
	-nozip, -nodelta,

END`
			;;
			"AddFolder"):
			Message=`cat << END
Adds an entire local folder to the database. The path of the local folder on the
local machine is specified by the -workdir parameter. Use -r to add the folder
recursively.

Required Params: -workdir
Optional Params: -nozip, -nodelta, -tempdir, -r, -auto or -text or
	-bin,-zoneoff, -notreadonly

END`
			;;
			"AddLabel"):
			Message=`cat << END
Adds a label to a project or a file.

Required Params: -label
Optional Params: -file

END`
			;;
			"BranchFile"):
			Message=`cat << END
Breaks the share link and the changes made to that file will no longer be
reflected in other projects.

Required Params: -file

END`
			;;
			"CreateProject"):
			Message=`cat << END
Creates an empty project in the VSS database whose full name is specified by the
-prj parameter.

END`
			;;
			"CheckInFile"):
			Message=`cat << END
Checks in one or multiple files.

Required Params: -file
Optional Params: -workdir, -tempdir, -keep, -checkin or -ask or -undo, -del,
	-zoneoff, -notreadonly, -nozip, -nodelta

END`
			;;
			"CheckInProject"):
			Message=`cat << END
Checks in an entire project. Use -r to check in the project recursively.

Optional Params: -workdir, -tempdir, -r, -del, -keep, -checkin or -ask or -undo,
	-zoneoff, -notreadonly, -nozip, -nodelta

END`
			;;
			"CheckOutFile"):
			Message=`cat << END
Checks out one or multiple files. This command also makes the local files writable.

Required Params: -file
Optional Params: -workdir, -tempdir, -ask or -skip or -replace, -time, -zoneoff,
	-nozip, -nodelta

END`
			;;
			"CheckOutProject"):
			Message=`cat << END
Checks out an entire project. This command also makes the local files in the
project writable. Use -r to checkout a project recursively.

Optional Params: -workdir, -tempdir, -r ,-ask or -skip or -replace
	-time,-zoneoff, -nozip, -nodelta

END`
			;;
			"Delete"):
			Message=`cat << END
Deletes a file or project. If the -permanent flag is set, it will delete the
file or project permanently from the database so it cannot be recovered.

Optional Params: -file, -permanent

END`
			;;
			"Dir"):
			Message=`cat << END
Displays all projects and files under a project. Use -r to see about a project
recursively.

Optinal Params: -r, -zoneoff

END`
			;;
			"GetDatabases"):
			Message=`cat << END
Lists all databases accessible by the input server.

END`
			;;
			"GetFile"):
			Message=`cat << END
Gets one or multiple files from the SourceSafe database. It will get the latest
version of  files unless the -rev or -label parameter is used to specify a
certain file.

Required Params: -file
Optional Params: -workdir, -tempdir, -rev, -label,-writable, -ask or -skip or
	-replace, -time, -zoneoff, -nozip, -nodelta

END`
			;;
			"GetFileHistory"):
			Message=`cat << END
Gets the revision history of the file.

Required Params: -file
Optional Params: -user, -datetime, -zoneoff

END`
			;;
			"GetFileInfo"):
			Message=`cat << END
Gets current information about a file.

Required Params: -file
Optional Params : -zoneoff

END`
			;;
			"GetFileList"):
			Message=`cat << END
Gets a list of all files in the input project. This command outputs the name,
version and date of each file.

Optional Params: -zoneoff

END`
			;;
			"GetProject"):
			Message=`cat << END
Gets all of the files in a project. It will get the latest version of the files
in a project unless the -label or -datetime parameter is used to specify a
previous version of a project. Use -r to get the project recursively.

Optional Params: -workdir, -tempdir, -datetime or -label , -r, -writable, -time,
	-ask or -skip or -replace, -zoneoff, -nozip, -nodelta

END`
			;;
			"GetProjectHistory"):
			Message=`cat << END
Displays project history in Command Line Client.


Optional params: -r,-user, -datatime, -zoneoff, -includefilehistory

END`
			;;
			"GetProjectTree"):
			Message=`cat << END
This command returns the structure of the project in the VSS database. Please
note that this command does not retrieve the files in the project.


END`
			;;
			"Interactive"):
			Message=`cat << END
Puts the Client in an interactive shell, where you can enter commands one after
the other, without having to re-run the Command Line Client each time. Type
'quit' when you want to quit interactive shell.

Optional Params : -tempdir

END`
			;;
			"Rename"):
			Message=`cat << END
Renames a file or project in the VSS database.

Required Params: -newname
Optional Params: -file

END`
			;;
			"ShareFile"):
			Message=`cat << END
Shares the current version of one or multiple files to another project. Updates
to a shared file will be reflected in all the projects to which the file is
shared.

Required Params: -file, -shareto
Optional Params: -branch

END`
			;;
			"ShareProject"):
			Message=`cat << END
Shares the current version of a project to another project. Updates to files in
a shared project will be reflected in all the projects to which the project is
shared.

Required Params: -shareto
Optional Params: -branch, -r

END`
			;;
			"UndoCheckOutProject"):
			Message=`cat << END
Cancels the checkout of a project and revert to the state before the Check Out
operation was performed. Use -r to undo checkout of the project recursively.

Optional Params: -workdir, -tempdir, -r, -time, -leave or -replace or
	-del,-zoneoff, -notreadonly, -nozip, -nodelta

END`
			;;
			"UndoCheckOutFile"):
			Message=`cat << END
Cancels the checkout of one or multiple files and revert to the state before the
Check Out operation was performed.

Required Params: -file
Optional Params: -workdir, -tempdir, -time, -leave or -replace or -del,
	-zoneoff, -notreadonly, -nozip, -nodelta

END`
			;;
			"Help"):
			Message=`cat << END
SAWPROJBASE:		The folder that maps to $
SAWPROJ:		if under SAWPROJBASE then do a simple substitute
			else, read from SAWROOTFILEPATH or search (slow)
SAWROOTFILE:		default is .sawroot
SAWROOTFILEPATH:	point to the folder that contains the .sawroot file
SAWSEARCHROOT:		if 2 or more .sawroot are at different parent folders
END`
			;;
			*):
			Message="I don't know"
			;;
	esac

	echo "$Message" > /dev/stderr
}

if [[ "$0" =~ "sawvcmd-echo-sawroot" ]]; then
		echo -n "$SAWPROJ"
elif [[ "$0" =~ "/bin/sawvcmd" ]]; then
		shopt -s nocasematch
		sawvcmd "$@"
fi





Tags: 工作
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments