3
3
set -e
4
4
5
5
script_folder=` dirname $0 `
6
+ absolute_repository_root=` readlink -f $script_folder /..`
6
7
7
- if [[ " $# " -ne 2 ]]
8
+ if [[ " $# " -gt 2 ]]
8
9
then
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)"
14
13
exit 1
15
14
fi
16
15
21
20
exit 1
22
21
fi
23
22
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
26
29
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 `
29
40
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
+ }
35
45
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
42
47
43
- # We only split on lines or otherwise the git blame output is nonsense
44
- IFS=$' \n '
48
+ diff_file=` mktemp`
45
49
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 `
47
54
48
55
for file in $diff_files ; do
56
+ file=$absolute_repository_root /$file
49
57
# If the file has been deleted we don't want to run the linter on it
50
58
if ! [[ -e $file ]]
51
59
then
52
60
continue
53
61
fi
54
62
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:
91
64
# 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 `
93
66
94
67
# Providing some errors were relevant we print them out
95
68
if [ " $result " ]
@@ -99,7 +72,5 @@ for file in $diff_files; do
99
72
fi
100
73
done
101
74
102
- unset IFS
103
-
104
75
# Return an error code if errors are found
105
76
exit $are_errors
0 commit comments