Revision control

Copy as Markdown

#!/bin/bash
# A (hacky) script for generating API reviews usage:
# ./doApiReview.sh oldVersionTag newVersionTag gerritUserName email name
# Example: ./doApiReview.sh v6.2.3 v6.3.0-alpha1 example.user example.user@qt.io "Example User"
# WARNING: This script runs rm -rf quite a lot, best run it in a separate jail where it can only wreck its immediate environment
set -e
BASE_MODULES=(qtshadertools qtdeclarative)
API_REVIEWS_FOR=(qtsensors qtpositioning qtwebchannel qtscxml qtcharts qt3d qtquick3d qtwayland qtwebengine)
checkout_qt_version() {
mod_list=$(printf ",%s" "${API_REVIEWS_FOR[@]}")
mod_list=${mod_list:1}
if [ -d "$1" ]; then
echo "'$1' already exists, skipping"
return 0
fi
mkdir $1 && cd $1
git clone $QT_GIT_REPO src
cd src
git checkout $1
perl init-repository --module-subset=qtbase,qtdeclarative,qtshadertools,$mod_list --codereview-username=$2
cd ../..
return 0 || return 1
}
build_qt_version() {
cd "$1"
found_all=1
for module in "${BASE_MODULES[@]}"; do
if [ ! -d "build/$module" ]; then
echo "Didn't find base module $module in $1"
found_all=0
break
fi
done
for module in "${API_REVIEWS_FOR[@]}"; do
if [ ! -d "build/$module" ]; then
echo "Didn't find $module in $1"
found_all=0
break
fi
if [ ! -d "$module-qml" ]; then
echo "Didn't find $module in $1"
found_all=0
break
fi
done
if [ $found_all -eq 1 ]; then
echo "All modules are built, skipping"
cd ..
return
fi
rm -rf build install base-install base-build *-qml && mkdir build && cd build
mkdir qtbase && cd qtbase
../../src/qtbase/configure -release -opensource -confirm-license -prefix ../../install
ninja install
cd ..
for module in "${BASE_MODULES[@]}"; do
mkdir $module
cd $module
../../install/bin/qt-configure-module $(pwd)/../../src/$module
ninja install
cd ..
done
cp -r ../install ../base-install && cp -r ../build ../base-build
for module in "${API_REVIEWS_FOR[@]}"; do
rm -rf $(pwd)/../install && cp -r $(pwd)/../base-install $(pwd)/../install && cp -r $(pwd)/../base-build $(pwd)/../build
mkdir $module
cd $module
if [ "$module" == "qt3d" ]; then
echo "Qt3D"
$(pwd)/../../install/bin/qt-configure-module $(pwd)/../../src/$module -no-feature-qt3d-assimp
elif [ "$module" == "qtquick3d" ]; then
echo "QtQuick3D"
$(pwd)/../../install/bin/qt-configure-module $(pwd)/../../src/$module -no-feature-quick3d-assimp
else
$(pwd)/../../install/bin/qt-configure-module $(pwd)/../../src/$module
fi
ninja install
cd ..
cp -r $(pwd)/../install/qml $(pwd)/../$module-qml
done
cd ../..
echo $(pwd)
}
function do_review() {
old=$1
new=$2
username=$3
email=$4
name=$5
module=$6
cd "$module"
gitdir=$(git rev-parse --git-dir);
# Download and install the gerrit pre-commit hook if it isn't already present
# Ideally this should be cached somewhere so we don't prompt every time
if [[ ! -f "$gitdir/hooks/commit-msg" ]]; then
scp -p -P 29418 $username@codereview.qt-project.org:hooks/commit-msg ${gitdir}/hooks/
fi
# Configure git
git config user.email "$email"
git config user.name "$name"
# Discard all unstaged changes
git reset --hard HEAD
# Reset to the latest dev commit
git checkout dev
# Remove any previous API review branch if present and replace it with a new one
git branch -D api_review_$1_$2 || true
git checkout -b api_review_$1_$2
# Nuke any left-overs from a previous review attempt and recreate the directory
rm -rf $(pwd)/qml-api-review || true
mkdir $(pwd)/qml-api-review
if [[ "$module" == "qtdeclarative" ]]; then
# base-install = qtdeclarative, so just copy that over.
cp -r $(pwd)/../../../$old/base-install/qml/* $(pwd)/qml-api-review
else
cp -r $(pwd)/../../../$old/$module-qml/* $(pwd)/qml-api-review
base_path=$(pwd)/../../../$old/base-install/qml
# Remove all files that are also present in the old base install, they should not be reviewed
cd qml-api-review; rm -rf $(cd $base_path && find . ! -path .); cd ..
fi
# Strip away binary artifacts
find $(pwd)/qml-api-review \( -name '*.dylib' -o -name '*.dll' -o -name '*.so' -o -name '*.png' \) -delete
qml_files=$(find $(pwd)/qml-api-review -type f -name '*.qml')
if [[ $qml_files ]]; then
perl -pe 'BEGIN { undef $/; }; s#(^/\*.*?\*/)(\r?\n)*?##ims' -i $qml_files
fi
# Commit API Review base commit
git add $(pwd)/qml-api-review
git commit -m "WIP: [Ignore] [QML Directory Base] $module $2 QML API Review" -m "This is a $old baseline commit for reviewing $new, please ignore. It has been auto-generated by doApiReview.sh"
if [ "$module" == "qtdeclarative" ]; then
# base-install = qtdeclarative, so just copy that over.
cp -r $(pwd)/../../../$new/base-install/qml/* $(pwd)/qml-api-review
else
cp -r $(pwd)/../../../$new/$module-qml/* $(pwd)/qml-api-review
base_path=$(pwd)/../../../$new/base-install/qml
# Remove all files that are also present in the old base install, they should not be reviewed
cd qml-api-review; rm -rf $(cd $base_path && find . ! -path .); cd ..
fi
# Strip away binary artifacts
find $(pwd)/qml-api-review \( -name '*.dylib' -o -name '*.dll' -o -name '*.so' -o -name '*.png' \) -delete
# Placeholder file in case we don't have any actual changes to commit
echo "Review file. If this is the only file then there are no changes for this module." > $(pwd)/qml-api-review/REVIEW-FILE
qml_files=$(find $(pwd)/qml-api-review/ -type f -name '*.qml')
if [[ $qml_files ]]; then
perl -pe 'BEGIN { undef $/; }; s#(^/\*.*?\*/)(\r?\n)*?##ims' -i $qml_files
fi
# Commit API Review
git add $(pwd)/qml-api-review
git commit -m "WIP: $module $new QML API Review" -m "This is a commit for reviewing the QML API of $module $new. It has been auto-generated by doApiReview.sh"
cd ..
}
function create_reviews() {
cd $(pwd)/dev/src
do_review "$1" "$2" "$3" "$4" "$5" "qtdeclarative"
for module in "${API_REVIEWS_FOR[@]}"; do
do_review "$1" "$2" "$3" "$4" "$5" "$module"
done
cd ../..
}
STEPS=3
OLD_VERSION=$1
NEW_VERSION=$2
CODEREVIEW_USERNAME=$3
EMAIL=$4
NAME=$5
echo "Reviewing $1 vs $2"
echo "[1/$STEPS] Preparing repositories..."
checkout_qt_version "$OLD_VERSION" "$CODEREVIEW_USERNAME"
checkout_qt_version "$NEW_VERSION" "$CODEREVIEW_USERNAME"
checkout_qt_version "dev" "$CODEREVIEW_USERNAME"
echo "[2/$STEPS] Building modules..."
build_qt_version "$OLD_VERSION"
build_qt_version "$NEW_VERSION"
echo "[3/$STEPS] Creating reviews..."
create_reviews "$OLD_VERSION" "$NEW_VERSION" "$CODEREVIEW_USERNAME" "$EMAIL" "$NAME"
echo "You can now find all the generated reviews in dev/src/MODULE_NAME. Please review them manually before pushing them to gerrit."