| OLD | NEW |
| (Empty) |
| 1 #!/bin/bash | |
| 2 # Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 # | |
| 6 ###################################################################### | |
| 7 # | |
| 8 # This script facilitates merging changes from the LLVM subversion | |
| 9 # repository into the PNaCl Mercurial repository. | |
| 10 # | |
| 11 ###################################################################### | |
| 12 set -o nounset | |
| 13 set -o errexit | |
| 14 | |
| 15 # Make sure this script is run from the right place | |
| 16 if [[ $(basename $(pwd)) != "native_client" ]] ; then | |
| 17 echo "ERROR: run this script from the native_client/ dir" | |
| 18 exit -1 | |
| 19 fi | |
| 20 | |
| 21 source tools/llvm/common-tools.sh | |
| 22 readonly NACL_ROOT="$(pwd)" | |
| 23 SetScriptPath "${NACL_ROOT}/tools/llvm/merge-tool.sh" | |
| 24 SetLogDirectory "${NACL_ROOT}/toolchain/hg-log" | |
| 25 readonly SCRIPT_PATH="$0" | |
| 26 readonly MERGE_LOG_FILE="${NACL_ROOT}/merge.log" | |
| 27 ###################################################################### | |
| 28 | |
| 29 # Location of the sources | |
| 30 # These should match the values in utman.sh | |
| 31 readonly TC_SRC="$(pwd)/hg" | |
| 32 readonly TC_SRC_UPSTREAM="${TC_SRC}/upstream" | |
| 33 readonly TC_SRC_LLVM_MASTER="${TC_SRC}/llvm-master" | |
| 34 readonly TC_SRC_LLVM_GCC_MASTER="${TC_SRC}/llvm-gcc-master" | |
| 35 | |
| 36 readonly PREDIFF="${TC_SRC}/prediff" | |
| 37 readonly POSTDIFF="${TC_SRC}/postdiff" | |
| 38 | |
| 39 readonly UPSTREAM_BRANCH=pnacl-sfi | |
| 40 | |
| 41 readonly HG_CONFIG_AUTO=(--config ui.merge=internal:merge | |
| 42 --config ui.username=chromebot1@gmail.com) | |
| 43 | |
| 44 readonly HG_CONFIG_MANUAL=( | |
| 45 --config kdiff3.executable=/usr/bin/diff3 | |
| 46 --config kdiff3.args="--auto --base \$base \$local \$other -o \$output") | |
| 47 | |
| 48 # TODO(pdox): Refactor repository checkout into a separate script | |
| 49 # so that we don't need to invoke utman. | |
| 50 utman() { | |
| 51 "${NACL_ROOT}"/tools/llvm/utman.sh "$@" | |
| 52 } | |
| 53 | |
| 54 #@ auto [rev] - Non-interactive merge | |
| 55 auto() { | |
| 56 INTERACTIVE_MERGE=false | |
| 57 export DISPLAY="" | |
| 58 HG_CONFIG=("${HG_CONFIG_AUTO[@]}") | |
| 59 merge-all "$@" | |
| 60 } | |
| 61 | |
| 62 #@ manual [rev] - Interactive merge | |
| 63 manual() { | |
| 64 INTERACTIVE_MERGE=true | |
| 65 HG_CONFIG=("${HG_CONFIG_MANUAL[@]}") | |
| 66 merge-all "$@" | |
| 67 } | |
| 68 | |
| 69 get-tip-revision() { | |
| 70 svn info "http://llvm.org/svn/llvm-project/" \ | |
| 71 | grep Revision \ | |
| 72 | awk '{print $2}' | |
| 73 } | |
| 74 | |
| 75 set-master-revision() { | |
| 76 echo "@@@BUILD_STEP Set LLVM revision: ${MERGE_REVISION}@@@" | |
| 77 echo "MERGE REVISION: ${MERGE_REVISION}" | |
| 78 | |
| 79 # Set environmental variable for utman | |
| 80 export LLVM_PROJECT_REV=${MERGE_REVISION} | |
| 81 utman svn-checkout-llvm-master | |
| 82 utman svn-update-llvm-master | |
| 83 utman svn-checkout-llvm-gcc-master | |
| 84 utman svn-update-llvm-gcc-master | |
| 85 } | |
| 86 | |
| 87 get-upstream() { | |
| 88 echo "@@@BUILD_STEP Get mercurial source@@@" | |
| 89 export UPSTREAM_REV=${UPSTREAM_BRANCH} | |
| 90 utman hg-checkout-upstream | |
| 91 utman hg-pull-upstream | |
| 92 utman hg-update-upstream | |
| 93 } | |
| 94 | |
| 95 #+ merge-all - Merge everything | |
| 96 merge-all() { | |
| 97 if [ $# -ne 1 ]; then | |
| 98 Fatal "Please specify revision or 'tip'" | |
| 99 fi | |
| 100 if [ "$1" == "tip" ]; then | |
| 101 MERGE_REVISION=$(get-tip-revision) | |
| 102 else | |
| 103 MERGE_REVISION=$1 | |
| 104 fi | |
| 105 | |
| 106 set-master-revision | |
| 107 get-upstream | |
| 108 | |
| 109 check-revisions | |
| 110 | |
| 111 assert-clean | |
| 112 | |
| 113 echo "@@@BUILD_STEP Merge@@@" | |
| 114 generate-pre-diff | |
| 115 | |
| 116 commit-vendor | |
| 117 hg-merge | |
| 118 | |
| 119 generate-post-diff | |
| 120 | |
| 121 if ${INTERACTIVE_MERGE}; then | |
| 122 vim-diff-diff | |
| 123 else | |
| 124 dump-diff-diff | |
| 125 fi | |
| 126 | |
| 127 final-banner | |
| 128 } | |
| 129 | |
| 130 final-banner() { | |
| 131 echo "********************************************************************" | |
| 132 echo "The hg/upstream working directory is now in a merged state." | |
| 133 echo "Before you commit and push, you should build PNaCl and run all tests." | |
| 134 echo "" | |
| 135 echo "1) Set the default LLVM_PROJECT_REV to ${MERGE_REVISION} (in utman.sh)" | |
| 136 echo "" | |
| 137 echo "2) Build PNaCl:" | |
| 138 echo " UTMAN_MERGE_TESTING=true tools/llvm/utman.sh everything-translator" | |
| 139 echo "" | |
| 140 echo "3) Run all tests:" | |
| 141 echo " tools/llvm/utman-test.sh test-all" | |
| 142 echo "" | |
| 143 echo "Depending on the size of the merge, there may be lots of bugs. You may" | |
| 144 echo "need to fix and rebuild several times. When you are confident all tests" | |
| 145 echo "are passing, you can commit and push." | |
| 146 echo "********************************************************************" | |
| 147 } | |
| 148 | |
| 149 assert-clean() { | |
| 150 svn-assert-no-changes "${TC_SRC_LLVM_MASTER}" | |
| 151 svn-assert-no-changes "${TC_SRC_LLVM_GCC_MASTER}" | |
| 152 | |
| 153 hg-assert-no-changes "${TC_SRC_UPSTREAM}" | |
| 154 hg-assert-no-outgoing "${TC_SRC_UPSTREAM}" | |
| 155 } | |
| 156 | |
| 157 #@ clean - Clean/revert mercurial repositories | |
| 158 clean() { | |
| 159 echo "@@@BUILD_STEP Clean hg/upstream@@@" | |
| 160 StepBanner "CLEAN - Cleaning repositories" | |
| 161 clean-upstream | |
| 162 } | |
| 163 | |
| 164 #+ clean-upstream - Clean the hg/upstream repository | |
| 165 clean-upstream() { | |
| 166 StepBanner "CLEAN" "Cleaning hg upstream repository" | |
| 167 | |
| 168 if ! [ -d "${TC_SRC_UPSTREAM}" ]; then | |
| 169 return 0 | |
| 170 fi | |
| 171 | |
| 172 # This is kind of silly, but a lot faster than | |
| 173 # checking out the repository from scratch again. | |
| 174 spushd "${TC_SRC_UPSTREAM}" | |
| 175 if hg-has-outgoing "${TC_SRC_UPSTREAM}"; then | |
| 176 hg rollback | |
| 177 fi | |
| 178 rm -rf llvm | |
| 179 rm -rf llvm-gcc | |
| 180 hg update -C ${UPSTREAM_BRANCH} | |
| 181 spopd | |
| 182 | |
| 183 hg-assert-no-outgoing "${TC_SRC_UPSTREAM}" | |
| 184 hg-assert-no-changes "${TC_SRC_UPSTREAM}" | |
| 185 } | |
| 186 | |
| 187 #+ check-revisions - Make sure the repostiory revision is set correctly. | |
| 188 check-revisions() { | |
| 189 local llvm_rev=$(svn-get-revision "${TC_SRC_LLVM_MASTER}") | |
| 190 local llvm_gcc_rev=$(svn-get-revision "${TC_SRC_LLVM_GCC_MASTER}") | |
| 191 if [ "${llvm_rev}" -ne "${MERGE_REVISION}" ]; then | |
| 192 Fatal "llvm-master revision does not match" | |
| 193 fi | |
| 194 if [ "${llvm_gcc_rev}" -ne "${MERGE_REVISION}" ]; then | |
| 195 Fatal "llvm-gcc-master revision does not match" | |
| 196 fi | |
| 197 | |
| 198 # Make sure MERGE_REVISION >= upstream_vendor_rev | |
| 199 local upstream_vendor_rev="$(get-upstream-vendor-revision)" | |
| 200 if [ "${#upstream_vendor_rev}" -lt 6 ] || | |
| 201 [ "${#upstream_vendor_rev}" -gt 7 ]; then | |
| 202 Fatal "Invalid upstream revision '${upstream_vendor_rev}'" | |
| 203 fi | |
| 204 if [ "${MERGE_REVISION}" -lt "${upstream_vendor_rev}" ]; then | |
| 205 Fatal "Trying to merge with an prior revision of LLVM" | |
| 206 fi | |
| 207 } | |
| 208 | |
| 209 get-upstream-vendor-revision() { | |
| 210 spushd "${TC_SRC_UPSTREAM}" | |
| 211 # This must match the commit message in commit-vendor() | |
| 212 hg head vendor | | |
| 213 grep 'Updating vendor' | | |
| 214 sed 's/.*Updating vendor to r\([0-9]\+\)$/\1/g' | |
| 215 spopd | |
| 216 } | |
| 217 | |
| 218 #+ generate-pre-diff - Generate vendor:pnacl diff prior to merge | |
| 219 generate-pre-diff() { | |
| 220 spushd "${TC_SRC_UPSTREAM}" | |
| 221 hg diff -r vendor:${UPSTREAM_BRANCH} &> "${PREDIFF}" | |
| 222 spopd | |
| 223 } | |
| 224 | |
| 225 #+ generate-post-diff - Generate vendor:pnacl diff after merge | |
| 226 generate-post-diff() { | |
| 227 spushd "${TC_SRC_UPSTREAM}" | |
| 228 hg diff -r vendor &> "${POSTDIFF}" | |
| 229 spopd | |
| 230 } | |
| 231 | |
| 232 #@ commit-vendor - Apply new commit to vendor branch | |
| 233 commit-vendor() { | |
| 234 StepBanner "Committing vendor" | |
| 235 | |
| 236 StepBanner "Switching to hg vendor branch" | |
| 237 | |
| 238 hg-update "${TC_SRC_UPSTREAM}" vendor | |
| 239 | |
| 240 StepBanner "Exporting svn to hg" | |
| 241 rm -rf "${TC_SRC_UPSTREAM}/llvm" | |
| 242 svn export "${TC_SRC_LLVM_MASTER}" "${TC_SRC_UPSTREAM}/llvm" | |
| 243 | |
| 244 rm -rf "${TC_SRC_UPSTREAM}/llvm-gcc" | |
| 245 svn export "${TC_SRC_LLVM_GCC_MASTER}" "${TC_SRC_UPSTREAM}/llvm-gcc" | |
| 246 | |
| 247 StepBanner "Updating hg file list" | |
| 248 spushd "${TC_SRC_UPSTREAM}" | |
| 249 hg add | |
| 250 hg remove -A 2>&1 | (grep -v "not removing" || true) | |
| 251 spopd | |
| 252 | |
| 253 if ! hg-has-changes "${TC_SRC_UPSTREAM}" ; then | |
| 254 Banner "Trivial merge, no changes recorded" | |
| 255 exit 55 | |
| 256 fi | |
| 257 | |
| 258 StepBanner "Committing vendor branch" | |
| 259 spushd "${TC_SRC_UPSTREAM}" | |
| 260 # This commit message must match the regex in get-upstream-vendor-revision() | |
| 261 hg "${HG_CONFIG[@]}" commit -m "Updating vendor to r${MERGE_REVISION}" | |
| 262 spopd | |
| 263 } | |
| 264 | |
| 265 #@ hg-merge - Merge and resolve conflicts for llvm | |
| 266 hg-merge() { | |
| 267 StepBanner "hg-merge - Merge and resolve conflicts" | |
| 268 | |
| 269 StepBanner "hg-merge" "Switching to ${UPSTREAM_BRANCH} branch" | |
| 270 hg-update "${TC_SRC_UPSTREAM}" ${UPSTREAM_BRANCH} | |
| 271 hg-assert-no-changes "${TC_SRC_UPSTREAM}" | |
| 272 | |
| 273 StepBanner "hg-merge" "Merging vendor into ${UPSTREAM_BRANCH}" | |
| 274 spushd "${TC_SRC_UPSTREAM}" | |
| 275 hg "${HG_CONFIG[@]}" -y merge -r vendor 2>&1 | tee "${MERGE_LOG_FILE}" | |
| 276 local hgret=${PIPESTATUS[0]} | |
| 277 if [ ${hgret} -ne 0 ] || | |
| 278 grep -q "remote deleted\|local deleted\|conflicting flags" \ | |
| 279 "${MERGE_LOG_FILE}" ; then | |
| 280 Fatal "MERGE FAILED" | |
| 281 fi | |
| 282 spopd | |
| 283 } | |
| 284 | |
| 285 #@ vim-diff-diff - Review diff-diff using vim | |
| 286 vim-diff-diff() { | |
| 287 vimdiff "${PREDIFF}" "${POSTDIFF}" | |
| 288 } | |
| 289 | |
| 290 #@ dump-diff-diff - Review diff-diff | |
| 291 dump-diff-diff() { | |
| 292 diff "${PREDIFF}" "${POSTDIFF}" || true | |
| 293 } | |
| 294 | |
| 295 #@ help - Usage information. | |
| 296 help() { | |
| 297 Usage | |
| 298 } | |
| 299 | |
| 300 [ $# = 0 ] && set -- help # Avoid reference to undefined $1. | |
| 301 if [ "$(type -t $1)" != "function" ]; then | |
| 302 echo "ERROR: unknown function '$1'." >&2 | |
| 303 echo "For help, try:" | |
| 304 echo " $0 help" | |
| 305 exit 1 | |
| 306 fi | |
| 307 | |
| 308 "$@" | |
| OLD | NEW |