33set -e
44
55script_folder=` dirname $0 `
6+ absolute_repository_root=` readlink -f $script_folder /..`
67
7- if [[ " $# " -ne 2 ]]
8+ if [[ " $# " -gt 2 ]]
89then
9- echo " Script for running the CPP linter only on modified lines."
10- echo " Requires two arguments the start and the end"
11- echo " start - a git reference that marks the first commit whose changes to consider"
12- echo " end - a git reference that marks the last commit whose changes to consider"
13-
10+ echo " Script for running the CPP linter only on modified lines. Arguments:"
11+ echo " target - a git reference to the branch we want to compare against (default: 'master')"
12+ echo " tip - a git reference to the commit with changes (default: current working tree)"
1413 exit 1
1514fi
1615
2120 exit 1
2221fi
2322
24- git_start=$1
25- git_end=$2
23+ if [[ " $# " -gt 0 ]]
24+ then
25+ git_start=$1
26+ else
27+ git_start=" master"
28+ fi
2629
27- # Get the list of files that have changed
28- diff_files=` git diff --name-only $git_start $git_end `
30+ if [[ " $# " -gt 1 ]]
31+ then
32+ git_end=$2
33+ git_merge_base_end=$2
34+ else
35+ git_end=" "
36+ git_merge_base_end=" HEAD"
37+ fi
38+
39+ git_start=` git merge-base $git_start $git_merge_base_end `
2940
30- # Build a filter that will filter the blame output
31- # to only include lines that come from one of the relevant_commits
32- # We do this by making the blame tool output the same hash for all
33- # lines that are too old.
34- blame_grep_filter=` git rev-parse " $git_start " `
41+ cleanup ()
42+ {
43+ rm -f $diff_file
44+ }
3545
36- # Build a regex for finding the line number of a given line inside blame
37- # First matches the 40 digit hash of the commi
38- # Then match an arbitary length number that represents the line in the original file
39- # Finally matches (and groups) another arbitary length digit which is the
40- # line in the final file
41- regex=" [0-9a-f]{40} [0-9]+ ([0-9]+)"
46+ trap cleanup EXIT
4247
43- # We only split on lines or otherwise the git blame output is nonsense
44- IFS=$' \n '
48+ diff_file=` mktemp`
4549
46- are_errors=0
50+ git diff $git_start $git_end > $diff_file
51+
52+ # Get the list of files that have changed
53+ diff_files=` git diff --name-only $git_start $git_end `
4754
4855for file in $diff_files ; do
56+ file=$absolute_repository_root /$file
4957 # If the file has been deleted we don't want to run the linter on it
5058 if ! [[ -e $file ]]
5159 then
5260 continue
5361 fi
5462
55- # We build another grep filter the output of the linting script
56- lint_grep_filter=" ^("
57-
58- # Include line 0 errors (e.g. copyright)
59- lint_grep_filter+=$file
60- lint_grep_filter+=" :0:"
61-
62- # We first filter only the lines that start with a commit hash
63- # Then we filter out the ones that come from the start commit
64- modified_lines=` git blame $git_start ..$git_end --line-porcelain $file | grep -E " ^[0-9a-f]{40}" | { grep -v " $blame_grep_filter " || true ; }`
65-
66- # For each modified line we find the line number
67- for line in $modified_lines ; do
68-
69- # Use the above regex to match the line number
70- if [[ $line =~ $regex ]]
71- then
72- # Some bash magic to get the first group from the regex (the line number)
73- LINENUM=" ${BASH_REMATCH[1]} "
74-
75- # The format from the linting script is filepath:linenum: [error type]
76- # So we build the first bit to filter out relevant lines
77- LINE_FILTER=$file :$LINENUM :
78-
79- # Add the line filter on to the grep expression as we want
80- # lines that match any of the line filters
81- lint_grep_filter+=" |"
82- lint_grep_filter+=$LINE_FILTER
83- fi
84- done
85-
86- # Add the closing bracket
87- lint_grep_filter+=" )"
88-
89- # Run the linting script and filter by the filter we've build
90- # of all the modified lines
63+ # Run the linting script and filter:
9164 # The errors from the linter go to STDERR so must be redirected to STDOUT
92- result=` $script_folder /cpplint.py $file 2>&1 | { grep -E " $lint_grep_filter " || true ; } `
65+ result=` $script_folder /cpplint.py $file 2>&1 | $script_folder /filter_lint_by_diff.py $diff_file $absolute_repository_root `
9366
9467 # Providing some errors were relevant we print them out
9568 if [ " $result " ]
@@ -99,7 +72,5 @@ for file in $diff_files; do
9972 fi
10073done
10174
102- unset IFS
103-
10475# Return an error code if errors are found
10576exit $are_errors
0 commit comments