HADOOP-12156. modernize smart-apply-patch (aw)

Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/dcde7e4a
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/dcde7e4a
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/dcde7e4a

Branch: refs/heads/HADOOP-12111
Commit: dcde7e4a23ca0a5dcd4b01104d2d39365b557bac
Parents: 3fee9f8
Author: Allen Wittenauer <[email protected]>
Authored: Mon Jul 6 15:50:46 2015 -0700
Committer: Allen Wittenauer <[email protected]>
Committed: Mon Jul 6 15:50:46 2015 -0700

----------------------------------------------------------------------
 dev-support/smart-apply-patch.sh | 628 ++++++++++++++++++++++++++--------
 dev-support/test-patch.sh        |   2 +-
 2 files changed, 492 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/dcde7e4a/dev-support/smart-apply-patch.sh
----------------------------------------------------------------------
diff --git a/dev-support/smart-apply-patch.sh b/dev-support/smart-apply-patch.sh
index ddfd940..bfd2aeb 100755
--- a/dev-support/smart-apply-patch.sh
+++ b/dev-support/smart-apply-patch.sh
@@ -11,179 +11,533 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 
-#
-# Determine if the git diff patch file has prefixes.
-# These files are generated via "git diff" *without* the --no-prefix option.
-#
-# We can apply these patches more easily because we know that the a/ and b/
-# prefixes in the "diff" lines stands for the project root directory.
-# So we don't have to hunt for the project root.
-# And of course, we know that the patch file was generated using git, so we
-# know git apply can handle it properly.
-#
-# Arguments: git diff file name.
-# Return: 0 if it is a git diff with prefix; 1 otherwise.
-#
-has_prefix() {
-  awk '/^diff --git / { if ($3 !~ "^a/" || $4 !~ "^b/") { exit 1 } }
-    /^\+{3}|-{3} / { if ($2 !~ "^[ab]/" && $2 !~ "^/dev/null") { exit 1 } }' 
"$1"
-  return $?
-}
+# Make sure that bash version meets the pre-requisite
 
-PATCH_FILE=$1
-DRY_RUN=$2
-if [ -z "$PATCH_FILE" ]; then
-  echo usage: $0 patch-file
+if [[ -z "${BASH_VERSINFO}" ]] \
+   || [[ "${BASH_VERSINFO[0]}" -lt 3 ]] \
+   || [[ "${BASH_VERSINFO[0]}" -eq 3 && "${BASH_VERSINFO[1]}" -lt 2 ]]; then
+  echo "bash v3.2+ is required. Sorry."
   exit 1
 fi
 
-TMPDIR=${TMPDIR:-/tmp}
-PATCH=${PATCH:-patch} # allow overriding patch binary
+RESULT=0
+
+## @description  Print a message to stderr
+## @audience     public
+## @stability    stable
+## @replaceable  no
+## @param        string
+function yetus_error
+{
+  echo "$*" 1>&2
+}
 
