aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorSiddhartha Bagaria <sbagaria@grailbio.com>2020-03-30 14:20:58 -0400
committerScott Linder <Scott.Linder@amd.com>2020-03-30 15:02:33 -0400
commit3c371491a2d5023060391ff54b924bf1c7a0c41f (patch)
treee7eb6c4ee879ff220e2a413dbcf3cb621ac79116 /utils
parent0af6d27e2ee2aa7365449e0f3c0f4727357a9584 (diff)
downloadllvm-3c371491a2d5023060391ff54b924bf1c7a0c41f.zip
llvm-3c371491a2d5023060391ff54b924bf1c7a0c41f.tar.gz
llvm-3c371491a2d5023060391ff54b924bf1c7a0c41f.tar.bz2
Setup clang-format as an Arcanist linter
Summary: This uses clang-format-diff as a linter for Arcanist. `arc lint` flow, also run as part of `arc diff` unless skipped with `--nolint`, will now run the linter shell script on the changed files, and prompt the user to accept the suggested changes. Message when clang-format-diff is not installed: {F6654094} Example of the noise during code review when clang-format-diff is not installed: https://reviews.llvm.org/differential/changeset/?ref=1115809 Prompt when clang-format-diff is installed and suggests edits: {F6650223} Reviewers: probinson, scott.linder Reviewed By: scott.linder Subscribers: scott.linder, MyDeveloperDay, JonasToth, danilaml, JDevlieghere, dberris, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D49116
Diffstat (limited to 'utils')
-rwxr-xr-xutils/arcanist/clang-format.sh59
1 files changed, 59 insertions, 0 deletions
diff --git a/utils/arcanist/clang-format.sh b/utils/arcanist/clang-format.sh
new file mode 100755
index 0000000..7ba7068
--- /dev/null
+++ b/utils/arcanist/clang-format.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+set -euo pipefail
+
+# "script-and-regex.regex": "/^(?P<severity>.*?)\n(?P<message>.*?)\n(?P<line>\\d),(?P<char>\\d)(\n(?P<original>.*?)>>>>\n(?P<replacement>.*?)<<<<?)$/s",
+
+# Arcanist linter that invokes clang-format.
+# stdout from this script is parsed into a regex and used by Arcanist.
+# https://secure.phabricator.com/book/phabricator/article/arcanist_lint_script_and_regex/
+
+# To skip running all linters when creating/updating a diff, use `arc diff --nolint`.
+
+if ! hash clang-format-diff >/dev/null; then
+ # advice severity level is completely non-disruptive.
+ # switch to warning or error if you want to prompt the user.
+ echo "advice"
+ echo "clang-format-diff not found in user's PATH; not linting file."
+ echo "===="
+ exit 0
+fi
+
+src_file="${1}"
+original_file="$(mktemp)"
+formatted_file="$(mktemp)"
+readonly src_file
+readonly original_file
+readonly formatted_file
+cp -p "${src_file}" "${original_file}"
+cp -p "${src_file}" "${formatted_file}"
+
+cleanup() {
+ rc=$?
+ rm "${formatted_file}" "${original_file}"
+ exit ${rc}
+}
+trap 'cleanup' INT HUP QUIT TERM EXIT
+
+# Arcanist can filter out lint messages for unchanged lines, but for that, we
+# need to generate line by line lint messages. Instead, we generate one lint
+# message on line 1, char 1 with file content edited using clang-format-diff.
+if git rev-parse --git-dir >/dev/null; then
+ arc_base_commit=$(arc which --show-base)
+ # An alternative is to use git-clang-format.
+ git diff -U0 --no-color "${arc_base_commit}"| clang-format-diff -style LLVM -i -p1
+else
+ svn diff --diff-cmd=diff -x -U0 "${src_file}" | clang-format-diff -style LLVM -i
+fi
+
+cp -p "${src_file}" "${formatted_file}"
+cp -p "${original_file}" "${src_file}"
+if ! diff -q "${src_file}" "${formatted_file}" > /dev/null ; then
+ echo "autofix"
+ echo "clang-format suggested style edits found:"
+ echo "1,1" # line,char of start of replacement.
+ cat "${src_file}"
+ echo ">>>>"
+ cat "${formatted_file}"
+ echo "<<<<"
+fi