#!/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 |