-# Cleanup handler for temporary files
-TOCLEAN=""
-cleanup() {
-  if [[ -n ${TOCLEAN} ]]; then
-    rm $TOCLEAN
+## @description  Print a message to stderr if --debug is turned on
+## @audience     public
+## @stability    stable
+## @replaceable  no
+## @param        string
+function yetus_debug
+{
+  if [[ -n "${YETUS_SHELL_SCRIPT_DEBUG}" ]]; then
+    echo "[$(date) DEBUG]: $*" 1>&2
   fi
-  exit $1
 }
-trap "cleanup 1" HUP INT QUIT TERM
 
-# Allow passing "-" for stdin patches
-if [ "$PATCH_FILE" == "-" ]; then
-  PATCH_FILE="$TMPDIR/smart-apply.in.$RANDOM"
-  cat /dev/fd/0 > $PATCH_FILE
-  TOCLEAN="$TOCLEAN $PATCH_FILE"
-fi
+## @description  Clean the filesystem as appropriate and then exit
+## @audience     private
+## @stability    evolving
+## @replaceable  no
+## @param        runresult
+function cleanup_and_exit
+{
+  local result=$1
 
-ISSUE_RE='^(HADOOP|YARN|MAPREDUCE|HDFS)-[0-9]+$'
-if [[ ${PATCH_FILE} =~ ^http || ${PATCH_FILE} =~ ${ISSUE_RE} ]]; then
-  # Allow downloading of patches
-  PFILE="$TMPDIR/smart-apply.in.$RANDOM"
-  TOCLEAN="$TOCLEAN $PFILE"
-  if [[ ${PATCH_FILE} =~ ^http ]]; then
-    patchURL="${PATCH_FILE}"
-  else # Get URL of patch from JIRA
-    wget -q -O "${PFILE}" "http://issues.apache.org/jira/browse/${PATCH_FILE}";
-    if [[ $? != 0 ]]; then
-      echo "Unable to determine what ${PATCH_FILE} may reference." 1>&2
-      cleanup 1
-    elif [[ $(grep -c 'Patch Available' "${PFILE}") == 0 ]]; then
-      echo "${PATCH_FILE} is not \"Patch Available\".  Exiting." 1>&2
-      cleanup 1
-    fi
-    relativePatchURL=$(grep -o '"/jira/secure/attachment/[0-9]*/[^"]*' 
"${PFILE}" | grep -v -e 'htm[l]*$' | sort | tail -1 | grep -o 
'/jira/secure/attachment/[0-9]*/[^"]*')
-    patchURL="http://issues.apache.org${relativePatchURL}";
+  if [[ ${PATCH_DIR} =~ ^/tmp/apply-patch
+    && -d ${PATCH_DIR} ]]; then
+    rm -rf "${PATCH_DIR}"
+  fi
+
+  # shellcheck disable=SC2086
+  exit ${result}
+}
+
+## @description  Setup the default global variables
+## @audience     public
+## @stability    stable
+## @replaceable  no
+function setup_defaults
+{
+  PATCHURL=""
+  OSTYPE=$(uname -s)
+
+  # Solaris needs POSIX, not SVID
+  case ${OSTYPE} in
+    SunOS)
+      AWK=${AWK:-/usr/xpg4/bin/awk}
+      SED=${SED:-/usr/xpg4/bin/sed}
+      WGET=${WGET:-wget}
+      GIT=${GIT:-git}
+      GREP=${GREP:-/usr/xpg4/bin/grep}
+      PATCH=${PATCH:-/usr/gnu/bin/patch}
+      DIFF=${DIFF:-/usr/gnu/bin/diff}
+      FILE=${FILE:-file}
+    ;;
+    *)
+      AWK=${AWK:-awk}
+      SED=${SED:-sed}
+      WGET=${WGET:-wget}
+      GIT=${GIT:-git}
+      GREP=${GREP:-grep}
+      PATCH=${PATCH:-patch}
+      DIFF=${DIFF:-diff}
+      FILE=${FILE:-file}
+    ;;
+  esac
+
+  DRYRUNMODE=false
+  PATCH_DIR=/tmp
+  while [[ -e ${PATCH_DIR} ]]; do
+    PATCH_DIR=/tmp/apply-patch-${RANDOM}.${RANDOM}
+  done
+  PATCHMODES=("git" "patch")
+  PATCHMODE=""
+  PATCHPREFIX=0
+}
+
+## @description  Print the usage information
+## @audience     public
+## @stability    stable
+## @replaceable  no
+function yetus_usage
+{
+  echo "Usage: apply-patch.sh [options] patch-file | issue-number | http"
+  echo
+  echo "--debug                If set, then output some extra stuff to stderr"
+  echo "--dry-run              Check for patch viability without applying"
+  echo "--patch-dir=<dir>      The directory for working and output files 
(default '/tmp/apply-patch-(random))"
+  echo
+  echo "Shell binary overrides:"
+  echo "--file-cmd=<cmd>       The 'file' command to use (default 'file')"
+  echo "--grep-cmd=<cmd>       The 'grep' command to use (default 'grep')"
+  echo "--git-cmd=<cmd>        The 'git' command to use (default 'git')"
+  echo "--patch-cmd=<cmd>      The GNU-compatible 'patch' command to use 
(default 'patch')"
+  echo "--wget-cmd=<cmd>       The 'wget' command to use (default 'wget')"
+}
+
+## @description  Interpret the command line parameters
+## @audience     private
+## @stability    stable
+## @replaceable  no
+## @params       $@
+## @return       May exit on failure
+function parse_args
+{
+  local i
+
+  for i in "$@"; do
+    case ${i} in
+      --debug)
+        YETUS_SHELL_SCRIPT_DEBUG=true
+      ;;
+      --dry-run)
+        DRYRUNMODE=true
+      ;;
+      --file-cmd=*)
+        FILE=${i#*=}
+      ;;
+      --git-cmd=*)
+        GIT=${i#*=}
+      ;;
+      --grep-cmd=*)
+        GREP=${i#*=}
+      ;;
+      --help|-help|-h|help|--h|--\?|-\?|\?)
+        yetus_usage
+        exit 0
+      ;;
+      --patch-cmd=*)
+        PATCH=${i#*=}
+      ;;
+      --patch-dir=*)
+        PATCH_DIR=${i#*=}
+      ;;
+      --wget-cmd=*)
+        WGET=${i#*=}
+      ;;
+      --*)
+        ## PATCH_OR_ISSUE can't be a --.  So this is probably
+        ## a plugin thing.
+        continue
+      ;;
+      *)
+        PATCH_OR_ISSUE=${i#*=}
+      ;;
+    esac
+  done
+
+  if [[ ! -d ${PATCH_DIR} ]]; then
+    mkdir -p "${PATCH_DIR}"
+    if [[ $? != 0 ]] ; then
+      yetus_error "ERROR: Unable to create ${PATCH_DIR}"
+      cleanup_and_exit 1
+    fi
   fi
-  if [[ -n $DRY_RUN ]]; then
-    echo "Downloading ${patchURL}"
+}
+
+## @description Given a possible patch file, guess if it's a patch file 
without using smart-apply-patch
+## @audience private
+## @stability evolving
+## @param path to patch file to test
+## @return 0 we think it's a patch file
+## @return 1 we think it's not a patch file
+function guess_patch_file
+{
+  local patch=$1
+  local fileOutput
+
+  yetus_debug "Trying to guess is ${patch} is a patch file."
+  fileOutput=$("${FILE}" "${patch}")
+  if [[ $fileOutput =~ \ diff\  ]]; then
+    yetus_debug "file magic says it's a diff."
+    return 0
   fi
-  wget -q -O "${PFILE}" "${patchURL}"
-  if [[ $? != 0 ]]; then
-    echo "${PATCH_FILE} could not be downloaded." 1>&2
-    cleanup 1
+  fileOutput=$(head -n 1 "${patch}" | "${GREP}" -E "^(From [a-z0-9]* Mon Sep 
17 00:00:00 2001)|(diff .*)|(Index: .*)$")
+  if [[ $? == 0 ]]; then
+    yetus_debug "first line looks like a patch file."
+    return 0
   fi
-  PATCH_FILE="${PFILE}"
-fi
+  return 1
+}
+
+## @description  Given ${PATCH_ISSUE}, determine what type of patch file is in 
use, and do the
+## @description  necessary work to place it into ${PATCH_DIR}/patch.
+## @audience     private
+## @stability    evolving
+## @replaceable  no
+## @return       0 on success
+## @return       1 on failure, may exit
+function locate_patch
+{
+  local notSureIfPatch=false
+  yetus_debug "locate patch"
 
-# Case for git-diff patches
-if grep -q "^diff --git" "${PATCH_FILE}"; then
-  GIT_FLAGS="--binary -v"
-  if has_prefix "$PATCH_FILE"; then
-    GIT_FLAGS="$GIT_FLAGS -p1"
+  # Allow passing "-" for stdin patches
+  if [[ ${PATCH_OR_ISSUE} == - ]]; then
+    PATCH_FILE="${PATCH_DIR}/patch"
+    cat /dev/fd/0 > "${PATCH_FILE}"
+  elif [[ -f ${PATCH_OR_ISSUE} ]]; then
+    PATCH_FILE="${PATCH_OR_ISSUE}"
   else
-    GIT_FLAGS="$GIT_FLAGS -p0"
+    if [[ ${PATCH_OR_ISSUE} =~ ^http ]]; then
+      echo "Patch is being downloaded at $(date) from"
+      PATCHURL="${PATCH_OR_ISSUE}"
+    else
+      ${WGET} -q -O "${PATCH_DIR}/jira" 
"http://issues.apache.org/jira/browse/${PATCH_OR_ISSUE}";
+
+      case $? in
+        0)
+        ;;
+        2)
+          yetus_error "ERROR: .wgetrc/.netrc parsing error."
+          cleanup_and_exit 1
+        ;;
+        3)
+          yetus_error "ERROR: File IO error."
+          cleanup_and_exit 1
+        ;;
+        4)
+          yetus_error "ERROR: URL ${PATCH_OR_ISSUE} is unreachable."
+          cleanup_and_exit 1
+        ;;
+        *)
+          yetus_error "ERROR: Unable to fetch ${PATCH_OR_ISSUE}."
+          cleanup_and_exit 1
+        ;;
+      esac
+
+      if [[ -z "${PATCH_FILE}" ]]; then
+        if [[ $(${GREP} -c 'Patch Available' "${PATCH_DIR}/jira") == 0 ]] ; 
then
+          if [[ ${JENKINS} == true ]]; then
+            yetus_error "ERROR: ${PATCH_OR_ISSUE} is not \"Patch Available\"."
+            cleanup_and_exit 1
+          else
+            yetus_error "WARNING: ${PATCH_OR_ISSUE} is not \"Patch 
Available\"."
+          fi
+        fi
+
+        relativePatchURL=$(${GREP} -o '"/jira/secure/attachment/[0-9]*/[^"]*' 
"${PATCH_DIR}/jira" | ${GREP} -v -e 'htm[l]*$' | sort | tail -1 | ${GREP} -o 
'/jira/secure/attachment/[0-9]*/[^"]*')
+        PATCHURL="http://issues.apache.org${relativePatchURL}";
+        if [[ ! ${PATCHURL} =~ \.patch$ ]]; then
+          notSureIfPatch=true
+        fi
+        echo "${ISSUE} patch is being downloaded at $(date) from"
+      fi
+    fi
+    if [[ -z "${PATCH_FILE}" ]]; then
+      ${WGET} -q -O "${PATCH_DIR}/patch" "${PATCHURL}"
+      if [[ $? != 0 ]];then
+        yetus_error "ERROR: ${PATCH_OR_ISSUE} could not be downloaded."
+        cleanup_and_exit 1
+      fi
+      PATCH_FILE="${PATCH_DIR}/patch"
+    fi
   fi
