#!/bin/bash me=${0/*\//} # $(echo $0 | sed -e 's=.*/\([^/][^/]*\)$=\1=') MYP4BIN=${0%\/$me} # $(echo $0 | sed -e "s=/$me$==") if [[ "$MYP4BIN" != /* ]]; then MYP4BIN="$PWD/$MYP4BIN" fi 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" ] || [ "$1" == 'update' ]; then echo "Downloading Perforce binaries for $MYPLAT ..." sourceSiteP4="ftp://ftp.perforce.com/perforce/r15.1" sourceSiteWeb="ftp://ftp.perforce.com/perforce/r12.1" which wget > /dev/null if [ $? -eq 0 ]; then wget -q -O "$P4BIN" "$sourceSiteP4/$MYPLAT/p4" wget -q -O "$P4DBIN" "$sourceSiteP4/$MYPLAT/p4d" wget -q -O "$P4WEBBIN" "$sourceSiteWeb/$MYPLAT/p4web" else curl -q -o "$P4BIN" "$sourceSiteP4/$MYPLAT/p4" curl -q -o "$P4DBIN" "$sourceSiteP4/$MYPLAT/p4d" curl -q -o "$P4WEBBIN" "$sourceSiteWeb/$MYPLAT/p4web" fi chmod a+x "$P4BIN" chmod a+x "$P4DBIN" chmod a+x "$P4WEBBIN" echo "Done." if [ "$1" == 'update' ]; then echo 'Update finished. If you meant to update your client use sync instead' exit 0 fi fi if [ ! -f "$P4DRAW" ]; then echo 'Missing link sighted' ln -s "$P4DBIN" "$MYP4BIN/p4d" echo "Linking $MYP4BIN/p4d.$BINTYPE.bin to p4d" fi # Check when requested only if [ "$1" == 'check' ]; then THIS_REV=9 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 if [ "$1" == 'check' ]; then exit 0 fi fi P4CONFIG=${P4CONFIG:-.p4config} 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') address=${address##... Address } # XXX Future - These two should be copied over to new remote spec # 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=${address%%@*} # $(echo "$address" | sed -e 's/@.*//') if [ ! -z "$owner" ]; then address=${address##*@} # $(echo "$address" | sed -e 's/^[^@]*@//') else owner=$P4USER # To catch @ with no userid specified address=${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 -c 'no file(s) to reconcile') 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') address=${address##... Address } 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 $me check Check for a newer version of this script $me update Download the lastest versions of the binaries but not the script. $me ignores Crudely list out matching .p4ignore entries 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 ;; update) cat <<FOOBAR $me update Update the underlying binaries This command will retrieve the lastest binaries for p4 p4d and possibly p4web. This hides the real 'p4 update' command, use 'p4 sync' instead. This is not a Perforce command. FOOBAR ;; ignores) cat <<FOOBAR $me ignores Crudely lists ignored items This command will run reconcile -n to try to identify any items that are being ignored do to some .p4ignore entry. This is not yet a Perforce command. FOOBAR ;; check) cat <<FOOBAR $me check Check for updates to this script This command will check to see if there is a newer version of this script. 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 if [ "$1" == 'ignores' ]; then $P4BIN -vmap=4 reconcile -n ... 2>&1 | grep REJECT exit $? fi $P4BIN "$@" exit $? else if [ -z "$2" ] || [ "$2" != '-p' ] || [ -z "$3" ] || [ -z "$4" ] || [ -z "$5" ] ; then cloneUsage # does not return fi if [ "$2" != '-p' ]; 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 owner=${address%%@*} # $(echo "$address" | sed -e 's/@.*//') if [ ! -z "$owner" ]; then address=${address##*@} # $(echo "$address" | sed -e 's/^[^@]*@//') else owner=$P4USER # To catch @ with no userid specified address=${address#@} # $(echo "$address" | sed -e 's/^@//') fi if [ "$owner" == "$address" ]; then owner=$P4USER fi streamArg='' remoteSpec='' P4USER=$owner else 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 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 -n $streamArg" $P4BIN -d "$baseDir" -u "$P4USER" init -C0 -n $streamArg # > /dev/null 2>&1 cd "$baseDir" if [ $? -ne 0 ]; then echo "Failed to create instance in $baseDir" exit 1 fi 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="$(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 [ "$1" == 'ignores' ]; then $P4BIN -vmap=4 reconcile -n ... 2>&1 | grep REJECT exit $? 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=$(pgrep -f "$P4WEBNAME.*$rootDir") 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 ;; 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') address=${address##... Address } 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 -c -e ' Users[0-9]') 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="$(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 usePort=$(cat "$rootDir/myPort") $P4BIN -p "$usePort" admin stop > /dev/null 2> /dev/null echo "Stopped server on $usePort" 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 -c 'no file(s) to reconcile') 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 |