vet.sh 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. # Check for module support
  28. if go help mod >& /dev/null; then
  29. # Install the pinned versions as defined in module tools.
  30. pushd ./test/tools
  31. go install \
  32. golang.org/x/lint/golint \
  33. golang.org/x/tools/cmd/goimports \
  34. honnef.co/go/tools/cmd/staticcheck \
  35. github.com/client9/misspell/cmd/misspell
  36. popd
  37. else
  38. # Ye olde `go get` incantation.
  39. # Note: this gets the latest version of all tools (vs. the pinned versions
  40. # with Go modules).
  41. go get -u \
  42. golang.org/x/lint/golint \
  43. golang.org/x/tools/cmd/goimports \
  44. honnef.co/go/tools/cmd/staticcheck \
  45. github.com/client9/misspell/cmd/misspell
  46. fi
  47. if [[ -z "${VET_SKIP_PROTO}" ]]; then
  48. if [[ "${TRAVIS}" = "true" ]]; then
  49. PROTOBUF_VERSION=3.14.0
  50. PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
  51. pushd /home/travis
  52. wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
  53. unzip ${PROTOC_FILENAME}
  54. bin/protoc --version
  55. popd
  56. elif [[ "${GITHUB_ACTIONS}" = "true" ]]; then
  57. PROTOBUF_VERSION=3.14.0
  58. PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
  59. pushd /home/runner/go
  60. wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
  61. unzip ${PROTOC_FILENAME}
  62. bin/protoc --version
  63. popd
  64. elif not which protoc > /dev/null; then
  65. die "Please install protoc into your path"
  66. fi
  67. fi
  68. exit 0
  69. elif [[ "$#" -ne 0 ]]; then
  70. die "Unknown argument(s): $*"
  71. fi
  72. # - Ensure all source files contain a copyright message.
  73. not git grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)\|DO NOT EDIT" -- '*.go'
  74. # - Make sure all tests in grpc and grpc/test use leakcheck via Teardown.
  75. not grep 'func Test[^(]' *_test.go
  76. not grep 'func Test[^(]' test/*.go
  77. # - Do not import x/net/context.
  78. not git grep -l 'x/net/context' -- "*.go"
  79. # - Do not import math/rand for real library code. Use internal/grpcrand for
  80. # thread safety.
  81. git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test'
  82. # - Do not call grpclog directly. Use grpclog.Component instead.
  83. git grep -l 'grpclog.I\|grpclog.W\|grpclog.E\|grpclog.F\|grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go'
  84. # - Ensure all ptypes proto packages are renamed when importing.
  85. not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go"
  86. # - Ensure all xds proto imports are renamed to *pb or *grpc.
  87. git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "'
  88. # - Check imports that are illegal in appengine (until Go 1.11).
  89. # TODO: Remove when we drop Go 1.10 support
  90. go list -f {{.Dir}} ./... | xargs go run test/go_vet/vet.go
  91. # - gofmt, goimports, golint (with exceptions for generated code), go vet.
  92. gofmt -s -d -l . 2>&1 | fail_on_output
  93. goimports -l . 2>&1 | not grep -vE "\.pb\.go"
  94. golint ./... 2>&1 | not grep -vE "/testv3\.pb\.go:"
  95. go vet -all ./...
  96. misspell -error .
  97. # - Check that generated proto files are up to date.
  98. if [[ -z "${VET_SKIP_PROTO}" ]]; then
  99. PATH="/home/travis/bin:${PATH}" make proto && \
  100. git status --porcelain 2>&1 | fail_on_output || \
  101. (git status; git --no-pager diff; exit 1)
  102. fi
  103. # - Check that our modules are tidy.
  104. if go help mod >& /dev/null; then
  105. find . -name 'go.mod' | xargs -IXXX bash -c 'cd $(dirname XXX); go mod tidy'
  106. git status --porcelain 2>&1 | fail_on_output || \
  107. (git status; git --no-pager diff; exit 1)
  108. fi
  109. # - Collection of static analysis checks
  110. #
  111. # TODO(dfawley): don't use deprecated functions in examples or first-party
  112. # plugins.
  113. SC_OUT="$(mktemp)"
  114. staticcheck -go 1.9 -checks 'inherit,-ST1015' ./... > "${SC_OUT}" || true
  115. # Error if anything other than deprecation warnings are printed.
  116. not grep -v "is deprecated:.*SA1019" "${SC_OUT}"
  117. # Only ignore the following deprecated types/fields/functions.
  118. not grep -Fv '.CredsBundle
  119. .HeaderMap
  120. .Metadata is deprecated: use Attributes
  121. .NewAddress
  122. .NewServiceConfig
  123. .Type is deprecated: use Attributes
  124. BuildVersion is deprecated
  125. balancer.ErrTransientFailure
  126. balancer.Picker
  127. extDesc.Filename is deprecated
  128. github.com/golang/protobuf/jsonpb is deprecated
  129. grpc.CallCustomCodec
  130. grpc.Code
  131. grpc.Compressor
  132. grpc.CustomCodec
  133. grpc.Decompressor
  134. grpc.MaxMsgSize
  135. grpc.MethodConfig
  136. grpc.NewGZIPCompressor
  137. grpc.NewGZIPDecompressor
  138. grpc.RPCCompressor
  139. grpc.RPCDecompressor
  140. grpc.ServiceConfig
  141. grpc.WithBalancerName
  142. grpc.WithCompressor
  143. grpc.WithDecompressor
  144. grpc.WithDialer
  145. grpc.WithMaxMsgSize
  146. grpc.WithServiceConfig
  147. grpc.WithTimeout
  148. http.CloseNotifier
  149. info.SecurityVersion
  150. proto is deprecated
  151. proto.InternalMessageInfo is deprecated
  152. proto.EnumName is deprecated
  153. proto.ErrInternalBadWireType is deprecated
  154. proto.FileDescriptor is deprecated
  155. proto.Marshaler is deprecated
  156. proto.MessageType is deprecated
  157. proto.RegisterEnum is deprecated
  158. proto.RegisterFile is deprecated
  159. proto.RegisterType is deprecated
  160. proto.RegisterExtension is deprecated
  161. proto.RegisteredExtension is deprecated
  162. proto.RegisteredExtensions is deprecated
  163. proto.RegisterMapType is deprecated
  164. proto.Unmarshaler is deprecated
  165. resolver.Backend
  166. resolver.GRPCLB
  167. Target is deprecated: Use the Target field in the BuildOptions instead.
  168. xxx_messageInfo_
  169. ' "${SC_OUT}"
  170. # - special golint on package comments.
  171. lint_package_comment_per_package() {
  172. # Number of files in this go package.
  173. fileCount=$(go list -f '{{len .GoFiles}}' $1)
  174. if [ ${fileCount} -eq 0 ]; then
  175. return 0
  176. fi
  177. # Number of package errors generated by golint.
  178. lintPackageCommentErrorsCount=$(golint --min_confidence 0 $1 | grep -c "should have a package comment")
  179. # golint complains about every file that's missing the package comment. If the
  180. # number of files for this package is greater than the number of errors, there's
  181. # at least one file with package comment, good. Otherwise, fail.
  182. if [ ${fileCount} -le ${lintPackageCommentErrorsCount} ]; then
  183. echo "Package $1 (with ${fileCount} files) is missing package comment"
  184. return 1
  185. fi
  186. }
  187. lint_package_comment() {
  188. set +ex
  189. count=0
  190. for i in $(go list ./...); do
  191. lint_package_comment_per_package "$i"
  192. ((count += $?))
  193. done
  194. set -ex
  195. return $count
  196. }
  197. lint_package_comment
  198. echo SUCCESS