forked from linux-test-project/lcov
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheckstyle.sh
executable file
·186 lines (152 loc) · 4.22 KB
/
checkstyle.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/bin/bash
#
# checkstyle.sh FILENAME(S)
#
# Check specified files for coding style issues. The mode of checking is
# selected using the MODE environment variable:
#
# MODE:
# diff Report only issues on code changed since git HEAD (default)
# full Report all issues
#
# Note: Currently checking is restricted to Perl files
# Return absolute path
function realpath() {
local path="$1"
if [[ -d "$path" ]] ; then
echo "$(cd "$path" && pwd)"
else
echo "$(cd "$(dirname "$path")" && pwd)/$(basename "$1")"
fi
}
# Return path relative to TOOLDIR
function relpath() {
local inpath="$1" outpath
outpath="${1##$TOOLDIR/}"
echo "$outpath"
# Let caller know if path was inside TOOLDIR
[[ "$inpath" != "$outpath" ]]
}
# Terminate with an error message
function die() {
echo "Error: $*" >&2
exit 1
}
# List source lines that violate the style guide rules. If an original file
# is supplied, only report new findings.
function report() {
local file="$1" tidy="$2" origfile="${3:-}" origtidy="${4:-}"
local diffopts mark origmark newmark lineno continuation newline
local tag line
# Mark offending lines. An offending line is a line in the original
# file that was removed and replaced with a fixed line by the tidy
# script.
diffopts=(
'--old-line-format' '-%L' # Mark changed lines
'--new-line-format' '' # Remove fixed lines
'--unchanged-line-format' ' %L' # Leave other lines
'--minimal'
)
mark="$TEMPDIR/${file##*/}.marked"
diff "${diffopts[@]}" "$file" "$tidy" >"$mark"
origmark="$TEMPDIR/${file##*/}.origmarked"
if [[ -n "$origfile" ]] ; then
# Use original version as baseline
diff "${diffopts[@]}" "$origfile" "$origtidy" >"$origmark"
else
# Use full file as baseline
sed -e 's/^/ /g' "$file" >"$origmark"
fi
# Mark lines that are added compared to baseline
diffopts=(
'--old-line-format' '' # Remove old lines
'--new-line-format' '+%L' # Mark changed lines
'--unchanged-line-format' ' %L' # Leave other lines
'--minimal'
)
newmark="$TEMPDIR/${file##*/}.newmarked"
diff "${diffopts[@]}" "$origmark" "$mark" >"$newmark"
if ! grep -q '^+-' "$newmark" ; then
echo "$file has no obvious style issues"
return 0
fi
if [[ -z "$origfile" ]] ; then
echo "Listing all findings in $file:"
else
echo "Listing findings in $file since git ref $GITBASE:"
fi
echo
# Display groups of newly introduced offending lines
lineno=1
continuation=0
newline=0
while read -r line ; do
tag=${line:0:2}
line=${line:2}
if [[ "$tag" == "+-" ]] ; then
# + means: introduced after baseline
# - means: an offending line
if [[ "$continuation" -eq 0 ]] ; then
if [[ "$newline" -eq 1 ]] ; then
echo
newline=0
fi
echo "In $file line $lineno:"
continuation=1
fi
echo "+${line//$'\t'/^I}"
else
if [[ "$continuation" -eq 1 ]] ; then
newline=1
continuation=0
fi
fi
(( lineno++ ))
done < "$newmark"
echo
echo "$file has style issues, please review (see also $tidy)." >&2
return 1
}
TOOLDIR="$(realpath "$(dirname "$0")"/..)"
PERLTIDY="${PERLTIDY:-perltidy}"
PERLTIDYRC="${PERLTIDYRC:-$TOOLDIR/.perltidyrc}"
# HEAD is default baseline
GITBASE=${GITBASE:-HEAD}
# diff is default mode
MODE=${MODE:-diff}
#MODE=${MODE@L}
case "$MODE" in
"diff") [[ ! -d "$TOOLDIR/.git" ]] && die "Not in a git repository" ;;
"full") ;;
*) die "Unknown checking mode '$MODE'" ;;
esac
TEMPDIR=$(mktemp -d) || die "Could not create temporary directory"
trap "rm -rf '$TEMPDIR'" exit
RC=0
for FILE in "${@}" ; do
BASE=${FILE##*/}
TIDY="$FILE.tdy"
if [[ "$MODE" == "diff" ]] ; then
GITFILE="$TEMPDIR/$BASE.git"
GITTIDY="$TEMPDIR/$BASE.git.tdy"
RELFILE="$(relpath "$(realpath "$FILE")")" ||
die "$FILE is outside of git repository"
git show "$GITBASE:$RELFILE" >"$GITFILE" ||
die "No version of $FILE found in git ref $GITBASE"
"$PERLTIDY" --profile="$PERLTIDYRC" "$GITFILE" -o "$GITTIDY" ||
die "Could not check git version of $FILE"
"$PERLTIDY" --profile="$PERLTIDYRC" "$FILE" -o "$TIDY" ||
die "Could not check $FILE"
report "$FILE" "$TIDY" "$GITFILE" "$GITTIDY"
else
"$PERLTIDY" --profile="$PERLTIDYRC" "$FILE" -o "$TIDY" ||
die "Could not check $FILE"
report "$FILE" "$TIDY"
fi
if [[ $? -ne 0 ]] ; then
RC=1
else
rm -f "$TIDY"
fi
done
exit $RC