vet.sh (6513B)
1 #!/bin/bash 2 3 set -ex # Exit on error; debugging enabled. 4 set -o pipefail # Fail a pipe if any sub-command fails. 5 6 # not makes sure the command passed to it does not exit with a return code of 0. 7 not() { 8 # This is required instead of the earlier (! $COMMAND) because subshells and 9 # pipefail don't work the same on Darwin as in Linux. 10 ! "$@" 11 } 12 13 die() { 14 echo "$@" >&2 15 exit 1 16 } 17 18 fail_on_output() { 19 tee /dev/stderr | not read 20 } 21 22 # Check to make sure it's safe to modify the user's git repo. 23 git status --porcelain | fail_on_output 24 25 # Undo any edits made by this script. 26 cleanup() { 27 git reset --hard HEAD 28 } 29 trap cleanup EXIT 30 31 PATH="${HOME}/go/bin:${GOROOT}/bin:${PATH}" 32 go version 33 34 if [[ "$1" = "-install" ]]; then 35 # Install the pinned versions as defined in module tools. 36 pushd ./test/tools 37 go install \ 38 golang.org/x/lint/golint \ 39 golang.org/x/tools/cmd/goimports \ 40 honnef.co/go/tools/cmd/staticcheck \ 41 github.com/client9/misspell/cmd/misspell 42 popd 43 if [[ -z "${VET_SKIP_PROTO}" ]]; then 44 if [[ "${GITHUB_ACTIONS}" = "true" ]]; then 45 PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files. 46 PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip 47 pushd /home/runner/go 48 wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} 49 unzip ${PROTOC_FILENAME} 50 bin/protoc --version 51 popd 52 elif not which protoc > /dev/null; then 53 die "Please install protoc into your path" 54 fi 55 fi 56 exit 0 57 elif [[ "$#" -ne 0 ]]; then 58 die "Unknown argument(s): $*" 59 fi 60 61 # - Check that generated proto files are up to date. 62 if [[ -z "${VET_SKIP_PROTO}" ]]; then 63 make proto && git status --porcelain 2>&1 | fail_on_output || \ 64 (git status; git --no-pager diff; exit 1) 65 fi 66 67 if [[ -n "${VET_ONLY_PROTO}" ]]; then 68 exit 0 69 fi 70 71 # - Ensure all source files contain a copyright message. 72 # (Done in two parts because Darwin "git grep" has broken support for compound 73 # exclusion matches.) 74 (grep -L "DO NOT EDIT" $(git grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)" -- '*.go') || true) | fail_on_output 75 76 # - Make sure all tests in grpc and grpc/test use leakcheck via Teardown. 77 not grep 'func Test[^(]' *_test.go 78 not grep 'func Test[^(]' test/*.go 79 80 # - Do not import x/net/context. 81 not git grep -l 'x/net/context' -- "*.go" 82 83 # - Do not import math/rand for real library code. Use internal/grpcrand for 84 # thread safety. 85 git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test' 86 87 # - Do not call grpclog directly. Use grpclog.Component instead. 88 git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' 89 90 # - Ensure all ptypes proto packages are renamed when importing. 91 not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" 92 93 # - Ensure all xds proto imports are renamed to *pb or *grpc. 94 git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "' 95 96 misspell -error . 97 98 # - gofmt, goimports, golint (with exceptions for generated code), go vet, 99 # go mod tidy. 100 # Perform these checks on each module inside gRPC. 101 for MOD_FILE in $(find . -name 'go.mod'); do 102 MOD_DIR=$(dirname ${MOD_FILE}) 103 pushd ${MOD_DIR} 104 go vet -all ./... | fail_on_output 105 gofmt -s -d -l . 2>&1 | fail_on_output 106 goimports -l . 2>&1 | not grep -vE "\.pb\.go" 107 golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:" 108 109 go mod tidy -compat=1.17 110 git status --porcelain 2>&1 | fail_on_output || \ 111 (git status; git --no-pager diff; exit 1) 112 popd 113 done 114 115 # - Collection of static analysis checks 116 # 117 # TODO(dfawley): don't use deprecated functions in examples or first-party 118 # plugins. 119 # TODO(dfawley): enable ST1019 (duplicate imports) but allow for protobufs. 120 SC_OUT="$(mktemp)" 121 staticcheck -go 1.19 -checks 'inherit,-ST1015,-ST1019,-SA1019' ./... > "${SC_OUT}" || true 122 # Error if anything other than deprecation warnings are printed. 123 not grep -v "is deprecated:.*SA1019" "${SC_OUT}" 124 # Only ignore the following deprecated types/fields/functions. 125 not grep -Fv '.CredsBundle 126 .HeaderMap 127 .Metadata is deprecated: use Attributes 128 .NewAddress 129 .NewServiceConfig 130 .Type is deprecated: use Attributes 131 BuildVersion is deprecated 132 balancer.ErrTransientFailure 133 balancer.Picker 134 extDesc.Filename is deprecated 135 github.com/golang/protobuf/jsonpb is deprecated 136 grpc.CallCustomCodec 137 grpc.Code 138 grpc.Compressor 139 grpc.CustomCodec 140 grpc.Decompressor 141 grpc.MaxMsgSize 142 grpc.MethodConfig 143 grpc.NewGZIPCompressor 144 grpc.NewGZIPDecompressor 145 grpc.RPCCompressor 146 grpc.RPCDecompressor 147 grpc.ServiceConfig 148 grpc.WithCompressor 149 grpc.WithDecompressor 150 grpc.WithDialer 151 grpc.WithMaxMsgSize 152 grpc.WithServiceConfig 153 grpc.WithTimeout 154 http.CloseNotifier 155 info.SecurityVersion 156 proto is deprecated 157 proto.InternalMessageInfo is deprecated 158 proto.EnumName is deprecated 159 proto.ErrInternalBadWireType is deprecated 160 proto.FileDescriptor is deprecated 161 proto.Marshaler is deprecated 162 proto.MessageType is deprecated 163 proto.RegisterEnum is deprecated 164 proto.RegisterFile is deprecated 165 proto.RegisterType is deprecated 166 proto.RegisterExtension is deprecated 167 proto.RegisteredExtension is deprecated 168 proto.RegisteredExtensions is deprecated 169 proto.RegisterMapType is deprecated 170 proto.Unmarshaler is deprecated 171 resolver.Backend 172 resolver.GRPCLB 173 Target is deprecated: Use the Target field in the BuildOptions instead. 174 xxx_messageInfo_ 175 ' "${SC_OUT}" 176 177 # - special golint on package comments. 178 lint_package_comment_per_package() { 179 # Number of files in this go package. 180 fileCount=$(go list -f '{{len .GoFiles}}' $1) 181 if [ ${fileCount} -eq 0 ]; then 182 return 0 183 fi 184 # Number of package errors generated by golint. 185 lintPackageCommentErrorsCount=$(golint --min_confidence 0 $1 | grep -c "should have a package comment") 186 # golint complains about every file that's missing the package comment. If the 187 # number of files for this package is greater than the number of errors, there's 188 # at least one file with package comment, good. Otherwise, fail. 189 if [ ${fileCount} -le ${lintPackageCommentErrorsCount} ]; then 190 echo "Package $1 (with ${fileCount} files) is missing package comment" 191 return 1 192 fi 193 } 194 lint_package_comment() { 195 set +ex 196 197 count=0 198 for i in $(go list ./...); do 199 lint_package_comment_per_package "$i" 200 ((count += $?)) 201 done 202 203 set -ex 204 return $count 205 } 206 lint_package_comment 207 208 echo SUCCESS