Home | History | Annotate | Download | only in tools
      1 # Copyright 2012 the V8 project authors. All rights reserved.
      2 # Redistribution and use in source and binary forms, with or without
      3 # modification, are permitted provided that the following conditions are
      4 # met:
      5 #
      6 #     * Redistributions of source code must retain the above copyright
      7 #       notice, this list of conditions and the following disclaimer.
      8 #     * Redistributions in binary form must reproduce the above
      9 #       copyright notice, this list of conditions and the following
     10 #       disclaimer in the documentation and/or other materials provided
     11 #       with the distribution.
     12 #     * Neither the name of Google Inc. nor the names of its
     13 #       contributors may be used to endorse or promote products derived
     14 #       from this software without specific prior written permission.
     15 #
     16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 # This file contains common function definitions for various other shell
     29 # scripts in this directory. It is not meant to be executed by itself.
     30 
     31 # Important: before including this file, the following variables must be set:
     32 # - BRANCHNAME
     33 # - PERSISTFILE_BASENAME
     34 
     35 TEMP_BRANCH=$BRANCHNAME-temporary-branch-created-by-script
     36 VERSION_FILE="src/version.cc"
     37 CHANGELOG_ENTRY_FILE="$PERSISTFILE_BASENAME-changelog-entry"
     38 PATCH_FILE="$PERSISTFILE_BASENAME-patch"
     39 PATCH_OUTPUT_FILE="$PERSISTFILE_BASENAME-patch-output"
     40 COMMITMSG_FILE="$PERSISTFILE_BASENAME-commitmsg"
     41 TOUCHED_FILES_FILE="$PERSISTFILE_BASENAME-touched-files"
     42 TRUNK_REVISION_FILE="$PERSISTFILE_BASENAME-trunkrevision"
     43 START_STEP=0
     44 CURRENT_STEP=0
     45 
     46 die() {
     47   [[ -n "$1" ]] && echo "Error: $1"
     48   echo "Exiting."
     49   exit 1
     50 }
     51 
     52 confirm() {
     53   echo -n "$1 [Y/n] "
     54   read ANSWER
     55   if [[ -z "$ANSWER" || "$ANSWER" == "Y" || "$ANSWER" == "y" ]] ; then
     56     return 0
     57   else
     58     return 1
     59   fi
     60 }
     61 
     62 delete_branch() {
     63   local MATCH=$(git branch | grep "$1" | awk '{print $NF}' | grep -x $1)
     64   if [ "$MATCH" == "$1" ] ; then
     65     confirm "Branch $1 exists, do you want to delete it?"
     66     if [ $? -eq 0 ] ; then
     67       git branch -D $1 || die "Deleting branch '$1' failed."
     68       echo "Branch $1 deleted."
     69     else
     70       die "Can't continue. Please delete branch $1 and try again."
     71     fi
     72   fi
     73 }
     74 
     75 # Persist and restore variables to support canceling/resuming execution
     76 # of this script.
     77 persist() {
     78   local VARNAME=$1
     79   local FILE="$PERSISTFILE_BASENAME-$VARNAME"
     80   echo "${!VARNAME}" > $FILE
     81 }
     82 
     83 restore() {
     84   local VARNAME=$1
     85   local FILE="$PERSISTFILE_BASENAME-$VARNAME"
     86   local VALUE="$(cat $FILE)"
     87   eval "$VARNAME=\"$VALUE\""
     88 }
     89 
     90 restore_if_unset() {
     91   local VARNAME=$1
     92   [[ -z "${!VARNAME}" ]] && restore "$VARNAME"
     93   [[ -z "${!VARNAME}" ]] && die "Variable '$VARNAME' could not be restored."
     94 }
     95 
     96 initial_environment_checks() {
     97   # Cancel if this is not a git checkout.
     98   [[ -d .git ]] \
     99     || die "This is not a git checkout, this script won't work for you."
    100 
    101   # Cancel if EDITOR is unset or not executable.
    102   [[ -n "$EDITOR" && -x "$(which $EDITOR)" ]] \
    103     || die "Please set your EDITOR environment variable, you'll need it."
    104 }
    105 
    106 common_prepare() {
    107   # Check for a clean workdir.
    108   [[ -z "$(git status -s -uno)" ]] \
    109     || die "Workspace is not clean. Please commit or undo your changes."
    110 
    111   # Persist current branch.
    112   CURRENT_BRANCH=$(git status -s -b -uno | grep "^##" | awk '{print $2}')
    113   persist "CURRENT_BRANCH"
    114 
    115   # Fetch unfetched revisions.
    116   git svn fetch || die "'git svn fetch' failed."
    117 
    118   # Get ahold of a safe temporary branch and check it out.
    119   if [ "$CURRENT_BRANCH" != "$TEMP_BRANCH" ] ; then
    120     delete_branch $TEMP_BRANCH
    121     git checkout -b $TEMP_BRANCH
    122   fi
    123 
    124   # Delete the branch that will be created later if it exists already.
    125   delete_branch $BRANCHNAME
    126 }
    127 
    128 common_cleanup() {
    129   restore_if_unset "CURRENT_BRANCH"
    130   git checkout -f $CURRENT_BRANCH
    131   [[ "$TEMP_BRANCH" != "$CURRENT_BRANCH" ]] && git branch -D $TEMP_BRANCH
    132   [[ "$BRANCHNAME" != "$CURRENT_BRANCH" ]] && git branch -D $BRANCHNAME
    133   # Clean up all temporary files.
    134   rm -f "$PERSISTFILE_BASENAME"*
    135 }
    136 
    137 # These two functions take a prefix for the variable names as first argument.
    138 read_and_persist_version() {
    139   for v in MAJOR_VERSION MINOR_VERSION BUILD_NUMBER PATCH_LEVEL; do
    140     VARNAME="$1${v%%_*}"
    141     VALUE=$(grep "#define $v" "$VERSION_FILE" | awk '{print $NF}')
    142     eval "$VARNAME=\"$VALUE\""
    143     persist "$VARNAME"
    144   done
    145 }
    146 restore_version_if_unset() {
    147   for v in MAJOR MINOR BUILD PATCH; do
    148     restore_if_unset "$1$v"
    149   done
    150 }
    151 
    152 upload_step() {
    153   let CURRENT_STEP+=1
    154   if [ $START_STEP -le $CURRENT_STEP ] ; then
    155     echo ">>> Step $CURRENT_STEP: Upload for code review."
    156     echo -n "Please enter the email address of a V8 reviewer for your patch: "
    157     read REVIEWER
    158     git cl upload -r "$REVIEWER" --send-mail \
    159       || die "'git cl upload' failed, please try again."
    160   fi
    161 }
    162 
    163 wait_for_lgtm() {
    164   echo "Please wait for an LGTM, then type \"LGTM<Return>\" to commit your \
    165 change. (If you need to iterate on the patch or double check that it's \
    166 sane, do so in another shell, but remember to not change the headline of \
    167 the uploaded CL."
    168   unset ANSWER
    169   while [ "$ANSWER" != "LGTM" ] ; do
    170     [[ -n "$ANSWER" ]] && echo "That was not 'LGTM'."
    171     echo -n "> "
    172     read ANSWER
    173   done
    174 }
    175 
    176 # Takes a file containing the patch to apply as first argument.
    177 apply_patch() {
    178   patch -p1 < "$1" > "$PATCH_OUTPUT_FILE" || \
    179     { cat "$PATCH_OUTPUT_FILE" && die "Applying the patch failed."; }
    180   tee < "$PATCH_OUTPUT_FILE" >(awk '{print $NF}' >> "$TOUCHED_FILES_FILE")
    181   rm "$PATCH_OUTPUT_FILE"
    182 }
    183 
    184 stage_files() {
    185   # Stage added and modified files.
    186   TOUCHED_FILES=$(cat "$TOUCHED_FILES_FILE")
    187   for FILE in $TOUCHED_FILES ; do
    188     git add "$FILE"
    189   done
    190   # Stage deleted files.
    191   DELETED_FILES=$(git status -s -uno --porcelain | grep "^ D" \
    192                                                  | awk '{print $NF}')
    193   for FILE in $DELETED_FILES ; do
    194     git rm "$FILE"
    195   done
    196   rm -f "$TOUCHED_FILES_FILE"
    197 }
    198