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