#!/bin/bash me=$(echo $0 | sed -e 's=.*/\([^/][^/]*\)$=\1=') hmm=$(which $me) if [ -z "$hmm" ]; then echo "I'm so lost, I can't find myself. Sorry" exit 1 fi MYP4BIN=$(echo $hmm | sed -e "s=/$me$==") what=$(uname) if [ "$what" == 'Darwin' ]; then MYPLAT='bin.darwin90x86_64' BINTYPE='mac' MD5BIN='md5' else kind=$(uname -p) if [ "$kind" == 'x86_64' ]; then MYPLAT='bin.linux26x86_64' BINTYPE='linux' MD5BIN='md5sum -' else if [ "$kind" == 'armv6l' ]; then MYPLAT='bin.linux26armhf' BINTYPE='pi' MD5BIN='md5sum -' fi fi fi if [ -z $MYPLAT ]; then echo 'I have no idea what system you are playing' exit 1 fi P4BIN=$MYP4BIN/p4.$BINTYPE.bin P4DRAW=$MYP4BIN/p4d P4DBIN=$P4DRAW.$BINTYPE.bin P4WEBNAME=p4web.$BINTYPE.bin P4WEBBIN=$MYP4BIN/$P4WEBNAME if [ ! -f $P4BIN ] || [ ! -f $P4DBIN ]; then echo "Downloading Perforce binaries for $MYPLAT ..." which wget > /dev/null if [ $? -eq 0 ]; then wget -q -O $P4BIN ftp://ftp.perforce.com/perforce/r15.1/$MYPLAT/p4 wget -q -O $P4DBIN ftp://ftp.perforce.com/perforce/r15.1/$MYPLAT/p4d wget -q -O $P4WEBBIN ftp://ftp.perforce.com/perforce/r12.1/$MYPLAT/p4web else curl -q -o $P4BIN ftp://ftp.perforce.com/perforce/r15.1/$MYPLAT/p4 curl -q -o $P4DBIN ftp://ftp.perforce.com/perforce/r15.1/$MYPLAT/p4d curl -q -o $P4WEBBIN ftp://ftp.perforce.com/perforce/r12.1/$MYPLAT/p4web fi chmod a+x $P4BIN chmod a+x $P4DBIN chmod a+x $P4WEBBIN echo "Done." fi if [ ! -f $P4DRAW ]; then echo 'Missing link sighted' ln -s $P4DBIN $MYP4BIN/p4d echo "Linking $MYP4BIN/p4d.$BINTYPE.bin to p4d" 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/myb4/b4?v=$NEWER_REV \ > /dev/null 2> /dev/null if [ $? -eq 0 ]; then echo "A newer version of myb4 is available" echo "https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myb4/b4" 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/myb4/b4?v=$NEWER_REV) if [ "$cur" == "200" ]; then echo "A newer version of myb4 is available" echo "https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myb4/b4" elif [ "$1" == "check" ]; then echo "No newer version is available" exit 0 fi fi fi rootDir=$($P4BIN -ztag set | \ egrep "^P4CONFIG=$P4CONFIG" | \ cut -d "'" -f 2 | \ sed "s/$P4CONFIG/.p4root/") RAWP4PORT="rsh:/bin/sh -c \"umask 077 && exec $P4DBIN -i -J off -r '$rootDir'\"" makeGroup () # (group owner subgroups protects) { exists=$($P4BIN groups | grep -e "$1") if [ -z "$exists" ]; then $P4BIN group -i > /dev/null <<FOOBAR Group: $1 MaxResults: unset MaxScanRows: unset MaxLockTime: unset Timeout: 999999 PasswordTimeout: unset Subgroups: $3 Owners: $2 Users: FOOBAR if [ ! -z "$4" ]; then $P4BIN protect -o | sed "\$,\$ s=\$= $4=" | $P4BIN protect -i > /dev/null fi fi } addToGroup () # (group userid) { group=$1 userid=$2 $P4BIN group -o $group | sed "\$,\$ s/\$/ $userid/" | $P4BIN group -i > /dev/null $P4BIN user -f -o $userid | $P4BIN user -if > /dev/null } delFromGroup () # (group userid) { group=$1 userid=$2 $P4BIN group -o $group | egrep -v "^[ ][ ]*$userid\$" | $P4BIN group -i > /dev/null $P4BIN user -d -f $userid > /dev/null 2>&1 } reformatRemote () # oldRemoteName { remoteName=$1 echo Converting remote $remoteName to local configuration address=$($P4BIN -ztag remote -o $remoteName | egrep '^... Address' | \ sed -e 's/... Address //') options=$($P4BIN -ztag remote -o $remoteName | egrep '^... Options' | \ sed -e 's/... Options //') description=$($P4BIN -ztag remote -o $remoteName | egrep '^... Description' | \ sed -e 's/... Description //') lls=$($P4BIN -ztag remote -o $remoteName | egrep '^... DepotMap' | \ sed -e 's/... DepotMap[0-9]* //' -e 's=^\(//.*\) //.*=\1=') rrs=$($P4BIN -ztag remote -o $remoteName | egrep '^... DepotMap' | \ sed -e 's/... DepotMap[0-9]* //' -e 's=^.* \(//.*\)=\1=') IFS=$'\n' lefts=($lls) IFS=$'\n' rights=($rrs) for(( x=0; x < ${#lefts[*]}; x++)); do curStream=$(echo ${lefts[$x]} | sed -e 's=//[^/]*/==' -e 's=/[.][.][.]==') mapping=$(echo ${rights[$x]} | sed -e 's=/[.][.][.]==') setupRemote done } setupRemote () { owner=$(echo $address | sed -e 's/@.*//') if [ ! -z "$owner" ]; then address=$(echo $address | sed -e 's/^[^@]*@//') else owner=$P4USER # To catch @ with no userid specified address=$(echo $address | sed -e 's/^@//') fi if [ "$owner" == "$address" ]; then owner=$P4USER fi remote=$($P4BIN key push-$curStream) if [ "$remote" != '0' ]; then if [ "push-$owner:$address" != $remote ]; then echo "Changing remote server details for $curStream - NOT IMPLEMENTED" exit 1 fi fi existing=$($P4BIN remotes | grep "push-$owner:$address") if [ -z "$existing" ]; then echo 'Creating new mapping' $P4BIN -u $owner -p $address login -s > /dev/null if [ $? -ne 0 ]; then echo "Please run '$me -u $owner -p $address login'" exit 1 fi $P4BIN remote -i > /dev/null <<FOOBAR RemoteID: push-$owner:$address Address: $address Owner: $owner Description: Push Mapping for $owner @ $address DepotMap: //$streamDepot/$curStream/... $mapping/... FOOBAR $P4BIN key push-$curStream push-$owner:$address > /dev/null else if [ "$remote" != '0' ]; then echo 'Replacing previous mapping' $P4BIN remote -o push-$owner:$address | \ sed \ -e "s=^[ ][ ]*//$streamDepot/$curStream/... .*\$= //$streamDepot/$curStream/... $mapping/...=" \ | \ $P4BIN remote -i > /dev/null else echo 'Appending to existing mapping' $P4BIN remote -o push-$owner:$address | \ sed "\$,\$ s=\$= //$streamDepot/$curStream/... $mapping/...=" | \ $P4BIN remote -i > /dev/null $P4BIN key push-$curStream push-$owner:$address > /dev/null fi fi $P4BIN -ztag remote -o push-$owner:$address | \ egrep '^[.][.][.] *(Address|DepotMap|Owner)' | \ sed -e 's/Address/RemoteServer:/' \ -e 's/Owner/RemoteUserID:/' \ -e 's/DepotMap[0-9][0-9]*/ /' \ -e 's/[.][.][.]//' } pendingWork () { 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 if [ $submitPending -eq 1 ]; then read -p '(s) Submit changes (r) Revert changes (q) Quit? ' \ answer else read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \ answer fi case $answer in s) $P4BIN reconcile -f //$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 if [ $submitPending -eq 1 ]; then read -p 'Change description? ' \ answer if [ -z "$answer" ]; then $P4BIN submit -d 'Checkpoint work' else $P4BIN submit -d "$answer" fi fi ;; 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 //$streamDepot/$curStream/... else echo 'Aborting...' exit 1 fi ;; q) exit 0 ;; esac fi } fetchCurrent () { if [ ! -z "$1" ] && [ "$1" != '-a' ] && [ "$1" != '-u' ]; then echo 'Unknown argument' exit 1 fi map=$($P4BIN key push-$curStream) if [ -z "$map" ]; then echo Please define a map before fetching exit 1 fi submitPending=1 pendingWork address=$($P4BIN -ztag remote -o $map | egrep '^[.][.][.] *Address' | \ sed -e 's/Address//' -e 's/[.][.][.]//') if [ -z "$address" ]; then echo Map $map has a malformed address exit 1 fi mapping=$($P4BIN -ztag remote -o $map | \ egrep '^[.][.][.] *DepotMap' | \ egrep "//$streamDepot/$curStream" | \ awk '{print $4;}') if [ -z "$mapping" ]; then echo Map $map has a malformed DepotMap for "//$streamDepot/$curStream" exit 1 fi owner=$($P4BIN -ztag remote -o $map | egrep '^[.][.][.] *Owner' | \ awk '{print $3;}') if [ -z "$owner" ]; then owner=$P4USER fi $P4BIN -u $owner -p $address login -s > /dev/null if [ $? -ne 0 ]; then echo "Please run '$me -u $owner -p $address login'" exit 1 fi if [ "$owner" != "$P4USER" ]; then addToGroup 'alteregos' "$owner" fi if [ "$1" == '-u' ] || [ "$2" == '-u' ]; then unsub='-u' else unsub='' fi if [ "$1" != '-a' ] && [ "$2" != '-a' ]; then echo "Trying to fetch $mapping from remote $address" echo $P4BIN -u $owner fetch $unsub -v -r $map "//$streamDepot/$curStream/..." $P4BIN -u $owner fetch $unsub -v -r $map "//$streamDepot/$curStream/..." # | grep 'Usage' else echo "Trying to fetch all streams associated with $address" echo $P4BIN -u $owner fetch $unsub -v -r $map $P4BIN -u $owner fetch $unsub -v -r $map # | grep 'Usage' fi #cnt=$($P4BIN -u $owner fetch -v -r $map $mapping 2> /dev/null | wc -l) $P4BIN sync //... > /dev/null if [ "$owner" != "$P4USER" ]; then delFromGroup 'alteregos' "$owner" fi } helpMe () { if [ -z "$1" ]; then $P4BIN "$@" exit $? fi if [ -z "$2" ]; then $P4BIN "$@" exit $? fi if [ "$2" == '-r' ]; then $P4BIN help $3 exit $? fi case $2 in dvcs) cat <<FOOBAR Using Perforce for Distributed Version Control $me init {-c stream} {rootDir} Create local server $me clone -p ADDRESS -f PATH {rootDir} Create local server based on remote $me clone -p ADDRESS -r REMOTE {rootDir} Create local server based on remote $me switch Which stream am I on? $me switch -l List all streams $me switch -c NEW_STREAM Create new stream from this one $me switch -cm NEW_STREAM Create new empty stream $me switch -mc NEW_STREAM Create new empty stream $me switch STREAM Switch to STREAM $me switch -d STREAM Hide a stream $me switch -r STREAM Recover a hidden stream $me switch -h List hidden streams $me map REMOTE_URL Define remote for cur STREAM {userid@}{ssl:}host:port://depot_path $me push {-a} Push current stream to defined remote $me fetch {-a} Fetch from defined remote to current stream $me mergefrom STREAM Run merge from named stream into current one $me checkpoint {description} Reconcile and submit if needed $me server {port} Start up a network accessible p4d $me server stop Shutdown the network acccessible p4d $me allow {{-a}USER PWD {p}} Allow user/password to fetch {and push} $me disallow {USER} Disallow user from fetching $me web Bring up p4web on the local server Run '$me help' on any of the above commands for more details FOOBAR ;; init) cat <<FOOBAR $me init {-c streamDepot} {rootDir} Create a personal Perforce server configured for distributed use. The optional rootDir argument defines the directory to use for this new server installation. The directory will be created. By default, this server is non-Unicode and case-sensitive. The optional -c argument defines the branching structure to use other than //stream/* Note: This wrapper obscures the underlying command FOOBAR ;; clone) cat <<FOOBAR $me clone -p host:port -f FILE_SPEC {rootDir} $me clone -p host:port -r REMOTE_SPEC {rootDir} Create a personal Perforce server configured for distributed use. The optional rootDir argument defines the directory to use for this new server installation. The directory will be created. By default, this server is non-Unicode and case-sensitive. You can specify 'MYP4=userid $me clone ...' to specify the userid to use on the remote server for authentication. The first form calls the underlying p4 clone command and then normalizes the system to confirm to this script's conversions. The second form calls the underlying p4 clone command and then normalizes the system to conform to this script's conventions. Note: This wrapper obscures the underlying command FOOBAR ;; switch) cat <<FOOBAR $me switch Which stream am I on? $me switch -l List all streams $me switch -c NEW_STREAM Create new stream from this one $me switch -cm NEW_STREAM Create new empty stream $me switch -mc NEW_STREAM Create new empty stream $me switch STREAM Switch to STREAM $me switch -d STREAM Hide a stream $me switch -r STREAM Recover a hidden stream $me switch -h List hidden streams Local branching is controlled using this command. The wrapper calls the underlying Perforce switch command for all of this functionality. With no arguments, it returns the name of the current stream. When called with the following arguments: -l returns the list of all streams -c creates a new stream of the specified name and populates it based on the current stream -cm create a new empty stream of the specified name -mc create a new empty stream of the specified name STREAM switches to the specified stream after shelving any pending work. The -d argument is used to hide a stream from being used or listed. No content is removed from the underlying storage and no remote mappings are changed. Use the -r option to restore a hidden stream. The -h argument is used to list out the hidden streams. FOOBAR ;; map) cat <<FOOBAR $me map $me map REMOTE_URL With no arguments, this returns the all mappings for the remote server associated with the current stream. The REMOTE_URL defines the mapping from the current stream and the specified location on a remote server. This mapping will be aggregated with any other mapping targeting the same remote server. The REMOTE_URL is in the following format: {userid@}{ssl:}host:port://depot_path If there is currently a map defined for this stream, then this will replace that mapping with this new one. This is not a Perforce command. This is a wrapper around the 'p4 remote' command. You may want to read '$me help remote' and '$me help remotes' FOOBAR ;; push) cat <<FOOBAR $me push {-a} Push current stream to defined remote This command looks up the associated remote for this stream and invokes the underlying 'p4 push' command with the appropriate arguments. If there is pending work, then you will be asked if you want to submit or revert the changes. The optional -a argument is used to push all streams associated with the remote linked to the current stream. Note: This wrapper obscures the underlying command FOOBAR ;; fetch) cat <<FOOBAR $me fetch {-a} Fetch from defined remote to current stream This command looks up the associated remote for this stream and invokes the underlying 'p4 fetch' command with the appropriate arguments. If there is pending work, then you will be asked if you want to submit or revert the changes. The optional -a argument is used to fetch all streams associated with the remote linked to the current stream. Note: This wrapper obscures the underlying command FOOBAR ;; mergefrom) cat <<FOOBAR $me mergefrom STREAM Run integ from named stream into current one This command runs 'p4 merge --from STREAM'. It then runs 'p4 resolve -as'. This does not submit the merged and resolved files, you must do that manually. This is not a Perforce command. You may want to look at the help for p4 merge. FOOBAR ;; checkpoint) cat <<FOOBAR $me checkpoint {description} Reconcile and submit if needed This command runs 'p4 reconcile' and then 'p4 submit -d {description}' This is not a Perforce command. FOOBAR ;; web) cat <<FOOBAR $me web Bring up p4web This command will either startup or shutdown a p4web browse instance running against the local server. This p4web is not network accessible. This is not a Perforce command. FOOBAR ;; server) cat <<FOOBAR $me server {port} Start up a network accessible p4d $me server stop Shutdown the network acccessible p4d This command invokes p4d on the specified port or 1666 for use either by remote user or by some local client like p4eclipse or p4v. By default, the local server is restricted to only the individual user. Use the '$me allow' command to enable others to fetch from this networked server. The 'stop' argument will shutdown this network accessible server. This is not yet a Perforce command. FOOBAR ;; allow) cat <<FOOBAR $me allow {-a} {USER PASSWORD {p}} Allow user/password to fetch {and push} This command creates the named user and sets their password accordingly. The optional 'p' argument enables the named user to 'push' to this server and is not recommended except for testing purposes. 'push' implies '-a' so all streams can be fetched and pushed to/from. The -a argument indicates that all streams should be accessible to the specified user. Without the -a, only the USER can only fetch from the current stream. With no arguments, this command lists the users which are currently allowed to fetch from this server when a networked server is running. This is not yet a Perforce command. FOOBAR ;; disallow) cat <<FOOBAR $me disallow {USER} Disallow user from fetching This command removes the named user from the system along with all access rules defined for them. This removes all access for the specified USER. With no arguments, this command lists the users which are currently allowed to fetch from this server when a networked server is running. This is not yet a Perforce command. FOOBAR ;; *) $P4BIN "$@" exit $? ;; esac echo " Run '$me help -r TOPIC' to get the underlying Perforce help" exit 0 } cloneUsage () { echo 'Usage: $me clone -p HOST:PORT -r REMOTE_SPEC {targetDir}' echo ' $me clone -p HOST:PORT -f FILE_SPEC {targetDir}' echo ' Use MYP4=userid $me clone ... to specify remote userid' exit 1 } if [ "$1" == 'help' ] || ( [ "$2" == '-r' ] && [ "$3" == 'help' ] ) ; then helpMe "$@" # helpMe should never return fi if [ "$rootDir" == 'noconfig' ]; then baseDir="$PWD" if [ "$1" == 'switch' ]; then echo exit 0 fi if [ "$1" == 'init' ]; then if [ "$2" == '-h' ]; then helpMe help init # helpMe should never return fi fi streamDepot='stream' if [ "$1" != 'init' ]; then if [ "$1" != 'clone' ]; then $P4BIN "$@" exit $? else if [ -z "$2" ] || [ "$2" != '-p' ] || [ -z "$3" ] || [ -z "$4" ] || [ -z "$5" ] ; then cloneUsage # does not return fi if [ -z $MYP4 ]; then P4USER=$USER else P4USER=$MYP4 fi streamArg='' address=$3 remoteSpec='' mapping='' if [ "$4" == '-r' ]; then remoteSpec=$5 mapping='' else if [ "$4" == '-f' ]; then remoteSpec='' mapping=$5 else cloneUsage # does not return fi fi $P4BIN -u $P4USER -p $address login -s > /dev/null if [ $? -ne 0 ]; then echo "Please run '$me -u $P4USER -p $address login" exit 1 fi if [ ! -z "$6" ]; then baseDir="$PWD/$6" if [ -d $baseDir ]; then echo 'That directory already exists' exit 1 fi else baseDir="$PWD" fi fi else if [ -z $MYP4 ]; then P4USER=$USER else P4USER=$MYP4 fi if [ "$2" == '-c' ]; then if [ -z "$3" ]; then echo 'Missing stream specification' exit 1 fi streamDepot=$(echo $3 | sed -e 's=^.*//==' -e 's=/.*==') streamArg="-c $3" baseDir="$4" else streamArg='' baseDir="$2" fi if [ ! -z "$baseDir" ]; then baseDir="$PWD/$baseDir" if [ -d $baseDir ]; then echo 'That directory already exists' exit 1 fi else baseDir="$PWD" fi address='' mapping='' fi echo 'Initializing...' rootDir="$baseDir/.p4root" if [ -d "$rootDir" ]; then echo "Perforce storage already maps to $rootDir" exit 1 fi if [ "$1" == 'init' ]; then echo $P4BIN -d $baseDir -u $P4USER init -C0 $streamArg $P4BIN -d $baseDir -u $P4USER init -C0 -n $streamArg > /dev/null 2>&1 cd $baseDir else if [ -z "$remoteSpec" ]; then echo $P4BIN -d $baseDir -u $P4USER clone -p $address -f $mapping $P4BIN -d $baseDir -u $P4USER clone -p $address -f $mapping if [ $? -ne 0 ]; then echo 'Aborting' exit 1 fi # clone using a depot path creates a remote named origin remoteSpec='origin' else echo $P4BIN -d $baseDir -u $P4USER clone -p $address -r $remoteSpec $P4BIN -d $baseDir -u $P4USER clone -p $address -r $remoteSpec if [ $? -ne 0 ]; then echo 'Aborting' exit 1 fi fi cd $baseDir reformatRemote origin $P4BIN remote -d origin fi sed -e 's/ -i -J off -r / -i -vdvcs=5 -J off -r /' .p4config > .tmpconfig mv -f .tmpconfig .p4config $P4BIN configure set serviceUser=$P4USER > /dev/null $P4BIN configure set monitor=0 > /dev/null rm -f .p4root/p4_log.txt .p4root/journal rmdir .p4root/backups # Setup for potential ssl network server mkdir .p4root/.p4ssldir chmod u+rwx .p4root/.p4ssldir chmod go-rwx .p4root/.p4ssldir P4SSLDIR="$baseDir/.p4root/.p4ssldir" $P4DBIN -Gc -r .p4root seed=$(echo $(openssl rand -base64 11) $(date)) userpwd=$(echo $seed | $MD5BIN | head -c11) echo "P4PASSWD=$userpwd" >> .p4config $P4BIN passwd -P "$userpwd" > /dev/null # Create fetch/push/alterego groups makeGroup alteregos $P4USER '' addToGroup alteregos $P4USER makeGroup fetch-group $P4USER alteregos makeGroup push-group $P4USER alteregos $P4BIN protect -i > /dev/null <<FOOBAR Protections: read group fetch-group * //$streamDepot/... write group push-group * //$streamDepot/... super group alteregos * //... FOOBAR exit 0 fi if [ ! -d "$rootDir" ]; then $P4BIN "$@" exit $? fi curStream=$($P4BIN switch | sed -e 's/ [*]//') P4USER=$($P4BIN set P4USER | sed -e 's/^P4USER=//' -e 's/ .config.$//') P4CLIENT=$($P4BIN set P4CLIENT | sed -e 's/^P4CLIENT=//' -e 's/ .config.$//') streamDepot=$($P4BIN client -o | egrep '^Stream' | sed -e 's=^Stream:.*//==' -e 's=/.*==') case $1 in init) if [ "$2" == '-h' ]; then helpMe help init fi echo "Already within a Perforce storage structure: $rootDir" exit 1 ;; web) if [ ! -f $P4WEBBIN ]; then echo 'Missing optional Perforce server binary' echo "Get p4web from $MYPLAT and name it p4web.$BINTYPE.bin" echo "in directory $MYP4BIN. Remember to chmod a+x" exit 1 fi cur=$(ps | grep $P4WEBNAME | head -1 | awk '{ print $8; }') if [ -z "$cur" ]; then $P4WEBBIN -b -l -w 8080 -p "$RAWP4PORT" > /dev/null & if [ "$what" == 'Darwin' ]; then open http://localhost:8080 fi echo "Run '$me web' again to shut it down" else echo 'Shutdown p4web' killall $P4WEBNAME fi exit 0 ;; status) $P4BIN status exit 0 ;; map) # p4 map - return current mapping # p4 map {userid@}{ssl:}host:port://:depot_path - map current stream with remote location if [ ! -z "$2" ]; then address=$(echo $2 | sed -e 's=://.*==' -e 's/^p4://') mapping=$(echo $2 | sed -e 's=.*//=//=' -e 's=/[.][.][.]$==') if [[ ! "$mapping" =~ '//' ]]; then echo "Usage: $me map {userid@}{ssl:}host:port://depot_path" exit fi setupRemote else map=$($P4BIN key push-$curStream) if [ "$map" != '0' ]; then $P4BIN -ztag remote -o $map | \ egrep '^[.][.][.] *(Address|DepotMap|Owner)' | \ sed -e 's/Address/RemoteServer:/' \ -e 's/Owner/RemoteUserID:/' \ -e 's/DepotMap[0-9][0-9]*/ /' \ -e 's/[.][.][.]//' else echo 'No mapping defined for this stream' fi fi exit 0 ;; fetch) fetchCurrent $2 $3 ;; push) map=$($P4BIN key push-$curStream) if [ -z "$map" ]; then echo Please define a map before fetching exit 1 fi submitPending=1 pendingWork address=$($P4BIN -ztag remote -o $map | egrep 'Address' | \ sed -e 's/Address//' -e 's/[.][.][.]//') if [ -z "$address" ]; then echo Map $map has a malformed address exit 1 fi mapping=$($P4BIN -ztag remote -o $map | \ egrep 'DepotMap' | egrep "//$streamDepot/$curStream" | \ awk '{print $3;}') if [ -z "$mapping" ]; then echo Map $map has a malformed DepotMap for "//$streamDepot/$curStream" exit 1 fi owner=$($P4BIN -ztag remote -o $map | egrep '^[.][.][.] *Owner' | \ awk '{print $3;}') if [ -z "$owner" ]; then owner=$P4USER fi $P4BIN -u $owner -p $address login -s > /dev/null if [ $? -ne 0 ]; then echo "Please run '$me -u $owner -p $address login'" exit 1 fi if [ "$owner" != "$P4USER" ]; then addToGroup 'alteregos' "$owner" fi if [ "$2" != '-a' ]; then echo $P4BIN -u $owner push -r $map -v "//$streamDepot/$curStream/..." $P4BIN -u $owner push -r $map -v "//$streamDepot/$curStream/..." else echo $P4BIN -u $owner push -r $map -v $P4BIN -u $owner push -r $map -v fi if [ "$owner" != "$P4USER" ]; then delFromGroup 'alteregos' "$owner" fi exit 0 ;; disallow) # user if [ -z "$2" ]; then cnt=$($P4BIN -ztag group -o fetch-$curStream-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' | wc -l) if [ $cnt -gt 0 ]; then echo "The following users are allowed to fetch from $curStream:" $P4BIN -ztag group -o fetch-$curStream-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' echo fi cnt=$($P4BIN -ztag group -o fetch-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' | wc -l) if [ $cnt -gt 0 ]; then echo 'The following users are allowed to fetch from any stream:' $P4BIN -ztag group -o fetch-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' echo fi cnt=$($P4BIN -ztag group -o push-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' | wc -l) if [ $cnt -gt 0 ]; then echo 'The following users are allowed to push:' $P4BIN -ztag group -o push-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' echo fi exit 0 fi if [ "$2" != "$P4USER" ]; then for g in $($P4BIN groups); do delFromGroup $g "$2" done echo User $2 can no longer fetch when networked else echo 'You cannot remove yourself' fi numPushers=$($P4BIN -ztag group -o push-group | egrep -e ' Users[0-9]' | wc -l) if [ "$numPushers" -eq 0 ]; then $P4BIN configure set server.allowpush=1 > /dev/null fi exit 0 ;; allow) # user password - enable fetch by user if [ -z "$2" ]; then cnt=$($P4BIN -ztag group -o fetch-$curStream-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' | wc -l) if [ $cnt -gt 0 ]; then echo "The following users are allowed to fetch from $curStream:" $P4BIN -ztag group -o fetch-$curStream-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' echo fi cnt=$($P4BIN -ztag group -o fetch-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' | wc -l) if [ $cnt -gt 0 ]; then echo 'The following users are allowed to fetch from any stream:' $P4BIN -ztag group -o fetch-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' echo fi cnt=$($P4BIN -ztag group -o push-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' | wc -l) if [ $cnt -gt 0 ]; then echo 'The following users are allowed to push:' $P4BIN -ztag group -o push-group | egrep '^[.][.][.] Users' | awk '{ print "\t", $3; };' echo fi exit 0 fi if [ "$2" == '-a' ]; then allAccess=1 useUser=$3 usePassword=$4 pushFlag=$5 else allAccess=0 useUser=$2 usePassword=$3 pushFlag=$4 fi if [ "$useUser" == "$P4USER" ]; then echo 'You are already in the group' exit 0 fi if [ -z "$usePassword" ]; then echo "You must specify a password for $useUser to use when fetching" seed=$(echo $(openssl rand -base64 11) $(date)) userpwd=$(echo $seed | $MD5BIN | head -c11) echo "Try: $me allow $useUser $userpwd" exit 1 fi if [ $allAccess -eq 1 ]; then addToGroup 'fetch-group' "$useUser" echo User $useUser can fetch any stream using password \"$usePassword\" else makeGroup "fetch-$curStream-group" $P4USER alteregos "read group fetch-$curStream-group * //$streamDepot/$curStream/..." addToGroup "fetch-$curStream-group" "$useUser" echo User $useUser can fetch from $curStream using password \"$usePassword\" fi if [ ! -z "$pushFlag" ]; then addToGroup 'push-group' "$useUser" echo User can also push to this server $P4BIN configure set server.allowpush=3 > /dev/null fi $P4BIN passwd -P $usePassword $useUser > /dev/null exit 0 ;; server) # server stop if [ "$2" == 'stop' ]; then if [ ! -f "$rootDir/myPort" ]; then echo 'No server is running' exit 0 fi $P4BIN -p $(cat $rootDir/myPort) admin stop > /dev/null 2> /dev/null echo "Stopped server on $(cat $rootDir/myPort)" rm -f $rootDir/myPort exit 0 fi # server {port} myip=$(ifconfig | grep inet | grep broadcast | awk '{ print $2; }') if [ -f "$rootDir/myPort" ]; then whichPort=$(cat $rootDir/myPort) $P4BIN -p $whichPort help > /dev/null 2> /dev/null if [ $? -eq 0 ]; then if [ -z "$2" ]; then if [ $whichPort == ':1666' ]; then echo "Server is already running on $whichPort" else echo "Server is already running on $whichPort, not on :1666" fi else if [ $whichPort == "$2" ]; then echo "Server is already running on $whichPort" else echo "Server is already running on $whichPort, not on $2" fi fi if [ -z $myip ]; then echo Fetchers should use \"$me map localhost$whichPort://$streamDepot/$curStream\" else echo Fetchers should use \"$me map ${myip}$whichPort://$streamDepot/$curStream\" fi exit 0 fi else if [ -z "$2" ]; then whichPort=':1666' else whichPort="$2" fi $P4BIN -p $whichPort help > /dev/null 2> /dev/null if [ $? -eq 0 ]; then echo "Some server is already running on $whichPort, aborting" exit 1 fi fi echo $whichPort > "$rootDir/myPort" P4SSLDIR="$rootDir/.p4ssldir" $P4DBIN -r "$rootDir" -vdvcs=5 -J off -p $whichPort -d > /dev/null 2> /dev/null echo "Stop server by running: $me server stop" if [ -z $myip ]; then echo Fetchers should use \"$me map localhost$whichPort://$streamDepot/$curStream\" else echo Fetchers should use \"$me map ${myip}$whichPort://$streamDepot/$curStream\" fi exit 0 ;; checkpoint) $P4BIN reconcile -f //$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 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) # switch reconciles and shelves by default if [ "$2" == '-h' ]; then $P4BIN -ztag keys -e 'stream-*' | egrep '^[.].*key ' | sed -e 's/^....key stream-//' -e 's/$/ (hidden)/' exit 0 fi if [ "$2" == '-d' ]; then if [ "$3" == "$curStream" ]; then echo You cannot hide the ground under your feet, switch to another stream first exit 1 fi if [ -z "$3" ]; then echo Please specify which stream to hide exit 1 fi echo Hiding stream $3, use -r to recover it stream=$($P4BIN stream -o //$streamDepot/$3 | egrep -v '^Owner:') $P4BIN key stream-$3 "$stream" > /dev/null $P4BIN stream -d //$streamDepot/$3 > /dev/null exit $? fi if [ "$2" == '-r' ]; then if [ "$3" == "$curStream" ]; then echo Wherever you are, there you are. Recoved what was never hidden exit 1 fi if [ -z "$3" ]; then echo Please specify which stream to recover exit 1 fi exists=$($P4BIN switch -l | egrep "^$3\$") if [ ! -z "$exists" ]; then echo "$3 isn't hidden, no need to recover" exit 1 fi exists=$($P4BIN key stream-$3) if [ -z "$exists" ]; then echo "$3 never existed" exit 1 fi cat <<FOOBAR | $P4BIN stream -i > /dev/null $exists Owner: $P4USER FOOBAR echo Restored $3 and switched to it $P4BIN switch $3 $P4BIN key -d stream-$3 > /dev/null exit $? fi if [ "$2" == '-c' ] || [ "$2" == '-mc' ] || [ "$2" == '-cm' ]; then exists=$($P4BIN key $3-stream) if [ "$exists" != '0' ]; then echo Seems that $3 is hidden, recover using $me switch -r $3 exit 1 fi fi $P4BIN "$@" exit $? ;; mergefrom) fromStream="$2" if [ -z "$fromStream" ]; then echo 'Please specify the stream from which to merge' exit 1 fi if [ "$fromStream" == "$curStream" ]; then echo 'Mobius streams are not supported' exit 0 fi stream_client=$($P4BIN switch -l | egrep "^$fromStream$") if [ -z "$stream_client" ]; then echo "Stream $2 does not exist" exit 1 fi submitPending=1 pendingWork # Simple merge, perhaps $P4BIN merge --from $fromStream opened=$($P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l) resolve=$($P4BIN -ztag resolve -n //$P4CLIENT/... 2> /dev/null | wc -l) if [ $resolve -gt 0 ]; then $P4BIN resolve -am fi if [ $opened -gt 0 ]; then echo 'Assuming no issues, you should now submit...' else echo 'No merge was necessary' fi exit 0 ;; *) $P4BIN "$@" exit $? ;; esac
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#10 | 13977 | Alan H Teague | Fix issue with missing P4CONFIG | ||
#9 | 12402 | Alan H Teague | Fixing test for running p4web | ||
#8 | 12166 | Alan H Teague | Updating for the GA release of 2015.1 p4d | ||
#7 | 11678 | Alan H Teague | Update rev counter | ||
#6 | 11677 | Alan H Teague |
Fix issue with cmd result test Add in additional help Add in pseudo ignores command Add in update command |
||
#5 | 11575 | Alan H Teague |
Fix relative invocation of script for binary directory Parameterize the wget/curl call to allow for alternative sources |
||
#4 | 11574 | Alan H Teague |
Fix a few more broken issues Remove auto check for updates and explicitly describe p4 check |
||
#3 | 11573 | Alan H Teague | Fix the broken bits from the sweeping changes of the earlier change | ||
#2 | 11569 | Alan H Teague |
Massive amount of script cleanup thanks to checkscript.net Fix rev number for update check |
||
#1 | 11528 | Alan H Teague |
Experimental usability wrapper for the 15.1 beta p4d/p4 This is for using perforce for distributed versioning - Sets up security of some sort for private instances - Allow/Disallow/Server commands for peer-to-peer sharing - Using different userids on remote servers - Simple case remote map definitions |