-  if [[ -z $DRY_RUN ]]; then
-    GIT_FLAGS="$GIT_FLAGS --stat --apply"
-    echo Going to apply git patch with: git apply "${GIT_FLAGS}"
-  else
-    GIT_FLAGS="$GIT_FLAGS --check"
+
+  if [[ ! -f "${PATCH_DIR}/patch" ]]; then
+    cp "${PATCH_FILE}" "${PATCH_DIR}/patch"
+    if [[ $? == 0 ]] ; then
+      echo "Patch file ${PATCH_FILE} copied to ${PATCH_DIR}"
+    else
+      yetus_error "ERROR: Could not copy ${PATCH_FILE} to ${PATCH_DIR}"
+      cleanup_and_exit 1
+    fi
   fi
-  # shellcheck disable=SC2086
-  git apply ${GIT_FLAGS} "${PATCH_FILE}"
-  if [[ $? == 0 ]]; then
-    cleanup 0
+
+  if [[ ! -f "${PATCH_DIR}/patch" ]]; then
+    cp "${PATCH_FILE}" "${PATCH_DIR}/patch"
+    if [[ $? == 0 ]] ; then
+      echo "Patch file ${PATCH_FILE} copied to ${PATCH_DIR}"
+    else
+      yetus_error "ERROR: Could not copy ${PATCH_FILE} to ${PATCH_DIR}"
+      cleanup_and_exit 1
+    fi
   fi
