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 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#)(?P.*?)\n(?P\\d),(?P\\d)\n(?P.*)>>>>\n(?P.*)$/s", + "include": [ + "(\\.(cpp|h)$)" + ] + } + } +}