...
1#!/bin/bash
2#
3# Presubmit checks for certificate-transparency-go.
4#
5# Checks for lint errors, spelling, licensing, correct builds / tests and so on.
6# Flags may be specified to allow suppressing of checks or automatic fixes, try
7# `scripts/presubmit.sh --help` for details.
8#
9# Globals:
10# GO_TEST_PARALLELISM: max processes to use for Go tests. Optional (defaults
11# to 10).
12# GO_TEST_TIMEOUT: timeout for 'go test'. Optional (defaults to 5m).
13set -eu
14
15check_pkg() {
16 local cmd="$1"
17 local pkg="$2"
18 check_cmd "$cmd" "try running 'go get -u $pkg'"
19}
20
21check_cmd() {
22 local cmd="$1"
23 local msg="$2"
24 if ! type -p "${cmd}" > /dev/null; then
25 echo "${cmd} not found, ${msg}"
26 return 1
27 fi
28}
29
30usage() {
31 echo "$0 [--coverage] [--fix] [--no-build] [--no-linters] [--no-generate]"
32}
33
34main() {
35 local coverage=0
36 local fix=0
37 local run_build=1
38 local run_lint=1
39 local run_generate=1
40 while [[ $# -gt 0 ]]; do
41 case "$1" in
42 --coverage)
43 coverage=1
44 ;;
45 --fix)
46 fix=1
47 ;;
48 --help)
49 usage
50 exit 0
51 ;;
52 --no-build)
53 run_build=0
54 ;;
55 --no-linters)
56 run_lint=0
57 ;;
58 --no-generate)
59 run_generate=0
60 ;;
61 *)
62 usage
63 exit 1
64 ;;
65 esac
66 shift 1
67 done
68
69 cd "$(dirname "$0")" # at scripts/
70 cd .. # at top level
71
72 go_srcs="$(find . -name '*.go' | \
73 grep -v vendor/ | \
74 grep -v mock_ | \
75 grep -v .pb.go | \
76 grep -v x509/ | \
77 grep -v asn1/ | \
78 tr '\n' ' ')"
79
80 # Prevent the creation of proto files with .txt extensions.
81 bad_protos="$(find . -name '*.pb.txt' -o -name '*.proto.txt' -print)"
82 if [[ "${bad_protos}" != "" ]]; then
83 echo "Text-based protos must use the .textproto extension:"
84 echo $bad_protos
85 exit 1
86 fi
87
88 if [[ "$fix" -eq 1 ]]; then
89 check_pkg goimports golang.org/x/tools/cmd/goimports || exit 1
90
91 echo 'running gofmt'
92 gofmt -s -w ${go_srcs}
93 echo 'running goimports'
94 goimports -w ${go_srcs}
95 fi
96
97 if [[ "${run_build}" -eq 1 ]]; then
98 echo 'running go build'
99 go build ./...
100
101 echo 'running go test'
102
103 # Individual package profiles are written to "$profile.out" files under
104 # /tmp/ct_profile.
105 # An aggregate profile is created at /tmp/coverage.txt.
106 mkdir -p /tmp/ct_profile
107 rm -f /tmp/ct_profile/*
108
109 for d in $(go list ./...); do
110 # Create a different -coverprofile for each test (if enabled)
111 local coverflags=
112 if [[ ${coverage} -eq 1 ]]; then
113 # Transform $d to a smaller, valid file name.
114 # For example:
115 # * github.com/google/certificate-transparency-go becomes c-t-go.out
116 # * github.com/google/certificate-transparency-go/cmd/createtree/keys becomes
117 # c-t-go-cmd-createtree-keys.out
118 local profile="${d}.out"
119 profile="${profile#github.com/*/}"
120 profile="${profile//\//-}"
121 profile="${profile/certificate-transparency-go/c-t-go}"
122 coverflags="-covermode=atomic -coverprofile='/tmp/ct_profile/${profile}'"
123 fi
124
125 # Do not run go test in the loop, instead echo it so we can use xargs to
126 # add some parallelism.
127 echo go test \
128 -short \
129 -timeout=${GO_TEST_TIMEOUT:-5m} \
130 ${coverflags} \
131 "$d"
132 done | xargs -I '{}' -P ${GO_TEST_PARALLELISM:-10} bash -c '{}' || exit 1
133
134 [[ ${coverage} -eq 1 ]] && \
135 cat /tmp/ct_profile/*.out > coverage.txt
136 fi
137
138 if [[ "${run_lint}" -eq 1 ]]; then
139 check_cmd golangci-lint \
140 'have you installed github.com/golangci/golangci-lint?' || exit 1
141
142 echo 'running golangci-lint'
143 golangci-lint run --deadline=5m
144 echo 'checking license headers'
145 ./scripts/check_license.sh ${go_srcs}
146 fi
147
148 if [[ "${run_generate}" -eq 1 ]]; then
149 check_cmd protoc 'have you installed protoc?'
150 check_pkg mockgen github.com/golang/mock/mockgen || exit 1
151
152 echo 'running go generate'
153 go generate -run="protoc" ./...
154 go generate -run="mockgen" ./...
155 fi
156}
157
158main "$@"
View as plain text