Wrapper to use custom p4 scripts.
authorIain Patterson <me@iain.cx>
Fri, 15 Apr 2011 15:07:08 +0000 (16:07 +0100)
committerIain Patterson <me@iain.cx>
Mon, 27 Jan 2014 14:49:47 +0000 (14:49 +0000)
Script which allows overriding Perforce commands or adding new commands.
If the file opt/p4/p4-<command> exists then "p4 <command>" will run the
file in preference to the builtin command.

Source opt/p4/common to identify the arguments which should be passed to
p4 itself.  They will be available in $p4opts.  The command name will be
available in $p4command.  Arguments to the command will be available in
the positional parameters as usual.

Three custom commands are included in this commit.

"p4 diffchange" does a diff of only files opened against the default
changelist or the changelist specified by the -c flag.

"p4 login" attempts to renew Kerberos credentials if SSO login is
enabled.

"p4 update" detects all new, delete or changed files, like "git -A" does.

.profile.d/p4.bashrc
opt/p4/common [new file with mode: 0644]
opt/p4/p4-diffchange [new file with mode: 0755]
opt/p4/p4-login [new file with mode: 0755]
opt/p4/p4-update [new file with mode: 0755]

index 736d7e4..081e89b 100644 (file)
@@ -25,3 +25,30 @@ else
   export P4MERGE="p4merge"
 fi
 unset p4script p4vim
+
+# p4: Wrapper around p4 to add some other features.
+function p4() {
+  if [ -z "$P4OPTSTRING" -a ! "${P4OPTSTRING+xxx}" = "xxx" ]; then
+    local p4=$(which p4)
+    P4OPTSTRING="$(strings $p4 | grep H:)"
+  fi
+
+  local opts=
+  OPTIND=1
+  if [ -n "$P4OPTSTRING" ]; then
+    while getopts "$P4OPTSTRING" opt; do
+      [ "$opt" = "?" ] && continue
+      opts="$opts -$opt $OPTARG"
+    done
+    shift $((OPTIND-1))
+  fi
+
+  command="$1"; shift
+  custom=${PROFILE_HOME:-~}/opt/p4/p4-"$command"
+
+  if [ -x "$custom" ]; then
+    "$custom" $opts "$command" ${1+"$@"}
+  else
+    ( exec p4 $opts "$command" ${1+"$@"} )
+  fi
+}
diff --git a/opt/p4/common b/opt/p4/common
new file mode 100644 (file)
index 0000000..2b5d43c
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/false
+#
+# common: Find arguments for a custom Perforce command.
+# Usage: . ${0%/*}/common
+# Notes: p4 options are stored in $p4opts.
+#        Command name is stored in $p4command.
+#        Command arguments are available in regular positional parameters.
+p4command=${0##*p4-}
+
+p4opts=
+while [ ! "$1" = "$p4command" ]; do
+  p4opts="$p4opts $1"
+  shift
+done
+shift
diff --git a/opt/p4/p4-diffchange b/opt/p4/p4-diffchange
new file mode 100755 (executable)
index 0000000..e6cd52e
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+. ${0%/*}/common
+
+diffopts=
+change=
+while [ $# -gt 0 ]; do
+  case "$1" in
+    -c) change="$2"; shift;;
+    -d[blnsw]|-f|-t|-s[abdelr]) diffopts="$diffopts $1";;
+    -dc)
+      diffopts="$diffopts $1";
+      if [ -n "$2" -a -z "${2//[0-9]/}" ]; then
+        diffopts="$diffopts $2"
+        shift
+      fi
+    ;;
+    -m)
+      diffopts="$diffopts $1 $2"
+      shift
+    ;;
+    *) break;;
+  esac
+  shift
+done
+
+if [ -z "$change" ]; then
+  change="${1:-default}"; shift
+fi
+
+files=$(p4 $p4opts opened -c "$change" ${1+"$@"} | sed 's/#.*//')
+[ -n "$files" ] && p4 $p4opts diff $diffopts $files
diff --git a/opt/p4/p4-login b/opt/p4/p4-login
new file mode 100755 (executable)
index 0000000..4d3074e
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+. ${0%/*}/common
+
+if [ -n "$P4LOGINSSO" ]; then
+  klist -s 2>/dev/null || kinit || unset P4LOGINSSO
+fi
+exec p4 $p4opts $p4command ${1+"$@"}
diff --git a/opt/p4/p4-update b/opt/p4/p4-update
new file mode 100755 (executable)
index 0000000..a6e938b
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+. ${0%/*}/common
+
+files=$(p4 $p4opts diff -sl ${1+"$@"} | sed 's/ /:/')
+add=
+delete=
+diff=
+
+for found in $files; do
+  mode=${found%%:*}
+  file=${found#*:}
+
+  case $mode in
+    "diff") diff="$diff
+$file"
+    ;;
+
+    "missing") delete="$delete
+$file"
+    ;;
+
+    "same");;
+
+  esac
+done
+
+add=$(find . -type f -o -type l | xargs p4 $p4opts files 2>&1 | sed -n 's/ - no such file(s).*//p;s/#[0-9]* - delete change.*//p')
+
+[ -n "$add" ] && echo "$add" | xargs p4 $p4opts add
+[ -n "$diff" ] && echo "$diff" | xargs p4 $p4opts edit
+[ -n "$delete" ] && echo "$delete" | xargs p4 $p4opts delete