1#!/usr/bin/env bash 2# Copyright 2021 Google LLC 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# Find code files. 17CODE_FILES=() 18while IFS= read -r -d $'\0'; do 19 CODE_FILES+=("$REPLY") 20done < <(find . -not \( -path '*/target' -prune \) -and -name '*.rs' -print0) 21 22# Find markdown files. 23MD_FILES=() 24while IFS= read -r -d $'\0'; do 25 MD_FILES+=("$REPLY") 26done < <(find . -not \( -path '*/target' -prune \) -and -not \( -path '*/wycheproof' -prune \) -and -name '*.md' -print0) 27 28# Check that source files have the Apache License header. 29# Automatically skips generated files. 30check_license() { 31 local path="$1" 32 33 if head -1 "$path" | grep -iq -e 'generated' -e '::prost::message'; then 34 return 0 35 fi 36 37 if echo "$path" | grep -q "/proto/"; then 38 return 0 39 fi 40 41 # Look for "Apache License" on the file header 42 if ! head -10 "$path" | grep -q 'Apache License'; then 43 # Format: $path:$line:$message 44 echo "$path:1:license header not found" 45 return 1 46 fi 47 return 0 48} 49 50# Check that any TODO markers in files have associated issue numbers 51check_todo() { 52 local path="$1" 53 local result 54 result=$(grep --with-filename --line-number TODO "$path" | grep --invert-match --regexp='TODO(#[0-9][0-9]*)') 55 if [[ -n $result ]]; then 56 echo "TODO marker without issue number:" 57 echo "$result" 58 return 1 59 fi 60 return 0 61} 62 63# Check that any calls that might panic have a comment noting why they're safe 64check_panic() { 65 local path="$1" 66 if [[ $path =~ "test" || $path =~ "examples/" || $path =~ "rinkey/" || $path =~ "benches/" ]]; then 67 return 0 68 fi 69 for needle in "panic!(" "unwrap(" "expect(" "unwrap_err(" "expect_err(" "unwrap_none(" "expect_none(" "unreachable!"; do 70 local result 71 result=$(grep --with-filename --line-number "$needle" "$path" | grep --invert-match --regexp='safe:'| grep --invert-match --regexp=':[0-9]*://') 72 if [[ -n $result ]]; then 73 echo "Un-annotated panic code:" 74 echo "$result" 75 return 1 76 fi 77 done 78 return 0 79} 80 81errcount=0 82for f in "${CODE_FILES[@]}"; do 83 check_license "$f" 84 errcount=$((errcount + $?)) 85 check_todo "$f" 86 errcount=$((errcount + $?)) 87 check_panic "$f" 88 errcount=$((errcount + $?)) 89done 90 91EMBEDMD="$(go env GOPATH)/bin/embedmd" 92if [[ ! -x "$EMBEDMD" ]]; then 93 go install github.com/campoy/embedmd@97c13d6 94fi 95for f in "${MD_FILES[@]}"; do 96 "$EMBEDMD" -d "$f" 97 errcount=$((errcount + $?)) 98 check_todo "$f" 99 errcount=$((errcount + $?)) 100 mdl "$f" 101 errcount=$((errcount + $?)) 102done 103 104if [ $errcount -gt 0 ]; then 105 echo "$errcount errors detected" 106 exit 1 107fi 108