blob: a8e4732b3d20456af925a37feeaf020becdc0ca1 [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
Akash Kankanala761955c2024-02-21 19:32:20 +053044 if [[ "${GITHUB_ACTIONS}" = "true" ]]; then
45 PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files.
khenaidoo5fc5cea2021-08-11 17:39:16 -040046 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
57elif [[ "$#" -ne 0 ]]; then
58 die "Unknown argument(s): $*"
59fi
60
Akash Kankanala761955c2024-02-21 19:32:20 +053061# - Check that generated proto files are up to date.
62if [[ -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)
65fi
66
67if [[ -n "${VET_ONLY_PROTO}" ]]; then
68 exit 0
69fi
70
khenaidoo5fc5cea2021-08-11 17:39:16 -040071# - Ensure all source files contain a copyright message.
Akash Kankanala761955c2024-02-21 19:32:20 +053072# (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
khenaidoo5fc5cea2021-08-11 17:39:16 -040075
76# - Make sure all tests in grpc and grpc/test use leakcheck via Teardown.
77not grep 'func Test[^(]' *_test.go
78not grep 'func Test[^(]' test/*.go
79
80# - Do not import x/net/context.
81not 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.
85git 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.
Akash Kankanala761955c2024-02-21 19:32:20 +053088git 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'
khenaidoo5fc5cea2021-08-11 17:39:16 -040089
90# - Ensure all ptypes proto packages are renamed when importing.
91not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go"
92
93# - Ensure all xds proto imports are renamed to *pb or *grpc.
94git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "'
95
96misspell -error .
97
khenaidoo5fc5cea2021-08-11 17:39:16 -040098# - gofmt, goimports, golint (with exceptions for generated code), go vet,
99# go mod tidy.
100# Perform these checks on each module inside gRPC.
101for 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"
Akash Kankanala761955c2024-02-21 19:32:20 +0530107 golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:"
khenaidoo5fc5cea2021-08-11 17:39:16 -0400108
Akash Kankanala761955c2024-02-21 19:32:20 +0530109 go mod tidy -compat=1.17
khenaidoo5fc5cea2021-08-11 17:39:16 -0400110 git status --porcelain 2>&1 | fail_on_output || \
111 (git status; git --no-pager diff; exit 1)
112 popd
113done
114
115# - Collection of static analysis checks
116#
117# TODO(dfawley): don't use deprecated functions in examples or first-party
118# plugins.
Akash Kankanala761955c2024-02-21 19:32:20 +0530119# TODO(dfawley): enable ST1019 (duplicate imports) but allow for protobufs.
khenaidoo5fc5cea2021-08-11 17:39:16 -0400120SC_OUT="$(mktemp)"
Akash Kankanala761955c2024-02-21 19:32:20 +0530121staticcheck -go 1.19 -checks 'inherit,-ST1015,-ST1019,-SA1019' ./... > "${SC_OUT}" || true
khenaidoo5fc5cea2021-08-11 17:39:16 -0400122# Error if anything other than deprecation warnings are printed.
123not grep -v "is deprecated:.*SA1019" "${SC_OUT}"
124# Only ignore the following deprecated types/fields/functions.
125not grep -Fv '.CredsBundle
126.HeaderMap
127.Metadata is deprecated: use Attributes
128.NewAddress
129.NewServiceConfig
130.Type is deprecated: use Attributes
131BuildVersion is deprecated
132balancer.ErrTransientFailure
133balancer.Picker
134extDesc.Filename is deprecated
135github.com/golang/protobuf/jsonpb is deprecated
136grpc.CallCustomCodec
137grpc.Code
138grpc.Compressor
139grpc.CustomCodec
140grpc.Decompressor
141grpc.MaxMsgSize
142grpc.MethodConfig
143grpc.NewGZIPCompressor
144grpc.NewGZIPDecompressor
145grpc.RPCCompressor
146grpc.RPCDecompressor
147grpc.ServiceConfig
khenaidoo5fc5cea2021-08-11 17:39:16 -0400148grpc.WithCompressor
149grpc.WithDecompressor
150grpc.WithDialer
151grpc.WithMaxMsgSize
152grpc.WithServiceConfig
153grpc.WithTimeout
154http.CloseNotifier
155info.SecurityVersion
156proto is deprecated
157proto.InternalMessageInfo is deprecated
158proto.EnumName is deprecated
159proto.ErrInternalBadWireType is deprecated
160proto.FileDescriptor is deprecated
161proto.Marshaler is deprecated
162proto.MessageType is deprecated
163proto.RegisterEnum is deprecated
164proto.RegisterFile is deprecated
165proto.RegisterType is deprecated
166proto.RegisterExtension is deprecated
167proto.RegisteredExtension is deprecated
168proto.RegisteredExtensions is deprecated
169proto.RegisterMapType is deprecated
170proto.Unmarshaler is deprecated
171resolver.Backend
172resolver.GRPCLB
173Target is deprecated: Use the Target field in the BuildOptions instead.
174xxx_messageInfo_
175' "${SC_OUT}"
176
177# - special golint on package comments.
178lint_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}
194lint_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}
206lint_package_comment
207
208echo SUCCESS