1#!/bin/sh 2 3# Usage: Run 'contrib/coverage-diff.sh <version1> <version2>' from source-root 4# after running 5# 6# make coverage-test 7# make coverage-report 8# 9# while checked out at <version2>. This script combines the *.gcov files 10# generated by the 'make' commands above with 'git diff <version1> <version2>' 11# to report new lines that are not covered by the test suite. 12 13V1=$1 14V2=$2 15 16diff_lines () { 17 perl -e ' 18 my $line_num; 19 while (<>) { 20 # Hunk header? Grab the beginning in postimage. 21 if (/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/) { 22 $line_num = $1; 23 next; 24 } 25 26 # Have we seen a hunk? Ignore "diff --git" etc. 27 next unless defined $line_num; 28 29 # Deleted line? Ignore. 30 if (/^-/) { 31 next; 32 } 33 34 # Show only the line number of added lines. 35 if (/^\+/) { 36 print "$line_num\n"; 37 } 38 # Either common context or added line appear in 39 # the postimage. Count it. 40 $line_num++; 41 } 42 ' 43} 44 45files=$(git diff --name-only "$V1" "$V2" -- \*.c) 46 47# create empty file 48>coverage-data.txt 49 50for file in $files 51do 52 git diff "$V1" "$V2" -- "$file" | 53 diff_lines | 54 sort >new_lines.txt 55 56 if ! test -s new_lines.txt 57 then 58 continue 59 fi 60 61 hash_file=$(echo $file | sed "s/\//\#/") 62 63 if ! test -s "$hash_file.gcov" 64 then 65 continue 66 fi 67 68 sed -ne '/#####:/{ 69 s/ #####:// 70 s/:.*// 71 s/ //g 72 p 73 }' "$hash_file.gcov" | 74 sort >uncovered_lines.txt 75 76 comm -12 uncovered_lines.txt new_lines.txt | 77 sed -e 's/$/\)/' | 78 sed -e 's/^/ /' >uncovered_new_lines.txt 79 80 grep -q '[^[:space:]]' <uncovered_new_lines.txt && 81 echo $file >>coverage-data.txt && 82 git blame -s "$V2" -- "$file" | 83 sed 's/\t//g' | 84 grep -f uncovered_new_lines.txt >>coverage-data.txt && 85 echo >>coverage-data.txt 86 87 rm -f new_lines.txt uncovered_lines.txt uncovered_new_lines.txt 88done 89 90cat coverage-data.txt 91 92echo "Commits introducing uncovered code:" 93 94commit_list=$(cat coverage-data.txt | 95 grep -E '^[0-9a-f]{7,} ' | 96 awk '{print $1;}' | 97 sort | 98 uniq) 99 100( 101 for commit in $commit_list 102 do 103 git log --no-decorate --pretty=format:'%an %h: %s' -1 $commit 104 echo 105 done 106) | sort 107 108rm coverage-data.txt 109