p4 #29

  • //
  • guest/
  • alan_h_teague/
  • myp4/
  • p4
  • View
  • Commits
  • Open Download .zip Download (15 KB)
#!/bin/bash
MYP4BIN=$HOME/bin

P4BIN=$MYP4BIN/p4.bin
P4DBIN=$MYP4BIN/p4d.bin

if [ ! -f $P4BIN ]; then
	what=$(uname)
	if [ "$what" == 'Darwin' ]; then
		MYPLAT="bin.darwin90x86_64"
	else
		MYPLAT="bin.linux26x86_64"
	fi
	echo "Downloading required Perforce binaries for $MYPLAT ..."
	which wget > /dev/null
	if [ $? -eq 0 ]; then
		wget -q -O $P4BIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4
		wget -q -O $P4DBIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4d
	else
		curl -q -o $P4BIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4
		curl -q -o $P4DBIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4d
	fi
	chmod a+x $P4BIN
	chmod a+x $P4DBIN
	echo "Done."
fi

# Check every so often like every 32 times or so
if [ "$1" == "check" ] || [ $(($RANDOM / 911)) -eq 0 ]; then
	THIS_REV=29
	NEWER_REV=$(($THIS_REV+1))
	which wget > /dev/null
	if [ $? -eq 0 ]; then
		wget -S --spider \
			https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4?v=$NEWER_REV \
			> /dev/null 2> /dev/null
		if [ $? -eq 0 ]; then
			echo "A newer version of myp4 is available"
			echo "https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4"
		elif [ "$1" == "check" ]; then
			echo "No newer version is available"
			exit 0
		fi
	else
		cur=$(curl -o /dev/null --silent --head --write-out "%{http_code}\n" \
			https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4?v=$NEWER_REV)
		if [ "$cur" == "200" ]; then
			echo "A newer version of myp4 is available"
			echo "https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4"
		elif [ "$1" == "check" ]; then
			echo "No newer version is available"
			exit 0
		fi
	fi
fi

if [ -z "$P4CONFIG" ]; then
    export P4CONFIG=".myp4"
fi

if [ -z "$P4IGNORE" ]; then
    export P4IGNORE=".myp4ignore"
fi

rootDir=$($P4BIN -ztag set | \
	egrep "^P4CONFIG=$P4CONFIG" | \
	cut -d "'" -f 2 | \
	sed "s/$P4CONFIG/.myp4d/")

if [ "$rootDir" == 'noconfig' ]; then
	if [ "$1" != 'init' ]; then
		$P4BIN "$@"
		exit $?
	fi
	echo 'Initializing...'
	baseDir="$PWD"
	if [ -n "$2" ]; then
			baseDir="$PWD/$2"
	fi
	rootDir="$baseDir/.myp4d"
  if [ -d "$rootDir" ]; then
		echo "Perforce storage already maps to $rootDir"
		exit 1
	fi
	mkdir -p "$rootDir"
	cat > "$baseDir/$P4CONFIG" <<FOOBAR
P4USER=$USER
P4CLIENT=$USER
P4IGNORE=$P4IGNORE
P4PORT=rsh:$P4DBIN -r "$rootDir" -Llog_file -i -vserver=3
FOOBAR
	cat > "$baseDir/$P4IGNORE" <<FOOBAR
.git
.gitignore
$P4CONFIG
.myp4d
$P4IGNORE
*.swp
FOOBAR
	cat > "$baseDir/.gitignore" <<FOOBAR
.git
.gitignore
$P4CONFIG
.myp4d
$P4IGNORE
*.swp
FOOBAR
	cd "$baseDir"
	$P4BIN configure set serviceUser=$USER > /dev/null
	$P4BIN depot -d depot > /dev/null
	$P4BIN depot -o branch | $P4BIN depot -i > /dev/null
	$P4BIN protect -o | $P4BIN protect -i > /dev/null
	$P4BIN client -o branches-master | \
		sed -e 's=//branch/... //branches-master/...=//branch/master/... //branches-master/...=' \
			-e 's/noallwrite/allwrite/' \
			-e 's/normdir/rmdir/' \
			-e 's/nomodtime/modtime/' \
			-e 's/submitunchanged/revertunchanged/' | \
		$P4BIN client -i > /dev/null
	# Create the initial client
	$P4BIN client -o -t branches-master | \
		$P4BIN client -i > /dev/null

	exit 0
fi

