1#!/usr/bin/env bash 2 3readonly BASEDIR=$(readlink -f $(dirname $0))/.. 4cd $BASEDIR 5 6# exit on errors 7set -e 8 9rc=0 10 11echo -n "Checking file permissions..." 12 13while read -r perm _res0 _res1 path; do 14 if [ ! -f "$path" ]; then 15 continue 16 fi 17 18 fname=$(basename -- "$path") 19 20 case ${fname##*.} in 21 c|h|cpp|cc|cxx|hh|hpp|md|html|js|json|svg|Doxyfile|yml|LICENSE|README|conf|in|Makefile|mk|gitignore|go|txt) 22 # These file types should never be executable 23 if [ "$perm" -eq 100755 ]; then 24 echo "ERROR: $path is marked executable but is a code file." 25 rc=1 26 fi 27 ;; 28 *) 29 shebang=$(head -n 1 $path | cut -c1-3) 30 31 # git only tracks the execute bit, so will only ever return 755 or 644 as the permission. 32 if [ "$perm" -eq 100755 ]; then 33 # If the file has execute permission, it should start with a shebang. 34 if [ "$shebang" != "#!/" ]; then 35 echo "ERROR: $path is marked executable but does not start with a shebang." 36 rc=1 37 fi 38 else 39 # If the file doesnot have execute permissions, it should not start with a shebang. 40 if [ "$shebang" = "#!/" ]; then 41 echo "ERROR: $path is not marked executable but starts with a shebang." 42 rc=1 43 fi 44 fi 45 ;; 46 esac 47 48done <<< "$(git grep -I --name-only --untracked -e . | git ls-files -s)" 49 50if [ $rc -eq 0 ]; then 51 echo " OK" 52fi 53 54if hash astyle; then 55 echo -n "Checking coding style..." 56 if [ "$(astyle -V)" \< "Artistic Style Version 3" ] 57 then 58 echo -n " Your astyle version is too old. This may cause failure on patch verification performed by CI. Please update astyle to at least 3.0.1 version..." 59 fi 60 rm -f astyle.log 61 touch astyle.log 62 # Exclude rte_vhost code imported from DPDK - we want to keep the original code 63 # as-is to enable ongoing work to synch with a generic upstream DPDK vhost library, 64 # rather than making diffs more complicated by a lot of changes to follow SPDK 65 # coding standards. 66 git ls-files '*.[ch]' '*.cpp' '*.cc' '*.cxx' '*.hh' '*.hpp' | \ 67 grep -v rte_vhost | grep -v cpp_headers | \ 68 xargs astyle --options=.astylerc >> astyle.log 69 if grep -q "^Formatted" astyle.log; then 70 echo " errors detected" 71 git diff 72 sed -i -e 's/ / /g' astyle.log 73 grep --color=auto "^Formatted.*" astyle.log 74 echo "Incorrect code style detected in one or more files." 75 echo "The files have been automatically formatted." 76 echo "Remember to add the files to your commit." 77 rc=1 78 else 79 echo " OK" 80 fi 81 rm -f astyle.log 82else 83 echo "You do not have astyle installed so your code style is not being checked!" 84fi 85 86echo -n "Checking comment style..." 87 88git grep --line-number -e '/[*][^ *-]' -- '*.[ch]' > comment.log || true 89git grep --line-number -e '[^ ][*]/' -- '*.[ch]' ':!lib/vhost/rte_vhost*/*' >> comment.log || true 90git grep --line-number -e '^[*]' -- '*.[ch]' >> comment.log || true 91 92if [ -s comment.log ]; then 93 echo " Incorrect comment formatting detected" 94 cat comment.log 95 rc=1 96else 97 echo " OK" 98fi 99rm -f comment.log 100 101echo -n "Checking for spaces before tabs..." 102git grep --line-number $' \t' -- > whitespace.log || true 103if [ -s whitespace.log ]; then 104 echo " Spaces before tabs detected" 105 cat whitespace.log 106 rc=1 107else 108 echo " OK" 109fi 110rm -f whitespace.log 111 112echo -n "Checking trailing whitespace in output strings..." 113 114git grep --line-number -e ' \\n"' -- '*.[ch]' > whitespace.log || true 115 116if [ -s whitespace.log ]; then 117 echo " Incorrect trailing whitespace detected" 118 cat whitespace.log 119 rc=1 120else 121 echo " OK" 122fi 123rm -f whitespace.log 124 125echo -n "Checking for use of forbidden library functions..." 126 127git grep --line-number -w '\(strncpy\|strcpy\|strcat\|sprintf\|vsprintf\)' -- './*.c' ':!lib/vhost/rte_vhost*/**' > badfunc.log || true 128if [ -s badfunc.log ]; then 129 echo " Forbidden library functions detected" 130 cat badfunc.log 131 rc=1 132else 133 echo " OK" 134fi 135rm -f badfunc.log 136 137echo -n "Checking for use of forbidden CUnit macros..." 138 139git grep --line-number -w 'CU_ASSERT_FATAL' -- 'test/*' ':!test/spdk_cunit.h' > badcunit.log || true 140if [ -s badcunit.log ]; then 141 echo " Forbidden CU_ASSERT_FATAL usage detected - use SPDK_CU_ASSERT_FATAL instead" 142 cat badcunit.log 143 rc=1 144else 145 echo " OK" 146fi 147rm -f badcunit.log 148 149echo -n "Checking blank lines at end of file..." 150 151if ! git grep -I -l -e . -z | \ 152 xargs -0 -P8 -n1 scripts/eofnl > eofnl.log; then 153 echo " Incorrect end-of-file formatting detected" 154 cat eofnl.log 155 rc=1 156else 157 echo " OK" 158fi 159rm -f eofnl.log 160 161echo -n "Checking for POSIX includes..." 162git grep -I -i -f scripts/posix.txt -- './*' ':!include/spdk/stdinc.h' ':!include/linux/**' ':!lib/vhost/rte_vhost*/**' ':!scripts/posix.txt' > scripts/posix.log || true 163if [ -s scripts/posix.log ]; then 164 echo "POSIX includes detected. Please include spdk/stdinc.h instead." 165 cat scripts/posix.log 166 rc=1 167else 168 echo " OK" 169fi 170rm -f scripts/posix.log 171 172if hash pycodestyle 2>/dev/null; then 173 PEP8=pycodestyle 174elif hash pep8 2>/dev/null; then 175 PEP8=pep8 176fi 177 178if [ ! -z ${PEP8} ]; then 179 echo -n "Checking Python style..." 180 181 PEP8_ARGS+=" --max-line-length=140" 182 183 error=0 184 git ls-files '*.py' | xargs -n1 $PEP8 $PEP8_ARGS > pep8.log || error=1 185 if [ $error -ne 0 ]; then 186 echo " Python formatting errors detected" 187 cat pep8.log 188 rc=1 189 else 190 echo " OK" 191 fi 192 rm -f pep8.log 193else 194 echo "You do not have pycodestyle or pep8 installed so your Python style is not being checked!" 195fi 196 197# Check if any of the public interfaces were modified by this patch. 198# Warn the user to consider updating the changelog any changes 199# are detected. 200echo -n "Checking whether CHANGELOG.md should be updated..." 201staged=$(git diff --name-only --cached .) 202working=$(git status -s --porcelain | grep -iv "??" | awk '{print $2}') 203files="$staged $working" 204if [[ "$files" = " " ]]; then 205 files=$(git diff-tree --no-commit-id --name-only -r HEAD) 206fi 207 208has_changelog=0 209for f in $files; do 210 if [[ $f == CHANGELOG.md ]]; then 211 # The user has a changelog entry, so exit. 212 has_changelog=1 213 break 214 fi 215done 216 217needs_changelog=0 218if [ $has_changelog -eq 0 ]; then 219 for f in $files; do 220 if [[ $f == include/spdk/* ]] || [[ $f == scripts/rpc.py ]] || [[ $f == etc/* ]]; then 221 echo "" 222 echo -n "$f was modified. Consider updating CHANGELOG.md." 223 needs_changelog=1 224 fi 225 done 226fi 227 228if [ $needs_changelog -eq 0 ]; then 229 echo " OK" 230else 231 echo "" 232fi 233 234exit $rc 235