Skip to content

Commit 4c50ffe

Browse files
Report cpplint errors only for changed lines
1 parent 071022e commit 4c50ffe

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ matrix:
3636
compiler: clang
3737
env: COMPILER=clang++
3838
- env: NAME="CPP-LINT"
39-
script: DIFF=`git diff --name-only master HEAD` && if [ "$DIFF" != "" ]; then python scripts/cpplint.py $DIFF; fi
39+
script: scripts/run_lint.sh master HEAD
4040

4141
script:
4242
- ./install.sh $COMPILER && cd regression && make test

scripts/run_lint.sh

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
if [[ "$#" -ne 2 ]]
6+
then
7+
echo "Script for running the CPP linter only on modified lines."
8+
echo "Requires two arguments the start and the end"
9+
echo "start - a git reference that marks the first commit whose changes to consider"
10+
echo "end - a git reference that marks the last commit whose changes to consider"
11+
12+
exit 1
13+
fi
14+
15+
if ! [[ -e scripts/cpplint.py ]]
16+
then
17+
echo "Lint script could not be found in the scripts directory"
18+
echo "Ensure cpplint.py is inside the scripts directory then run again"
19+
exit 1
20+
fi
21+
22+
git_start=$1
23+
git_end=$2
24+
25+
# Get the list of files that have changed
26+
diff_files=`git diff --name-only $git_start $git_end`
27+
28+
# Build a filter that will filter the blame output
29+
# to only include lines that come from one of the relevant_commits
30+
# We do this by making the blame tool output the same hash for all
31+
# lines that are too old.
32+
blame_grep_filter=`git rev-parse "$git_start"`
33+
34+
# Build a regex for finding the line number of a given line inside blame
35+
# First matches the 40 digit hash of the commi
36+
# Then match an arbitary length number that represents the line in the original file
37+
# Finally matches (and groups) another arbitary length digit which is the
38+
# line in the final file
39+
regex="[0-9a-f]{40} [0-9]+ ([0-9]+)"
40+
41+
# We only split on lines or otherwise the git blame output is nonsense
42+
IFS=$'\n'
43+
44+
are_errors=0
45+
46+
for file in $diff_files; do
47+
# We build another grep filter the output of the linting script
48+
lint_grep_filter="^("
49+
50+
# Include line 0 errors (e.g. copyright)
51+
lint_grep_filter+=$file
52+
lint_grep_filter+=":0"
53+
54+
# We first filter only the lines that start with a commit hash
55+
# Then we filter out the ones that come from the start commit
56+
modified_lines=`git blame $git_start..$git_end --line-porcelain $file | grep -E "^[0-9a-f]{40}" | { grep -v "$blame_grep_filter" || true; }`
57+
58+
# For each modified line we find the line number
59+
for line in $modified_lines; do
60+
61+
# Use the above regex to match the line number
62+
if [[ $line =~ $regex ]]
63+
then
64+
# Some bash magic to get the first group from the regex (the line number)
65+
LINENUM="${BASH_REMATCH[1]}"
66+
67+
# The format from the linting script is filepath:linenum: [error type]
68+
# So we build the first bit to filter out relevant lines
69+
LINE_FILTER=$file:$LINENUM
70+
71+
# Add the line filter on to the grep expression as we want
72+
# lines that match any of the line filters
73+
lint_grep_filter+="|"
74+
lint_grep_filter+=$LINE_FILTER
75+
fi
76+
done
77+
78+
# Add the closing bracket
79+
lint_grep_filter+=")"
80+
81+
# Run the linting script and filter by the filter we've build
82+
# of all the modified lines
83+
# The errors from the linter go to STDERR so must be redirected to STDOUT
84+
result=`python scripts/cpplint.py $file 2>&1 | { grep -E "$lint_grep_filter" || true; }`
85+
86+
# Providing some errors were relevant we print them out
87+
if [ "$result" ]
88+
then
89+
are_errors=1
90+
(>&2 echo "$result")
91+
fi
92+
done
93+
94+
unset IFS
95+
96+
# Return an error code if errors are found
97+
exit $are_errors

0 commit comments

Comments
 (0)