vet.sh 6.6 KB

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