blob: e45068a623902c13e5e12650f4014655661063a4 [file] [log] [blame] [edit]
#!/usr/bin/env bash
#
# This script updates the copy of ANGLE in Source/ThirdParty/ANGLE
# with the latest changes from upstream.
#
set -e
cd "$(dirname "$0")/../../Source/ThirdParty/ANGLE"
ANGLE_DIR="$PWD"
ANGLE_TARGET_COMMIT="origin/main"
WEBKIT_TARGET_COMMIT=$(git rev-parse HEAD)
WEBKIT_TARGET_COMMIT_SHORT=$(git rev-parse --abbrev-ref HEAD)
q="-q"
# Check for modified files in WebKit ignoring untracked file except in ANGLE dir
check_uncommitted_changes() {
modified_files=$(git status --porcelain | grep -e "^[^?]" -e "^?? Source/ThirdParty/ANGLE") || true
if [ -n "$modified_files" ]; then
echo "WebKit has uncommitted or untracked changes. Commit, stash, or remove them:"
echo "$modified_files"
exit 1
fi
}
generate_changes_diff() {
# Exclude WebKit-added build files from the diff.
git diff "$1" --ignore-submodules=all --full-index --cached -b --ignore-cr-at-eol -- . \
':(exclude)ANGLE.plist' \
':(exclude)ANGLE.xcodeproj' \
':(exclude)Configurations' \
':(exclude)**CMakeLists.txt' \
':(exclude)*.cmake' \
':(exclude)adjust-angle-include-paths*' \
':(exclude)changes.diff' \
':(exclude)gni-to-cmake.py' \
':(exclude)Makefile' \
':(exclude)third_party/zlib/google/compression_utils_portable*' \
':(exclude)third_party/kotlin_stdlib*' \
':(exclude)**.DS_Store' \
':(exclude)WebKit' \
':(exclude)WebKitBuild' \
':(exclude)third_party/r8/custom_d8.jar' \
':(exclude)third_party/googletest' \
':(exclude)parsetab.py' \
> changes.diff
}
generate_changes() {
PREVIOUS_ANGLE_COMMIT_HASH=$(grep -m 1 -o -E "[a-z0-9]{40}" ANGLE.plist)
rm -rf .git
git init ${q}
git remote add origin https://chromium.googlesource.com/angle/angle
git fetch ${q} --depth 1 origin "$PREVIOUS_ANGLE_COMMIT_HASH"
git add -A
generate_changes_diff "$PREVIOUS_ANGLE_COMMIT_HASH"
rm -rf .git
}
generate_sources() {
source_list_file="$(mktemp /tmp/ANGLEShaderProgramVersionSourceList.txt.XXXX)"
find src -type f -iname '*.h' -o -iname '*.cpp' -o -iname '*.c' -o -iname '*.cc' -o -iname '*.mm' -o -iname '*.inc' > ${source_list_file}
./src/program_serialize_data_version.py WebKit/ANGLEShaderProgramVersion.h ${source_list_file}
rm ${source_list_file}
}
usage() {
SCRIPT_NAME=$(basename "$0")
echo "USAGE: $SCRIPT_NAME [-h|--help] [--generate-changes | --generate-sources | <commit>]"
echo " -h or --help Print this help message."
echo " -v or --verbose Print more output."
echo " --generate-changes Generate ANGLE changes.diff, difference to last merged upstream revision."
echo " --generate-sources Generate ANGLE generated sources."
echo " <commit> The ANGLE commit to update to. Defaults to origin/main"
}
while [[ $# -gt 0 ]]; do
opt="$1";
shift;
case "$opt" in
-h|--help)
usage
exit 0
;;
-v|--verbose)
echo "WEBKIT_TARGET_COMMIT: $WEBKIT_TARGET_COMMIT ($WEBKIT_TARGET_COMMIT_SHORT)"
q=""
;;
--generate-changes)
generate_changes
exit 0
;;
--generate-sources)
generate_sources
exit 0
;;
--*)
echo "ERROR: Unrecognized argument: $opt"
usage
exit 1
;;
*)
ANGLE_TARGET_COMMIT="$opt"
;;
esac
done
check_uncommitted_changes
if ! which git-filter-repo > /dev/null; then
echo "Please install git-filter-repo from https://github.com/newren/git-filter-repo"
exit 1
fi
in_rebase() {
test -d .git && { test -d "$(git rev-parse --git-path rebase-merge)" || test -d "$(git rev-parse --git-path rebase-apply)"; } ;
}
wait_for_rebase_to_complete() {
if ! in_rebase; then
return 1
fi
echo
echo "For patches that have been upstreamed, you should choose the 'ours' version,"
echo "and the resulting commits after rebase should be mostly empty. For patches"
echo "that haven't been upstreamed, resolve conflicts prioritizing 'theirs' when"
echo "possible to preserve WebKit's changes."
echo
echo "The script will pause now. Please complete the rebase, then come back and"
echo "press Enter to continue:"
read -r
while in_rebase && ! GIT_EDITOR=true git rebase --continue; do
echo
echo "Rebase still in progress. Complete the rebase and press Enter to continue:"
read -r
done
}
cleanup_after_successful_rebase_and_exit() {
cd "$ANGLE_DIR"
echo
generate_changes_diff "$ANGLE_TARGET_COMMIT"
git --no-pager diff -b --cached "$LAST_ROLL_COMMIT_HASH" -- Compiler.cmake GLESv2.cmake
echo
echo "Rebase complete!"
echo "Above are the changes to Compiler.cmake and GLESv2.cmake."
echo "Now you'll need to apply the equivalent changes to the ANGLE XCode"
echo "project and make sure it builds. Please examine changes.diff and"
echo "undo any unintentional changes or unnecessary added files."
echo "You can examine the rebased history in the temporary git repository in"
echo "Source/ThirdParty/ANGLE to see where changes came from."
echo
echo "This script will pause now. Press Enter to continue when you're"
echo "done. The script will generate changes.diff and delete the"
echo "temporary git repository in Source/ThirdParty/ANGLE."
echo
echo "Press Enter to continue after fixing build:"
generate_sources
read -r
generate_sources
generate_changes_diff "$ANGLE_TARGET_COMMIT"
echo "Generating contents of commit message into commit-message.txt."
echo "Be sure to copy out this file's contents and delete it before committing."
echo "Update ANGLE to $(git log -1 ${COMMIT_HASH} --format=%cs) (${COMMIT_HASH})" > commit-message.txt
echo "Need the bug URL (OOPS!)." >> commit-message.txt
echo "Include a Radar link (OOPS!)." >> commit-message.txt
echo "" >> commit-message.txt
echo "Reviewed by NOBODY (OOPS!)" >> commit-message.txt
echo "" >> commit-message.txt
echo "Contains upstream commits:" >> commit-message.txt
echo git log --oneline "$PREVIOUS_ANGLE_COMMIT_HASH".."$COMMIT_HASH" --pretty="%h %s" >> commit-message.txt
git log --oneline "$PREVIOUS_ANGLE_COMMIT_HASH".."$COMMIT_HASH" --pretty="%h %s" >> commit-message.txt
echo "Removing temporary git repository from Source/ThirdParty/ANGLE"
rm -rf .git
git add -A .
# Undo the addition of commit-message.txt to make it easier for the user to remove.
git restore --staged commit-message.txt
echo
echo "ANGLE update is now staged. Ready to commit and upload patch."
exit 0
}
if wait_for_rebase_to_complete ; then
cleanup_after_successful_rebase_and_exit
fi
cd ../../..
echo "Creating WebKit branch that only contains ANGLE changes, using git-filter-repo."
echo "This may take a few minutes, but massively speeds up rebasing later."
git branch -f just-angle ${WEBKIT_TARGET_COMMIT} && git-filter-repo --refs refs/heads/just-angle --path Source/ThirdParty/ANGLE --path-rename Source/ThirdParty/ANGLE/: --force
cd "$ANGLE_DIR"
echo "Downloading latest ANGLE via git clone."
# Remove all files including hidden ones, but not . or ..
rm -rf ..?* .[!.]* ./*
git clone https://chromium.googlesource.com/angle/angle .
echo "Successfully downloaded latest ANGLE."
git checkout -q "$ANGLE_TARGET_COMMIT"
echo "Commit hash: "
COMMIT_HASH=$(git rev-parse HEAD)
echo "$COMMIT_HASH"
echo ""
echo "Generating angle_commit.h"
angle_commit_file="$(mktemp /tmp/angle_commit.h.TEMP.XXXX)"
./src/commit_id.py gen "${angle_commit_file}"
echo "Applying WebKit's local ANGLE changes to the old ANGLE version."
echo "Fetching WebKit changes into ANGLE repo."
git remote add webkit ../../.. -t just-angle
git fetch webkit
git checkout just-angle
PREVIOUS_ANGLE_COMMIT_HASH=$(grep -m 1 -o -E "[a-z0-9]{40}" ANGLE.plist)
LAST_ROLL_COMMIT_HASH=$(git log --format="%H" -1 ANGLE.plist)
echo "Updating ANGLE.plist commit hashes."
sed -i.bak -e "s/\([^a-z0-9]\)[a-z0-9]\{40\}\([^a-z0-9]\)/\1$COMMIT_HASH\2/g" ANGLE.plist
echo "Updating ANGLE.plist date."
sed -i.bak -e "s/<string>[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]<\/string>/<string>$(date +%Y-%m-%d)<\/string>/g" ANGLE.plist
rm ANGLE.plist.bak
echo "Translating gni build files to cmake."
git checkout "$ANGLE_TARGET_COMMIT" -- src/compiler.gni src/libGLESv2.gni src/libANGLE/renderer/d3d/BUILD.gn
./gni-to-cmake.py src/compiler.gni Compiler.cmake
./gni-to-cmake.py src/libGLESv2.gni GLESv2.cmake
./gni-to-cmake.py src/libANGLE/renderer/d3d/BUILD.gn D3D.cmake --prepend 'src/libANGLE/renderer/d3d/'
./gni-to-cmake.py src/libANGLE/renderer/gl/BUILD.gn GL.cmake --prepend 'src/libANGLE/renderer/gl/'
./gni-to-cmake.py src/libANGLE/renderer/metal/BUILD.gn Metal.cmake --prepend 'src/libANGLE/renderer/metal/'
git checkout src/compiler.gni src/libGLESv2.gni
echo "Moving angle_commit.h into place"
mv "${angle_commit_file}" WebKit/angle_commit.h
git add -A .
git commit -m "Updated ANGLE.plist, angle_commit.h and cmake files."
# Graft the WebKit commit history on top of the ANGLE commit history at
# the point of the last ANGLE roll. This will allow us to rebase just
# the WebKit changes since the last roll on top of ANGLE main.
git replace --graft "$LAST_ROLL_COMMIT_HASH" "$PREVIOUS_ANGLE_COMMIT_HASH"
# Rebase the WebKit commit history on top of ANGLE main.
git checkout -b rebased-webkit-changes
echo "Rebasing WebKit's local changes on latest ANGLE main."
if ! git rebase "$ANGLE_TARGET_COMMIT"; then
echo
echo "There is now a temporary git repo in Source/ThirdParty/ANGLE with a"
echo "rebase in progress. You must resolve the merge conflict and continue"
echo "the rebase. Make sure to do this in the temporary"
echo "Source/ThirdParty/ANGLE repo, not the main WebKit repo."
wait_for_rebase_to_complete
fi
cleanup_after_successful_rebase_and_exit