if [ ! -d "$rootDir" ]; then
		$P4BIN "$@"
		exit $?
fi

curBranch=$($P4BIN client -o | \
		egrep "//branch/[^/]+/... " | head -1 | \
		sed -e 's=^.*//branch/==' -e 's=/[.][.][.].*$==')

P4USER=$USER
P4CLIENT=$USER

case $1 in
	init)
		echo "Already within a Perforce storage structure: $rootDir"
		exit 1
		;;
	server)
		if [ -z "$2" ]; then
			echo ":1666" > "$rootDir/myPort"
		else
			echo "$2" > "$rootDir/myPort"
		fi
		port=$(head -1 "$rootDir/myPort")
		$P4DBIN -r "$rootDir" -vserver=3 -Llog_file -p $port -d
		echo "Stop server by running: p4 -p $port admin stop"
		exit 0
		;;
	checkpoint)
		$P4BIN reconcile -m -f //$P4CLIENT/...
		oops=$($P4BIN reconcile -n -m -f //$P4CLIENT/... 2>&1 | \
			grep 'no file(s) to reconcile' | \
			wc -l)
		if [ $oops -eq 0 ]; then
			echo "There is a problem with reconcile. Fix it before continuing"
			exit 1
		fi
		cnt=$($P4BIN -ztag opened //$P4CLIENT/... 2>&1 | wc -l)
		if [ $cnt -gt 0 ]; then
			if [ -z "$2" ]; then
				$P4BIN submit -d "Auto-checkpoint"
			else
				$P4BIN submit -d "$2"
			fi
		fi
		exit 0
		;;
	switch)
		if [ "$2" == '-a' ]; then
			for f in $($P4BIN -ztag clients -e 'branches-*' | \
									grep '... client ' | \
									sed -e 's/branches-//' -e 's/... client //'); do
				if [ "$f" == "$curBranch" ]; then
					echo "$f *"
				else
					echo $f
				fi
			done
			exit 0
		fi
		if [ "$2" != '-b' ]; then
			toBranch="$2"
			if [ -z "$toBranch" ]; then
				echo "Current branch $curBranch"
				exit 0
			fi
			branch_client=$($P4BIN -ztag clients -e "branches-$2" | \
				grep "... client " | \
				sed -e 's/... client //')
			if [ -z "$branch_client" ]; then
				echo "Branch $2 does not exist, yet (use -b to create)"
				exit 1
			fi
			if [ "$toBranch" == "$curBranch" ]; then
				echo "Already there, wasn't that fast?"
				exit 0
			fi
			work=$($P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l)
			if [ $work -eq 0 ]; then
				work=$($P4BIN -ztag status //$P4CLIENT/... 2> /dev/null | wc -l)
			fi
			if [ $work -gt 0 ]; then
				echo "There are pending changes, how do you want to proceed?"
				# One day add in (m) Move changes
				read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \
					answer
				case $answer in
					s)
						newChange=$($P4BIN change -o | \
							sed -e "s/<enter description here>/Shelf for $curBranch/" | \
							$P4BIN change -i | sed -e 's/^Change //' -e 's/ .*//')
						$P4BIN reconcile -f -c $newChange //$P4CLIENT/...
						oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | \
							grep 'no file(s) to reconcile' | \
							wc -l)
						if [ $oops -eq 0 ]; then
							echo "There is a problem with reconcile. Fix it before continuing"
							exit 1
						fi
						$P4BIN shelve -c $newChange > /dev/null
						$P4BIN key "branchShelf-$USER-$curBranch" $newChange  > /dev/null
						$P4BIN revert -w //branch/$curBranch/... > /dev/null
						;;
					r)
						read -p 'New files will be deleted, edits discarded, etc. Are you sure? (y/n) ' \
							answer
						if [ "$answer" == "y" ]; then
							$P4BIN reconcile -f //$P4CLIENT/... > /dev/null 2> /dev/null
							$P4BIN revert -w //branch/$curBranch/...
						else
							echo "Aborting..."
							exit 1
						fi
						;;
					q)
						exit 0
						;;
				esac
			fi
			echo "Switch from $curBranch to $toBranch"
			if [ -z "$branch_client" ]; then
				$P4BIN client -o | \
					sed -e "s=//branch/[^/]*/... //$USER/...=//branch/$toBranch/... //$USER/...=" | \
					$P4BIN client -i > /dev/null
			else
				$P4BIN client -s -t $branch_client > /dev/null
			fi
			$P4BIN sync -q //$P4CLIENT/...  2> /dev/null
			curShelf=$($P4BIN key "branchShelf-$USER-$toBranch")
			if [ $curShelf != 0 ]; then
				echo "Unshelving $curShelf"
				$P4BIN unshelve -s $curShelf
				$P4BIN shelve -d -c $curShelf > /dev/null
				$P4BIN change -d $curShelf > /dev/null
				$P4BIN key -d "branchShelf-$USER-$toBranch" > /dev/null
			fi
			exit 0
		fi
		newBranch=$3
		if [ -z "$newBranch" ]; then
			echo "Current branch $curBranch"
			exit 0
		fi
		branch_client=$($P4BIN -ztag clients -e "branches-$2" | \
			grep "... client " | \
			sed -e 's/... client //')
		if [ -n "$branch_client" ]; then
			echo "Existing branch $newBranch"
			echo "Perhaps you meant to say: p4 switch $newBranch (i.e., no -b)"
			exit 1
		fi
		if [[ $newBranch == *-* ]]; then
			echo "Branch names cannot contain dashes."
			exit 1
		fi
		if [[ $newBranch =~ \  ]]; then
			echo "Branch names cannot contain spaces."
			exit 1
		fi
		work=$($P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l)
		if [ $work -eq 0 ]; then
			work=$($P4BIN -ztag status //$P4CLIENT/... 2> /dev/null | wc -l)
		fi
		if [ $work -gt 0 ]; then
			echo "There are pending changes, how do you want to proceed?"
			# One day add in (m) Move changes
			read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \
				answer
			case $answer in
				s)
					newChange=$($P4BIN change -o | \
						sed -e "s/<enter description here>/Shelf for $curBranch/" | \
						$P4BIN change -i | sed -e 's/^Change //' -e 's/ .*//')
					$P4BIN reconcile -f -c $newChange //$P4CLIENT/...
					oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | \
						grep 'no file(s) to reconcile' | \
						wc -l)
					if [ $oops -eq 0 ]; then
						echo "There is a problem with reconcile. Fix it before continuing"
						exit 1
					fi
					$P4BIN shelve -c $newChange > /dev/null
					$P4BIN key "branchShelf-$USER-$curBranch" $newChange  > /dev/null
					$P4BIN revert -w //branch/$curBranch/... > /dev/null
					;;
				r)
					read -p 'New files will be deleted, edits discarded, etc. Are you sure? (y/n) ' \
						answer
					if [ "$answer" == "y" ]; then
						$P4BIN reconcile -f //$P4CLIENT/... > /dev/null 2> /dev/null
						$P4BIN revert -w //branch/$curBranch/...
					else
						echo "Aborting..."
						exit 1
					fi
					;;
				q)
					exit 0
					;;
			esac
		fi
		emptyBranch=$($P4BIN -ztag files -m1 ... 2> /dev/null | egrep '^[.][.][.]' | wc -l)
		if [ $emptyBranch == 0 ]; then
			echo "No files to branch"
		else
			$P4BIN populate -d "Branching //branches/$curBranch to //branches/$newBranch" \
				//branch/$curBranch/... //branch/$newBranch/...
			if [ $? != 0 ]; then
				echo "Failed to create branch $2 mapping to //branch/$newBranch"
				exit 1
			fi
		fi
		echo "Switch from $curBranch to $newBranch"
		$P4BIN client -o -t branches-master branches-$newBranch | \
			sed -e "s=//branch/[^/]*/... //=//branch/$newBranch/... //=" | \
			$P4BIN client -i > /dev/null
		$P4BIN client -s -t branches-$newBranch > /dev/null
		$P4BIN sync -q //$P4CLIENT/... 2> /dev/null
		exit 0
		;;
	mergefrom)
		fromBranch="$2"
		if [ -z "$fromBranch" ]; then
			echo 'Please specify the branch from which to merge'
			exit 1
		fi
		branch_client=$($P4BIN -ztag clients -e "branches-$fromBranch" | \
			grep "... client " | \
			sed -e 's/... client //')
		if [ -z "$branch_client" ]; then
			echo "Branch $2 does not exist"
			exit 1
		fi
		if [ "$fromBranch" == "$curBranch" ]; then
			echo 'Mobius branches are not supported'
			exit 0
		fi
		work=$($P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l)
		if [ $work -eq 0 ]; then
			work=$($P4BIN -ztag status //$P4CLIENT/... 2> /dev/null | wc -l)
		fi
		if [ $work -gt 0 ]; then
			echo "There are pending changes, how do you want to proceed?"
			read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \
				answer
			case $answer in
				s)
					newChange=$($P4BIN change -o | \
						sed -e "s/<enter description here>/Shelf for $curBranch/" | \
						$P4BIN change -i | sed -e 's/^Change //' -e 's/ .*//')
					$P4BIN reconcile -f -c $newChange //$P4CLIENT/...
					oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | \
						grep 'no file(s) to reconcile' | \
						wc -l)
					if [ $oops -eq 0 ]; then
						echo "There is a problem with reconcile. Fix it before continuing"
						exit 1
					fi
					$P4BIN shelve -c $newChange > /dev/null
					$P4BIN key "branchShelf-$USER-$curBranch" $newChange  > /dev/null
					$P4BIN revert -w //branch/$curBranch/... > /dev/null
					;;
				r)
					read -p 'New files will be deleted, edits discarded, etc. Are you sure? (y/n) ' \
						answer
					if [ "$answer" == "y" ]; then
						$P4BIN reconcile -f //$P4CLIENT/... > /dev/null 2> /dev/null
						$P4BIN revert -w //branch/$curBranch/...
					else
						echo "Aborting..."
						exit 1
					fi
					;;
				q)
					exit 0
					;;
			esac
		fi
		integ_dir=""
		branch_branch=$($P4BIN -ztag branches -e "merge-$fromBranch-$curBranch" | \
			grep "... branch " | \
			sed -e 's/... branch //')
		if [ -z "$branch_branch" ]; then
			branch_branch=$($P4BIN -ztag branches -e "merge-$curBranch-$fromBranch" | \
				grep "... branch " | \
				sed -e 's/... branch //')
			integ_dir="-r"
		fi
		if [ -z "$branch_branch" ]; then
			# Simple integ, perhaps
			complexFrom=$($P4BIN -ztag client -o branches-$fromBranch | egrep '^... View1')
			complexTo=$($P4BIN -ztag client -o branches-$curBranch | egrep '^... View1')
			if [ "$complexFrom" != "" ]; then
				echo "$fromBranch is complex aka multiple lines in View"
				echo "Need to define a branchspec for merge-$fromBranch-$curBranch"
				$P4BIN -ztag client -o branches-$fromBranch | \
					egrep '^... View[0-9]' | \
					awk '{ print $3; }' > .$$.left
				$P4BIN -ztag client -o branches-$curBranch | \
					egrep '^... View[0-9]' | \
					awk '{ print $3; }' > .$$.right
				echo "Something like: p4 branchspec merge-$fromBranch-$curBranch"
				echo "View:"
				lcnt=$(wc -l .$$.left | awk '{ print $1;}' )
				rcnt=$(wc -l .$$.right | awk '{ print $1;}' )
				if [ $lcnt -lt $rcnt ]; then
					num=$(($rcnt - $lcnt))
					for(( i=0; i < $num; i++ )); do
						echo "//???/..." >> .$$.left
					done
				elif [ $rcnt -lt $lcnt ]; then
					num=$(($lcnt - $rcnt))
					for(( i=0; i < $num; i++ )); do
						echo "//???/..." >> .$$.right
					done
				fi
				paste .$$.left .$$.right | sed -e 's/^/	/'
				\rm .$$.left .$$.right
				exit 1
			fi
			if [ -n "$complexTo" ]; then
				echo "$curBranch is complex aka multiple lines in View"
				echo "Need to define a branchspec for merge-$fromBranch-$curBranch"
				$P4BIN -ztag client -o branches-$fromBranch | \
					egrep '^... View[0-9]' | \
					awk '{ print $3; }' > .$$.left
				$P4BIN -ztag client -o branches-$curBranch | \
					egrep '^... View[0-9]' | \
					awk '{ print $3; }' > .$$.right
				echo "Something like: p4 branchspec merge-$fromBranch-$curBranch"
				echo "View:"
				lcnt=$(wc -l .$$.left | awk '{ print $1;}' )
				rcnt=$(wc -l .$$.right | awk '{ print $1;}' )
				if [ $lcnt -lt $rcnt ]; then
					num=$(($rcnt - $lcnt))
					for(( i=0; i < $num; i++ )); do
						echo "//???/..." >> .$$.left
					done
				elif [ $rcnt -lt $lcnt ]; then
					num=$(($lcnt - $rcnt))
					for(( i=0; i < $num; i++ )); do
						echo "//???/..." >> .$$.right
					done
				fi
				paste .$$.left .$$.right | sed -e 's/^/	/'
				\rm .$$.left .$$.right
				exit 1
			fi
			$P4BIN integ //branch/$fromBranch/... //branch/$curBranch/...
			$P4BIN resolve -am
		else
			# Defined integ, simple
			echo "Merging using branchspec $branch_branch"
			$P4BIN integ -b $branch_branch $integ_dir
			$P4BIN resolve -am
		fi
		echo "Assuming no issues, you should now submit..."
		;;
	help)
		$P4BIN "$@"
		echo
		echo "Extra local commands:"
		echo "  p4 switch {branchName}         Switch to specified branch or report current"
		echo "  p4 switch -b newBranchName     Create new branch"
		echo "  p4 switch -a                   List the defined branches"
		echo 
		echo "  p4 branch FROM-TO              Define how to merge between two branches"
		echo "                                 Only needed if branches use multi-line views"
		echo "  p4 mergefrom BRANCHNAME        Run integ from named branch into current one"
		echo "                                 Only needed if branches use multi-line views"
		echo "  p4 checkpoint {description}    Reconcile and submit if needed"
		echo "  p4 server {port}               Start up a network accessible p4d linked to"
		echo "                                 this Perforce storage structure"
		echo "  p4 check                       Force a check for updates of myp4"
		;;
	*)
		$P4BIN "$@"
		exit $?
		;;
