vet.sh 5.6 KB

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