1#!/bin/bash 2 3set -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. 15if ! 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 20fi 21if ! 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 26fi 27 28src_file="${1}" 29original_file="$(mktemp)" 30formatted_file="$(mktemp)" 31readonly src_file 32readonly original_file 33readonly formatted_file 34cp -p "${src_file}" "${original_file}" 35cp -p "${src_file}" "${formatted_file}" 36 37cleanup() { 38 rc=$? 39 rm "${formatted_file}" "${original_file}" 40 exit ${rc} 41} 42trap '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. 54arc_base_commit=$(arc which --show-base) 55git diff-index -U0 "${arc_base_commit}" "${src_file}" \ 56 | clang/tools/clang-format/clang-format-diff.py -style file -i -p1 57 58cp -p "${src_file}" "${formatted_file}" 59cp -p "${original_file}" "${src_file}" 60if ! 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 "<<<<" 68fi 69