summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/build_tools/format-diff.sh
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xsrc/rocksdb/build_tools/format-diff.sh203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/rocksdb/build_tools/format-diff.sh b/src/rocksdb/build_tools/format-diff.sh
new file mode 100755
index 000000000..62e8834f7
--- /dev/null
+++ b/src/rocksdb/build_tools/format-diff.sh
@@ -0,0 +1,203 @@
+#!/usr/bin/env bash
+# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+# If clang_format_diff.py command is not specfied, we assume we are able to
+# access directly without any path.
+
+print_usage () {
+ echo "Usage:"
+ echo "format-diff.sh [OPTIONS]"
+ echo "-c: check only."
+ echo "-h: print this message."
+}
+
+while getopts ':ch' OPTION; do
+ case "$OPTION" in
+ c)
+ CHECK_ONLY=1
+ ;;
+ h)
+ print_usage
+ exit 1
+ ;;
+ ?)
+ print_usage
+ exit 1
+ ;;
+ esac
+done
+
+REPO_ROOT="$(git rev-parse --show-toplevel)"
+
+if [ "$CLANG_FORMAT_DIFF" ]; then
+ echo "Note: CLANG_FORMAT_DIFF='$CLANG_FORMAT_DIFF'"
+ # Dry run to confirm dependencies like argparse
+ if $CLANG_FORMAT_DIFF --help >/dev/null < /dev/null; then
+ true #Good
+ else
+ exit 128
+ fi
+else
+ # First try directly executing the possibilities
+ if clang-format-diff --help &> /dev/null < /dev/null; then
+ CLANG_FORMAT_DIFF=clang-format-diff
+ elif clang-format-diff.py --help &> /dev/null < /dev/null; then
+ CLANG_FORMAT_DIFF=clang-format-diff.py
+ elif $REPO_ROOT/clang-format-diff.py --help &> /dev/null < /dev/null; then
+ CLANG_FORMAT_DIFF=$REPO_ROOT/clang-format-diff.py
+ else
+ # This probably means we need to directly invoke the interpreter.
+ # But first find clang-format-diff.py
+ if [ -f "$REPO_ROOT/clang-format-diff.py" ]; then
+ CFD_PATH="$REPO_ROOT/clang-format-diff.py"
+ elif which clang-format-diff.py &> /dev/null; then
+ CFD_PATH="$(which clang-format-diff.py)"
+ else
+ echo "You didn't have clang-format-diff.py and/or clang-format available in your computer!"
+ echo "You can download clang-format-diff.py by running: "
+ echo " curl --location https://raw.githubusercontent.com/llvm/llvm-project/main/clang/tools/clang-format/clang-format-diff.py -o ${REPO_ROOT}/clang-format-diff.py"
+ echo "You should make sure the downloaded script is not compromised."
+ echo "You can download clang-format by running:"
+ echo " brew install clang-format"
+ echo " Or"
+ echo " apt install clang-format"
+ echo " This might work too:"
+ echo " yum install git-clang-format"
+ echo "Then make sure clang-format is available and executable from \$PATH:"
+ echo " clang-format --version"
+ exit 128
+ fi
+ # Check argparse pre-req on interpreter, or it will fail
+ if echo import argparse | ${PYTHON:-python3}; then
+ true # Good
+ else
+ echo "To run clang-format-diff.py, we'll need the library "argparse" to be"
+ echo "installed. You can try either of the follow ways to install it:"
+ echo " 1. Manually download argparse: https://pypi.python.org/pypi/argparse"
+ echo " 2. easy_install argparse (if you have easy_install)"
+ echo " 3. pip install argparse (if you have pip)"
+ exit 129
+ fi
+ # Unfortunately, some machines have a Python2 clang-format-diff.py
+ # installed but only a Python3 interpreter installed. Unfortunately,
+ # automatic 2to3 migration is insufficient, so suggest downloading latest.
+ if grep -q "print '" "$CFD_PATH" && \
+ ${PYTHON:-python3} --version | grep -q 'ython 3'; then
+ echo "You have clang-format-diff.py for Python 2 but are using a Python 3"
+ echo "interpreter (${PYTHON:-python3})."
+ echo "You can download clang-format-diff.py for Python 3 by running: "
+ echo " curl --location https://raw.githubusercontent.com/llvm/llvm-project/main/clang/tools/clang-format/clang-format-diff.py -o ${REPO_ROOT}/clang-format-diff.py"
+ echo "You should make sure the downloaded script is not compromised."
+ exit 130
+ fi
+ CLANG_FORMAT_DIFF="${PYTHON:-python3} $CFD_PATH"
+ # This had better work after all those checks
+ if $CLANG_FORMAT_DIFF --help >/dev/null < /dev/null; then
+ true #Good
+ else
+ exit 128
+ fi
+ fi
+fi
+
+# TODO(kailiu) following work is not complete since we still need to figure
+# out how to add the modified files done pre-commit hook to git's commit index.
+#
+# Check if this script has already been added to pre-commit hook.
+# Will suggest user to add this script to pre-commit hook if their pre-commit
+# is empty.
+# PRE_COMMIT_SCRIPT_PATH="`git rev-parse --show-toplevel`/.git/hooks/pre-commit"
+# if ! ls $PRE_COMMIT_SCRIPT_PATH &> /dev/null
+# then
+# echo "Would you like to add this script to pre-commit hook, which will do "
+# echo -n "the format check for all the affected lines before you check in (y/n):"
+# read add_to_hook
+# if [ "$add_to_hook" == "y" ]
+# then
+# ln -s `git rev-parse --show-toplevel`/build_tools/format-diff.sh $PRE_COMMIT_SCRIPT_PATH
+# fi
+# fi
+set -e
+
+uncommitted_code=`git diff HEAD`
+
+# If there's no uncommitted changes, we assume user are doing post-commit
+# format check, in which case we'll try to check the modified lines vs. the
+# facebook/rocksdb.git main branch. Otherwise, we'll check format of the
+# uncommitted code only.
+if [ -z "$uncommitted_code" ]
+then
+ # Attempt to get name of facebook/rocksdb.git remote.
+ [ "$FORMAT_REMOTE" ] || FORMAT_REMOTE="$(LC_ALL=POSIX LANG=POSIX git remote -v | grep 'facebook/rocksdb.git' | head -n 1 | cut -f 1)"
+ # Fall back on 'origin' if that fails
+ [ "$FORMAT_REMOTE" ] || FORMAT_REMOTE=origin
+ # Use main branch from that remote
+ [ "$FORMAT_UPSTREAM" ] || FORMAT_UPSTREAM="$FORMAT_REMOTE/$(LC_ALL=POSIX LANG=POSIX git remote show $FORMAT_REMOTE | sed -n '/HEAD branch/s/.*: //p')"
+ # Get the common ancestor with that remote branch. Everything after that
+ # common ancestor would be considered the contents of a pull request, so
+ # should be relevant for formatting fixes.
+ FORMAT_UPSTREAM_MERGE_BASE="$(git merge-base "$FORMAT_UPSTREAM" HEAD)"
+ # Get the differences
+ diffs=$(git diff -U0 "$FORMAT_UPSTREAM_MERGE_BASE" | $CLANG_FORMAT_DIFF -p 1)
+ echo "Checking format of changes not yet in $FORMAT_UPSTREAM..."
+else
+ # Check the format of uncommitted lines,
+ diffs=$(git diff -U0 HEAD | $CLANG_FORMAT_DIFF -p 1)
+ echo "Checking format of uncommitted changes..."
+fi
+
+if [ -z "$diffs" ]
+then
+ echo "Nothing needs to be reformatted!"
+ exit 0
+elif [ $CHECK_ONLY ]
+then
+ echo "Your change has unformatted code. Please run make format!"
+ if [ $VERBOSE_CHECK ]; then
+ clang-format --version
+ echo "$diffs"
+ fi
+ exit 1
+fi
+
+# Highlight the insertion/deletion from the clang-format-diff.py's output
+COLOR_END="\033[0m"
+COLOR_RED="\033[0;31m"
+COLOR_GREEN="\033[0;32m"
+
+echo -e "Detect lines that doesn't follow the format rules:\r"
+# Add the color to the diff. lines added will be green; lines removed will be red.
+echo "$diffs" |
+ sed -e "s/\(^-.*$\)/`echo -e \"$COLOR_RED\1$COLOR_END\"`/" |
+ sed -e "s/\(^+.*$\)/`echo -e \"$COLOR_GREEN\1$COLOR_END\"`/"
+
+echo -e "Would you like to fix the format automatically (y/n): \c"
+
+# Make sure under any mode, we can read user input.
+exec < /dev/tty
+read to_fix
+
+if [ "$to_fix" != "y" ]
+then
+ exit 1
+fi
+
+# Do in-place format adjustment.
+if [ -z "$uncommitted_code" ]
+then
+ git diff -U0 "$FORMAT_UPSTREAM_MERGE_BASE" | $CLANG_FORMAT_DIFF -i -p 1
+else
+ git diff -U0 HEAD | $CLANG_FORMAT_DIFF -i -p 1
+fi
+echo "Files reformatted!"
+
+# Amend to last commit if user do the post-commit format check
+if [ -z "$uncommitted_code" ]; then
+ echo -e "Would you like to amend the changes to last commit (`git log HEAD --oneline | head -1`)? (y/n): \c"
+ read to_amend
+
+ if [ "$to_amend" == "y" ]
+ then
+ git commit -a --amend --reuse-message HEAD
+ echo "Amended to last commit"
+ fi
+fi