Skip to content

Commit 0e46795

Browse files
author
Daniel Kroening
authored
Merge pull request #405 from thk123/feature/lint-changed-lines
Modify Travis to only run the linter on modified lines
2 parents 8ef7511 + 2633d64 commit 0e46795

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

.travis.yml

+1-1
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
- make -C src minisat2-download

scripts/run_lint.sh

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

0 commit comments

Comments
 (0)