[FEATURE] Use SVG Trees in Record Selector
[Packages/TYPO3.CMS.git] / Build / Scripts / duplicateExceptionCodeCheck.sh
1 #!/bin/bash
2
3 #########################
4 #
5 # Find duplicate exception timestamps and list them.
6 # Additionally find exceptions that have no exception code.
7 # Optionally write the list of found exception codes to the standard output stream in JSON format.
8 #
9 # It expects to be run from the core root.
10 #
11 ##########################
12
13 # --------------------------
14 # --- default parameters ---
15 # --------------------------
16 print=0
17 scanPath="typo3/"
18
19 ignoreFiles=()
20 # auto generated file, shouldn't be checked
21 ignoreFiles+="sysext/core/Tests/Acceptance/Support/_generated/BackendTesterActions.php"
22 ignoreFiles+="sysext/core/Tests/Acceptance/Support/_generated/InstallTesterActions.php"
23 # an exception in here throws a code from a previous exception/error
24 ignoreFiles+="sysext/extbase/Classes/Core/Bootstrap.php"
25 ignoreFiles+="sysext/form/Classes/Mvc/Property/Exception/TypeConverterException.php"
26 ignoreFiles+="sysext/core/Classes/Database/Driver/PDOStatement.php"
27 ignoreFiles+="sysext/core/Classes/Database/Driver/PDOStatementImplementation.php"
28 ignoreFiles+="sysext/core/Classes/Database/Driver/PDOConnection.php"
29 ignoreFiles+="sysext/frontend/Classes/Typolink/PageLinkBuilder.php"
30
31 # ------------------------
32 # --- print usage info ---
33 # ------------------------
34 usage()
35 {
36 echo "Usage: $0 [options] "
37 echo " "
38 echo "No arguments/default: Check exception numbers for duplicates. "
39 echo " "
40 echo "Options: "
41 echo " -p "
42 echo " Specifies whether the list of exceptions found should "
43 echo " be output as JSON in the standard output stream. "
44 echo " "
45 echo " -h "
46 echo " Show this help. "
47 echo " "
48 exit 0
49 }
50
51 # -----------------------
52 # --- parsing of args ---
53 # -----------------------
54 OPTIND=1
55
56 while getopts "hp" opt;do
57 case "$opt" in
58 h)
59 usage
60 ;;
61 p)
62 print=1
63 ;;
64 *)
65 exit 1
66 ;;
67 esac
68 done
69
70 shift $((OPTIND-1))
71
72 # ------------------------------------------------
73 # --- print list of found exceptions to stdout ---
74 # ------------------------------------------------
75 print_exceptions() {
76 IFS=$'\n' sorted=($(sort -u <<<"${exceptionCodes[*]}")); unset IFS
77
78 local numExceptions=${#sorted[@]}
79
80 printf "{\n"
81 printf " \"exceptions\": {\n"
82 if [ ${numExceptions} -gt 0 ]; then
83 for (( i=0; i<${numExceptions}-1; i++ ));
84 do
85 printf " \"%s\":\"%s\",\n" "${sorted[$i]}" "${sorted[$i]}"
86 done
87 printf " \"%s\":\"%s\"\n" "${sorted[${numExceptions}-1]}" "${sorted[${numExceptions}-1]}"
88 fi
89 printf " },\n"
90 printf " \"total\":%s\n" "${numExceptions}"
91 printf "}\n"
92 }
93
94 # -------------------------------------------------------------------------------
95 # --- check PHP files recursively for missing and duplicate exception numbers ---
96 # -------------------------------------------------------------------------------
97 scan_exceptions() {
98 local foundNewFile=0
99 local oldFilename=""
100 local firstLineOfMatch=""
101 local foundExceptionInFile=1
102 local exceptionCodes=()
103
104 # grep
105 # '-r' recursive
106 # '--include '*.php'' in all .php files
107 # '-Pzoab' pcre regex, -zo remove all linebreaks for multiline match, treat all files as text, output position "filename:position: match", binary position
108 #
109 # (?:(?!Exception\()[\w\\])* negative lookahead. capture all alphanum and \ until we reach "Exception("
110 # eat "Exception("
111 # (?:(?!\);).|[\r\n])*\);[\r\n]+ negative lookahead again, eat everything including a \n until we reach the first ");", then line breaks
112
113 cd "$scanPath" || exit 1
114
115 grep \
116 -r \
117 --include '*.php' \
118 -Pzoab \
119 'new (?:(?!Exception\()[\w\\])*Exception\((?:(?!\);).|[\r\n])*\);[\r\n]+' \
120 | \
121 {
122 while read line;
123 do
124 possibleFilename=`echo ${line} | cut -d':' -f1`
125 if [[ ${possibleFilename} =~ .php$ ]]; then
126 # the matched line consists of a file name match, we're dealing with a new match here.
127 foundNewFile=1
128 oldFilename=${currentFilename}
129 currentFilename=${possibleFilename}
130 else
131 foundNewFile=0
132 fi
133
134 # skip file if in blacklist
135 if [[ {$ignoreFiles[@]} =~ ${currentFilename} ]]; then
136 continue
137 fi
138
139 # check for match in previous file name
140 if [[ ${foundNewFile} -eq 1 ]] && [[ ${foundExceptionInFile} -eq 0 ]]; then
141 if [ "$print" -ne "1" ]; then
142 # checking exception codes: exit
143 # listing exception codes: ignore
144 echo "File: $oldFilename"
145 echo "The created exception contains no 10 digit exception code as second argument, in or below this line:"
146 echo "$firstLineOfMatch"
147 exit 1
148 fi
149 fi
150
151 # reset found flag if we're handling new file
152 if [[ ${foundNewFile} -eq 1 ]]; then
153 foundExceptionInFile=0
154 firstLineOfMatch=${line}
155 fi
156
157 # see if the line consists of an exception code
158 if [[ "$line" =~ .*([0-9]{10}).* ]]; then
159 foundExceptionInFile=1
160 exceptionCode=${BASH_REMATCH[1]}
161 # check if that code was registered already
162 if [[ " ${exceptionCodes[@]} " =~ " ${exceptionCode} " ]]; then
163 if [ "$print" -ne "1" ]; then
164 # checking exception codes: exit
165 # listing exception codes: ignore
166 echo "Duplicate exception code ${exceptionCode} in file:"
167 echo ${currentFilename}
168 exit 1
169 fi
170 fi
171 exceptionCodes+=(${exceptionCode})
172 fi
173 done || exit 1
174
175 if [ "$print" -eq "1" ]; then
176 print_exceptions
177 fi
178
179 exit 0
180 }
181
182 exitCode=$?
183
184 cd - > /dev/null
185
186 exit $exitCode
187 }
188
189 scan_exceptions