-  echo "git apply failed. Going to apply the patch with: ${PATCH}"
-fi
 
-# Come up with a list of changed files into $TMP
-TMP="$TMPDIR/smart-apply.paths.$RANDOM"
-TOCLEAN="$TOCLEAN $TMP"
+  if [[ ${notSureIfPatch} == "true" ]]; then
+    guess_patch_file "${PATCH_FILE}"
+    if [[ $? != 0 ]]; then
+      yetus_error "ERROR: ${PATCHURL} is not a patch file."
+      cleanup_and_exit 1
+    else
+      yetus_debug "The patch ${PATCHURL} was not named properly, but it looks 
like a patch file. proceeding, but issue/branch matching might go awry."
+    fi
+  fi
+}
+
+## @description  if patch-level zero, then verify we aren't
+## @description  just adding files
+## @audience     public
+## @stability    stable
+## @param        filename
+## @param        command
+## @param        [..]
+## @replaceable  no
+## @returns      $?
+function verify_zero
+{
+  local logfile=$1
+  shift
+  local dir
+
+  # don't return /dev/null
+  # shellcheck disable=SC2016
+  changed_files1=$(${AWK} 'function p(s){if(s!~"^/dev/null"){print s}}
+    /^diff --git /   { p($3); p($4) }
+    /^(\+\+\+|---) / { p($2) }' "${PATCH_DIR}/patch" | sort -u)
+
+  # maybe we interpreted the patch wrong? check the log file
+  # shellcheck disable=SC2016
+  changed_files2=$(${GREP} -E '^[cC]heck' "${logfile}" \
+    | ${AWK} '{print $3}' \
+    | ${SED} -e 's,\.\.\.$,,g')
 
-if $PATCH -p0 -E --dry-run < $PATCH_FILE 2>&1 > $TMP; then
-  PLEVEL=0
-  #if the patch applied at P0 there is the possability that all we are doing
-  # is adding new files and they would apply anywhere. So try to guess the
-  # correct place to put those files.
+  for filename in ${changed_files1} ${changed_files2}; do
 
-  TMP2="$TMPDIR/smart-apply.paths.2.$RANDOM"
-  TOCLEAN="$TOCLEAN $TMP2"
+    # leading prefix = bad
+    if [[ ${filename} =~ ^(a|b)/ ]]; then
+      return 1
+    fi
+
+    # touching an existing file is proof enough
+    # that pl=0 is good
+    if [[ -f ${filename} ]]; then
+      return 0
+    fi
 
-  egrep '^patching file |^checking file ' $TMP | awk '{print $3}' | grep -v 
/dev/null | sort -u > $TMP2
+    dir=$(dirname ${filename} 2>/dev/null)
+    if [[ -n ${dir} && -d ${dir} ]]; then
+      return 0
+    fi
+  done
 
-  if [ ! -s $TMP2 ]; then
-    echo "Error: Patch dryrun couldn't detect changes the patch would make. 
Exiting."
-    cleanup 1
+  # ¯\_(ツ)_/¯ - no way for us to know, all new files with no prefix!
+  yetus_error "WARNING: Patch only adds files; using patch level 
${PATCHPREFIX}"
+  return 0
+}
+
+## @description  run the command, sending stdout and stderr to the given 
filename
+## @audience     public
+## @stability    stable
+## @param        filename
+## @param        command
+## @param        [..]
+## @replaceable  no
+## @returns      $?
+function run_and_redirect
+{
+  local logfile=$1
+  shift
+
+  # to the log
+  echo "${*}" > "${logfile}"
+  # the actual command
+  "${@}" >> "${logfile}" 2>&1
+}
+
+## @description git patch dryrun
+## @replaceable  no
+## @audience     private
+## @stability    evolving
+function git_dryrun
+{
+  local prefixsize=${1:-0}
+
+  while [[ ${prefixsize} -lt 4
+    && -z ${PATCHMODE} ]]; do
+    run_and_redirect "${PATCH_DIR}/apply-patch-git-dryrun.log" \
+       "${GIT}" apply --binary -v --check "-p${prefixsize}" "${PATCH_FILE}"
+    if [[ $? == 0 ]]; then
+      PATCHPREFIX=${prefixsize}
+      PATCHMODE=git
+      echo "Verifying the patch:"
+      cat "${PATCH_DIR}/apply-patch-git-dryrun.log"
+      break
+    fi
+    ((prefixsize=prefixsize+1))
+  done
+
+  if [[ ${prefixsize} -eq 0 ]]; then
+    verify_zero "${PATCH_DIR}/apply-patch-git-dryrun.log"
+    if [[ $? != 0 ]]; then
+      PATCHMODE=""
+      PATCHPREFIX=""
+      git_dryrun 1
+    fi
   fi
+}
 
-  #first off check that all of the files do not exist
-  FOUND_ANY=0
-  for CHECK_FILE in $(cat $TMP2)
-  do
-    if [[ -f $CHECK_FILE ]]; then
-      FOUND_ANY=1
+## @description  patch patch dryrun
+## @replaceable  no
+## @audience     private
+## @stability    evolving
+function patch_dryrun
+{
+  local prefixsize=${1:-0}
+
+  while [[ ${prefixsize} -lt 4
+    && -z ${PATCHMODE} ]]; do
+    run_and_redirect "${PATCH_DIR}/apply-patch-patch-dryrun.log" \
+      "${PATCH}" "-p${prefixsize}" -E --dry-run < "${PATCH_FILE}"
+    if [[ $? == 0 ]]; then
+      PATCHPREFIX=${prefixsize}
+      PATCHMODE=patch
+      if [[ ${DRYRUNMODE} == true ]]; then
+        echo "Verifying the patch:"
+        cat "${PATCH_DIR}/apply-patch-patch-dryrun.log"
+      fi
+      break
     fi
+    ((prefixsize=prefixsize+1))
   done
 
-  if [[ "$FOUND_ANY" = "0" ]]; then
-    #all of the files are new files so we have to guess where the correct 
place to put it is.
+  if [[ ${prefixsize} -eq 0 ]]; then
+    verify_zero "${PATCH_DIR}/apply-patch-patch-dryrun.log"
+    if [[ $? != 0 ]]; then
+      PATCHMODE=""
+      PATCHPREFIX=""
+      patch_dryrun 1
+    fi
+  fi
+}
+
+## @description  driver for dryrun methods
+## @replaceable  no
+## @audience     private
+## @stability    evolving
+function dryrun
+{
+  local method
 
-    # if all of the lines start with a/ or b/, then this is a git patch that
-    # was generated without --no-prefix
-    if ! grep -qv '^a/\|^b/' $TMP2 ; then
-      echo Looks like this is a git patch. Stripping a/ and b/ prefixes
-      echo and incrementing PLEVEL
-      PLEVEL=$[$PLEVEL + 1]
-      sed -i -e 's,^[ab]/,,' $TMP2
+  for method in "${PATCHMODES[@]}"; do
+    if declare -f ${method}_dryrun >/dev/null; then
+      "${method}_dryrun"
     fi
+    if [[ -n ${PATCHMODE} ]]; then
+      break
+    fi
+  done
 
-    PREFIX_DIRS_AND_FILES=$(cut -d '/' -f 1 $TMP2 | sort -u)
- 
-    # if we are at the project root then nothing more to do
-    if [[ -d hadoop-common-project ]]; then
-      echo Looks like this is being run at project root
+  if [[ -n ${PATCHMODE} ]]; then
+    RESULT=0
+    return 0
+  fi
+  RESULT=1
+  return 1
+}
 
-    # if all of the lines start with hadoop-common/, hadoop-hdfs/, 
hadoop-yarn/ or hadoop-mapreduce/, this is
-    # relative to the hadoop root instead of the subproject root, so we need
-    # to chop off another layer
-    elif [[ "$PREFIX_DIRS_AND_FILES" =~ 
^(hadoop-common-project|hadoop-hdfs-project|hadoop-yarn-project|hadoop-mapreduce-project)$
 ]]; then
+## @description  git patch apply
+## @replaceable  no
+## @audience     private
+## @stability    evolving
+function git_apply
+{
+  echo "Applying the patch:"
+  run_and_redirect "${PATCH_DIR}/apply-patch-git-apply.log" \
+    "${GIT}" apply --binary -v --stat --apply "-p${PATCHPREFIX}" 
"${PATCH_FILE}"
+  cat "${PATCH_DIR}/apply-patch-git-apply.log"
+}
 
-      echo Looks like this is relative to project root. Increasing PLEVEL
-      PLEVEL=$[$PLEVEL + 1]
 
-    elif ! echo "$PREFIX_DIRS_AND_FILES" | grep -vxq 
'hadoop-common-project\|hadoop-hdfs-project\|hadoop-yarn-project\|hadoop-mapreduce-project'
 ; then
-      echo Looks like this is a cross-subproject patch. Try applying from the 
project root
-      cleanup 1
+## @description  patch patch apply
+## @replaceable  no
+## @audience     private
+## @stability    evolving
+function patch_apply
+{
+  echo "Applying the patch:"
+  run_and_redirect "${PATCH_DIR}/apply-patch-patch-apply.log" \
+    "${PATCH}" "-p${PATCHPREFIX}" -E < "${PATCH_FILE}"
+  cat "${PATCH_DIR}/apply-patch-patch-apply.log"
+}
+
+
+## @description  driver for patch apply methods
+## @replaceable  no
+## @audience     private
+## @stability    evolving
+function apply
+{
+  if declare -f ${PATCHMODE}_apply >/dev/null; then
+    "${PATCHMODE}_apply"
+    if [[ $? -gt 0 ]]; then
+      RESULT=1
+    else
+      RESULT=0
     fi
+  else
+    yetus_error "ERROR: Patching method ${PATCHMODE} does not have a way to 
apply patches!"
+    RESULT=1
   fi
-elif $PATCH -p1 -E --dry-run < $PATCH_FILE 2>&1 > /dev/null; then
-  PLEVEL=1
-elif $PATCH -p2 -E --dry-run < $PATCH_FILE 2>&1 > /dev/null; then
-  PLEVEL=2
-else
-  echo "The patch does not appear to apply with p0 to p2";
-  cleanup 1;
-fi
+}
+
+trap "cleanup_and_exit 1" HUP INT QUIT TERM
 
-# If this is a dry run then exit instead of applying the patch
-if [[ -n $DRY_RUN ]]; then
-  cleanup 0;
+setup_defaults
+
+parse_args "$@"
+
+locate_patch
+
+dryrun
+
+if [[ ${RESULT} -gt 0 ]]; then
+  yetus_error "ERROR: Aborting! The patch cannot be verified."
+  cleanup_and_exit ${RESULT}
 fi
 
-echo Going to apply patch with: $PATCH -p$PLEVEL
-$PATCH -p$PLEVEL -E < $PATCH_FILE
+if [[ ${DRYRUNMODE} == false ]]; then
+  apply
+fi
 
-cleanup $?
+cleanup_and_exit ${RESULT}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/dcde7e4a/dev-support/test-patch.sh
----------------------------------------------------------------------
diff --git a/dev-support/test-patch.sh b/dev-support/test-patch.sh
index f93cb4a..793c42f 100755
--- a/dev-support/test-patch.sh
+++ b/dev-support/test-patch.sh
@@ -1601,7 +1601,7 @@ function verify_patch_file
   # Before building, check to make sure that the patch is valid
   export PATCH
 
-  "${BINDIR}/smart-apply-patch.sh" "${PATCH_DIR}/patch" dryrun
+  "${BINDIR}/smart-apply-patch.sh" --dry-run "${PATCH_DIR}/patch"
   if [[ $? != 0 ]] ; then
     echo "PATCH APPLICATION FAILED"
     add_vote_table -1 patch "The patch command could not apply the patch 
during dryrun."

Reply via email to