173
|
1 #!/bin/bash
|
|
2
|
|
3 set -euo pipefail
|
|
4
|
|
5 # "script-and-regex.regex": "/^(?P<severity>.*?)\n(?P<message>.*?)\n(?P<line>\\d),(?P<char>\\d)(\n(?P<original>.*?)>>>>\n(?P<replacement>.*?)<<<<?)$/s",
|
|
6
|
|
7 # Arcanist linter that invokes clang-format via clang/tools/clang-format/clang-format-diff.py
|
|
8 # stdout from this script is parsed into a regex and used by Arcanist.
|
|
9 # https://secure.phabricator.com/book/phabricator/article/arcanist_lint_script_and_regex/
|
|
10
|
|
11 # To skip running all linters when creating/updating a diff, use `arc diff --nolint`.
|
|
12
|
|
13 # advice severity level is completely non-disruptive.
|
|
14 # switch to warning or error if you want to prompt the user.
|
|
15 if ! hash clang-format >/dev/null; then
|
|
16 echo "advice"
|
|
17 echo "clang-format not found in user's PATH; not linting file."
|
|
18 echo "===="
|
|
19 exit 0
|
|
20 fi
|
|
21 if ! git rev-parse --git-dir >/dev/null; then
|
|
22 echo "advice"
|
|
23 echo "not in git repostitory; not linting file."
|
|
24 echo "===="
|
|
25 exit 0
|
|
26 fi
|
|
27
|
|
28 src_file="${1}"
|
|
29 original_file="$(mktemp)"
|
|
30 formatted_file="$(mktemp)"
|
|
31 readonly src_file
|
|
32 readonly original_file
|
|
33 readonly formatted_file
|
|
34 cp -p "${src_file}" "${original_file}"
|
|
35 cp -p "${src_file}" "${formatted_file}"
|
|
36
|
|
37 cleanup() {
|
|
38 rc=$?
|
|
39 rm "${formatted_file}" "${original_file}"
|
|
40 exit ${rc}
|
|
41 }
|
|
42 trap 'cleanup' INT HUP QUIT TERM EXIT
|
|
43
|
|
44 # Arcanist can filter out lint messages for unchanged lines, but for that, we
|
|
45 # need to generate line by line lint messages. Instead, we generate one lint
|
|
46 # message on line 1, char 1 with file content edited using clang-format-diff.py
|
|
47 #
|
|
48 # We do not use git-clang-format because it wants to modify the index,
|
|
49 # and arc is already holding the lock.
|
|
50 #
|
|
51 # We do not look for clang-format-diff or clang-format-diff.py in the PATH
|
|
52 # because whether/how these are installed differs between distributions,
|
|
53 # and we have an executable copy in the tree anyway.
|
|
54 arc_base_commit=$(arc which --show-base)
|
|
55 git diff-index -U0 "${arc_base_commit}" \
|
|
56 | clang/tools/clang-format/clang-format-diff.py -style file -i -p1
|
|
57
|
|
58 cp -p "${src_file}" "${formatted_file}"
|
|
59 cp -p "${original_file}" "${src_file}"
|
|
60 if ! diff -q "${src_file}" "${formatted_file}" > /dev/null ; then
|
|
61 echo "autofix"
|
|
62 echo "clang-format suggested style edits found:"
|
|
63 echo "1,1" # line,char of start of replacement.
|
|
64 cat "${src_file}"
|
|
65 echo ">>>>"
|
|
66 cat "${formatted_file}"
|
|
67 echo "<<<<"
|
|
68 fi
|