esac
# Change User Description Committed
#29 10704 Alan H Teague Updating to 14.2 p4/p4d binaries
#28 9724 Alan H Teague Clean up help
#27 9700 Alan H Teague Adding in p4 check command
#26 9175 Alan H Teague Revise new version check to work on systems without curl
#25 9136 Alan H Teague fix incorrect test and try to guess platform
#24 9029 Alan H Teague update the rev counter
#23 9028 Alan H Teague Remove 'p4 branch' 'p4 branches' 'p4 branchspec' 'p4 branchspecs'
Add 'p4 switch -a' to list all branches
Add 'p4 switch -b NEWBRANCH' to create new branch
Update help accordingly
#22 9027 Alan H Teague use client -s -t to switch client view
#21 9022 Alan H Teague use modtime and -m for checkpoint
#20 8982 Alan H Teague Suggest a merge branchspec for complex branches
#19 8974 Alan H Teague Exclude vi .swp files
Switch from back-tick to $() syntax for subcommands
#18 8921 Alan H Teague Allow for spaces in directory names
Update help for current set of commands
Prevent creating of branches which contain spaces
#17 8920 Alan H Teague Add in 'p4 server {port}' to launch network server
#16 8918 Alan H Teague Add 'p4 checkpoint' command to reconcile/submit
#15 8891 Alan H Teague don't check for new versions often
#14 8878 Alan H Teague Fix inserted issues, correct test
#13 8877 Alan H Teague Missing fi fi fi
#12 8876 Alan H Teague set version
#11 8875 Alan H Teague Add rcs'ism
#10 8874 Alan H Teague Fix reconcile bug - aka losing files
#9 8861 Alan H Teague Cleanup return codes
Normalize test of strings exist/not exist
#8 8860 Alan H Teague Modify myp4 to use existing P4CONFIG and P4IGNORE values.

This change also simplifies the root construction code a bit.

#review @alan_h_teague

Will make some immediate changes... ;-)
#7 8806 Alan H Teague Revert back to using branch instead of newbranch
Add in conversion from 'p4 branchspec(s)' to 'p4 branch(es)'
Add in hints to above
Append to 'p4 help'
Check for complex views in mergefrom command
#6 8802 Alan H Teague Update to add mergedown
#5 8799 Alan H Teague Create client template per branch instead of using filesystem structure
Enable user specific shelving and non-user specific use of branches
#4 8791 Alan H Teague Change from depot to branch for base depot for branches
Enable use of user-defined branches based off clients named USER-BRANCH
#3 8778 Alan H Teague Make it work with both basic p4 and wrapped p4
#2 8776 Alan H Teague Remove indirection of branch names
#1 8774 Alan H Teague Initial import of the myp4 project