[PATCH] D49116: Setup clang-format as an Arcanist linter

Siddhartha Bagaria via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 9 18:17:26 PDT 2018


starsid created this revision.
starsid added a reviewer: probinson.
Herald added a subscriber: llvm-commits.

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.


Repository:
  rL LLVM

https://reviews.llvm.org/D49116

Files:
  .arcanist/
  .arcanist/linters/
  .arcanist/linters/clang-format.sh
  .arclint


Index: .arclint
===================================================================
--- /dev/null
+++ .arclint
@@ -0,0 +1,12 @@
+{
+  "linters": {
+    "clang-format": {
+      "type": "script-and-regex",
+      "script-and-regex.script": ".arcanist/linters/clang-format.sh",
+      "script-and-regex.regex": "/^(?P<autofix>#)(?P<message>.*?)\n(?P<line>\\d),(?P<char>\\d)\n(?P<original>.*)>>>>\n(?P<replacement>.*)$/s",
+      "include": [
+        "(\\.(cpp|h)$)"
+      ]
+    }
+  }
+}
Index: .arcanist/linters/clang-format.sh
===================================================================
--- /dev/null
+++ .arcanist/linters/clang-format.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+set -euo pipefail
+
+# 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/
+
+if ! command -v clang-format-diff >/dev/null; then
+  RED='\033[0;31m'
+  NC='\033[0m' # No Color
+  echo -e "${RED}Please install clang-format-diff for arcanist to lint C/C++ source code.${NC}" >&2
+  exit 1
+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 list 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 "#clang-format suggested style edits found:"
+  echo "1,1"  # line,char of start of replacement.
+  cat "${src_file}"
+  echo ">>>>"
+  cat "${formatted_file}"
+fi


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49116.154745.patch
Type: text/x-patch
Size: 2353 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180710/d09f420b/attachment.bin>


More information about the llvm-commits mailing list