Skip to content

Commit dfdda47

Browse files
committed
script/genproto.sh: Refactor to be explicit about versions.
Refactoring script/genproto.sh around state-of-the-art techniques of managing tooling in go: - https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module - uses https://github.com/myitcv/gobin instead of customly created gopath.proto dir - caches tools between executions - guaratees hermetics runs (it was not guaranteed for protoc_grpc_gateway that used latest) The change is no-op for the generated code. The commit reveals a few 'worring things': 1 We depend on : github.com/grpc-ecosystem/grpc-gateway/@v/v1.4.1/protoc-gen-grpc-gateway 2. And also : github.com/grpc-ecosystem/grpc-gateway/@v/v1.15.0/protoc-gen-swagger/protoc-gen-swagger 3. And on extremely old: github.com/gogo/[email protected] protoc-gen-gofast that is out of sync with the library linked to binaries: github.com/gogo/[email protected]
1 parent 2c66612 commit dfdda47

File tree

6 files changed

+372
-90
lines changed

6 files changed

+372
-90
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ hack/tls-setup/certs
1919
/vendor
2020
/tests/e2e/default.proxy
2121
*.tmp
22-
2322
*.bak
23+
.gobincache/

scripts/genproto.sh

+50-89
Original file line numberDiff line numberDiff line change
@@ -10,65 +10,42 @@ if ! [[ "$0" =~ scripts/genproto.sh ]]; then
1010
exit 255
1111
fi
1212

13+
source ./scripts/test_lib.sh
14+
1315
if [[ $(protoc --version | cut -f2 -d' ') != "3.12.3" ]]; then
1416
echo "could not find protoc 3.12.3, is it installed + in PATH?"
1517
exit 255
1618
fi
1719

18-
# directories containing protos to be built
19-
DIRS="./wal/walpb ./api/etcdserverpb ./etcdserver/api/snap/snappb ./raft/raftpb ./api/mvccpb ./lease/leasepb ./api/authpb ./etcdserver/api/v3lock/v3lockpb ./etcdserver/api/v3election/v3electionpb ./api/membershippb"
20+
export GOMOD="./tools/mod"
21+
22+
run env GO111MODULE=off go get -u github.com/myitcv/gobin
2023

21-
# disable go mod - this is for the go get/install invocations
22-
export GO111MODULE=off
24+
GOFAST_BIN=$(tool_get_bin github.com/gogo/protobuf/protoc-gen-gofast)
25+
GRPC_GATEWAY_BIN=$(tool_get_bin github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway)
26+
SWAGGER_BIN=$(tool_get_bin github.com/grpc-ecosystem/grpc-gateway/[email protected])
27+
GOGOPROTO_ROOT="$(tool_pkg_dir github.com/gogo/protobuf/proto)/.."
28+
GRPC_GATEWAY_ROOT="$(tool_pkg_dir github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway)/.."
2329

24-
# exact version of packages to build
25-
GOGO_PROTO_SHA="1adfc126b41513cc696b209667c8656ea7aac67c"
26-
GRPC_GATEWAY_SHA="92583770e3f01b09a0d3e9bdf64321d8bebd48f2"
27-
SCHWAG_SHA="b7d0fc9aadaaae3d61aaadfc12e4a2f945514912"
30+
echo
31+
echo "Resolved binary and packages versions:"
32+
echo " - protoc-gen-gofast: ${GOFAST_BIN}"
33+
echo " - protoc-gen-grpc-gateway: ${GRPC_GATEWAY_BIN}"
34+
echo " - swagger: ${SWAGGER_BIN}"
35+
echo " - gogoproto-root: ${GOGOPROTO_ROOT}"
36+
echo " - grpc-gateway-root: ${GRPC_GATEWAY_ROOT}"
2837

29-
# set up self-contained GOPATH for building
30-
export GOPATH=${PWD}/gopath.proto
31-
export GOBIN=${PWD}/bin
32-
export PATH="${GOBIN}:${PATH}"
38+
# directories containing protos to be built
39+
DIRS="./wal/walpb ./api/etcdserverpb ./etcdserver/api/snap/snappb ./raft/raftpb ./api/mvccpb ./lease/leasepb ./api/authpb ./etcdserver/api/v3lock/v3lockpb ./etcdserver/api/v3election/v3electionpb ./api/membershippb"
3340

34-
ETCD_IO_ROOT="${GOPATH}/src/go.etcd.io"
35-
ETCD_ROOT="${ETCD_IO_ROOT}/etcd"
36-
GOGOPROTO_ROOT="${GOPATH}/src/github.com/gogo/protobuf"
37-
SCHWAG_ROOT="${GOPATH}/src/github.com/hexfusion/schwag"
3841
GOGOPROTO_PATH="${GOGOPROTO_ROOT}:${GOGOPROTO_ROOT}/protobuf"
39-
GRPC_GATEWAY_ROOT="${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway"
40-
41-
function cleanup {
42-
# Remove the whole fake GOPATH which can really confuse go mod.
43-
rm -rf "${PWD}/gopath.proto"
44-
}
45-
46-
cleanup
47-
trap cleanup EXIT
48-
49-
mkdir -p "${ETCD_IO_ROOT}"
50-
ln -s "${PWD}" "${ETCD_ROOT}"
51-
52-
# Ensure we have the right version of protoc-gen-gogo by building it every time.
53-
# TODO(jonboulle): vendor this instead of `go get`ting it.
54-
go get -u github.com/gogo/protobuf/{proto,protoc-gen-gogo,gogoproto}
55-
go get -u golang.org/x/tools/cmd/goimports
56-
pushd "${GOGOPROTO_ROOT}"
57-
git reset --hard "${GOGO_PROTO_SHA}"
58-
make install
59-
popd
60-
61-
# generate gateway code
62-
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
63-
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
64-
pushd "${GRPC_GATEWAY_ROOT}"
65-
git reset --hard "${GRPC_GATEWAY_SHA}"
66-
go install ./protoc-gen-grpc-gateway
67-
popd
42+
43+
log_callout -e "\nRunning gofast proto generation..."
6844

6945
for dir in ${DIRS}; do
70-
pushd "${dir}"
71-
protoc --gofast_out=plugins=grpc,import_prefix=go.etcd.io/:. -I=".:${GOGOPROTO_PATH}:${ETCD_IO_ROOT}:${GRPC_GATEWAY_ROOT}/third_party/googleapis" ./*.proto
46+
run pushd "${dir}"
47+
run protoc --gofast_out=plugins=grpc,import_prefix=go.etcd.io/:. -I=".:${GOGOPROTO_PATH}:${ETCD_ROOT_DIR}/..:${GRPC_GATEWAY_ROOT}/third_party/googleapis" \
48+
--plugin="${GOFAST_BIN}" ./*.proto
7249
# shellcheck disable=SC1117
7350
sed -i.bak -E 's/go\.etcd\.io\/(gogoproto|github\.com|golang\.org|google\.golang\.org)/\1/g' ./*.pb.go
7451
# shellcheck disable=SC1117
@@ -86,30 +63,30 @@ for dir in ${DIRS}; do
8663
# shellcheck disable=SC1117
8764
sed -i.bak -E "s|go.etcd.io/etcd/v3/api|go.etcd.io/etcd/api/v3|g" ./*.pb.go
8865
rm -f ./*.bak
89-
gofmt -s -w ./*.pb.go
90-
goimports -w ./*.pb.go
91-
popd
66+
run gofmt -s -w ./*.pb.go
67+
run goimports -w ./*.pb.go
68+
run popd
9269
done
9370

71+
log_callout -e "\nRunning swagger & grpc_gateway proto generation..."
72+
9473
# remove old swagger files so it's obvious whether the files fail to generate
9574
rm -rf Documentation/dev-guide/apispec/swagger/*json
9675
for pb in api/etcdserverpb/rpc etcdserver/api/v3lock/v3lockpb/v3lock etcdserver/api/v3election/v3electionpb/v3election; do
9776
protobase="${pb}"
98-
protoc -I. \
77+
run protoc -I. \
9978
-I"${GRPC_GATEWAY_ROOT}"/third_party/googleapis \
10079
-I"${GOGOPROTO_PATH}" \
101-
-I"${ETCD_IO_ROOT}" \
80+
-I"${ETCD_ROOT_DIR}/.." \
10281
--grpc-gateway_out=logtostderr=true:. \
10382
--swagger_out=logtostderr=true:./Documentation/dev-guide/apispec/swagger/. \
83+
--plugin="${SWAGGER_BIN}" --plugin="${GRPC_GATEWAY_BIN}" \
10484
${protobase}.proto
10585
# hack to move gw files around so client won't include them
10686
pkgpath=$(dirname "${protobase}")
10787
pkg=$(basename "${pkgpath}")
10888
gwfile="${protobase}.pb.gw.go"
10989

110-
echo ">>> $gwfile"
111-
head -n 30 "$gwfile"
112-
11390
sed -i.bak -E "s/package $pkg/package gw/g" ${gwfile}
11491
# shellcheck disable=SC1117
11592
sed -i.bak -E "s/protoReq /&$pkg\./g" ${gwfile}
@@ -125,52 +102,36 @@ for pb in api/etcdserverpb/rpc etcdserver/api/v3lock/v3lockpb/v3lock etcdserver/
125102
# shellcheck disable=SC1117
126103
sed -i.bak -E "s|go.etcd.io/etcd/v3/api|go.etcd.io/etcd/api/v3|g" ${gwfile}
127104
mkdir -p "${pkgpath}"/gw/
128-
go fmt ${gwfile}
105+
run go fmt ${gwfile}
129106
mv ${gwfile} "${pkgpath}/gw/"
130107
rm -f ./${protobase}*.bak
131108
swaggerName=$(basename ${protobase})
132-
mv Documentation/dev-guide/apispec/swagger/${protobase}.swagger.json \
109+
run mv Documentation/dev-guide/apispec/swagger/${protobase}.swagger.json \
133110
Documentation/dev-guide/apispec/swagger/"${swaggerName}".swagger.json
134111
done
135-
rm -rf Documentation/dev-guide/apispec/swagger/etcdserver/
136-
137-
# append security to swagger spec
138-
go get -u "github.com/hexfusion/schwag"
139-
pushd "${SCHWAG_ROOT}"
140-
git reset --hard "${SCHWAG_SHA}"
141-
go install .
142-
popd
143-
schwag -input=Documentation/dev-guide/apispec/swagger/rpc.swagger.json
144-
145-
# install protodoc
146-
# go get -v -u go.etcd.io/protodoc
147-
#
148-
# run './scripts/genproto.sh --skip-protodoc'
149-
# to skip protodoc generation
150-
#
112+
113+
log_callout -e "\nRunning swagger ..."
114+
run_go_tool github.com/hexfusion/schwag -input=Documentation/dev-guide/apispec/swagger/rpc.swagger.json
115+
151116
if [ "$1" != "--skip-protodoc" ]; then
152-
echo "protodoc is auto-generating grpc API reference documentation..."
153-
go get -v -u go.etcd.io/protodoc
154-
SHA_PROTODOC="484ab544e116302a9a6021cc7c427d334132e94a"
155-
PROTODOC_PATH="${GOPATH}/src/go.etcd.io/protodoc"
156-
pushd "${PROTODOC_PATH}"
157-
git reset --hard "${SHA_PROTODOC}"
158-
go install
159-
echo "protodoc is updated"
160-
popd
161-
162-
protodoc --directories="api/etcdserverpb=service_message,api/mvccpb=service_message,lease/leasepb=service_message,api/authpb=service_message" \
117+
log_callout "protodoc is auto-generating grpc API reference documentation..."
118+
119+
run rm -rf Documentation/dev-guide/api_reference_v3.md
120+
run_go_tool go.etcd.io/protodoc --directories="api/etcdserverpb=service_message,api/mvccpb=service_message,lease/leasepb=service_message,api/authpb=service_message" \
163121
--title="etcd API Reference" \
164122
--output="Documentation/dev-guide/api_reference_v3.md" \
165123
--message-only-from-this-file="api/etcdserverpb/rpc.proto" \
166-
--disclaimer="This is a generated documentation. Please read the proto files for more."
124+
--disclaimer="This is a generated documentation. Please read the proto files for more." || exit 2
167125

168-
protodoc --directories="etcdserver/api/v3lock/v3lockpb=service_message,etcdserver/api/v3election/v3electionpb=service_message,api/mvccpb=service_message" \
126+
run rm -rf Documentation/dev-guide/api_concurrency_reference_v3.md
127+
run_go_tool go.etcd.io/protodoc --directories="etcdserver/api/v3lock/v3lockpb=service_message,etcdserver/api/v3election/v3electionpb=service_message,api/mvccpb=service_message" \
169128
--title="etcd concurrency API Reference" \
170129
--output="Documentation/dev-guide/api_concurrency_reference_v3.md" \
171-
--disclaimer="This is a generated documentation. Please read the proto files for more."
130+
--disclaimer="This is a generated documentation. Please read the proto files for more." || exit 2
172131

173-
echo "protodoc is finished..."
132+
log_success "protodoc is finished."
174133
else
175-
echo "skipping grpc API reference document auto-generation..."
134+
log_warning "skipping grpc API reference document auto-generation..."
176135
fi
136+
137+
log_success -e "\n./genproto SUCCESS"

scripts/test_lib.sh

+31
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ function go_test {
191191
# tool_exists [tool] [instruction]
192192
# Checks whether given [tool] is installed. In case of failure,
193193
# prints a warning with installation [instruction] and returns !=0 code.
194+
#
195+
# WARNING: This depend on "any" version of the 'binary' that might be tricky
196+
# from hermetic build perspective. For go binaries prefer 'tool_go_run'
194197
function tool_exists {
195198
local tool="${1}"
196199
local instruction="${2}"
@@ -200,3 +203,31 @@ function tool_exists {
200203
fi
201204
}
202205

206+
# tool_get_bin [tool] - returns absolute path to a tool binary (or returns error)
207+
function tool_get_bin {
208+
tool_exists "gobin" "GO111MODULE=off go get -u github.com/myitcv/gobin" || return 2
209+
210+
local tool="$1"
211+
if [[ "$tool" == *"@"* ]]; then
212+
run gobin -p "${tool}" || return 2
213+
else
214+
run_for_module ./tools/mod run gobin -p -m --mod=readonly "${tool}" || return 2
215+
fi
216+
}
217+
218+
# tool_pkg_dir [pkg] - returns absolute path to a directory that stores given pkg.
219+
# The pkg versions must be defined in ./tools/mod directory.
220+
function tool_pkg_dir {
221+
run_for_module ./tools/mod run go list -f '{{.Dir}}' "${1}"
222+
}
223+
224+
# tool_get_bin [tool]
225+
function run_go_tool {
226+
local cmdbin
227+
if ! cmdbin=$(tool_get_bin "${1}"); then
228+
return 2
229+
fi
230+
shift 1
231+
run "${cmdbin}" "$@" || return 2
232+
}
233+

tools/mod/go.mod

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module go.etcd.io/etcd/tools/v3
2+
3+
go 1.15
4+
5+
require (
6+
github.com/ghodss/yaml v1.0.0 // indirect
7+
github.com/go-openapi/loads v0.19.5 // indirect
8+
github.com/go-openapi/spec v0.19.9 // indirect
9+
github.com/gogo/protobuf v1.0.0
10+
github.com/grpc-ecosystem/grpc-gateway v1.4.1
11+
github.com/hexfusion/schwag v0.0.0-20170606222847-b7d0fc9aadaa
12+
go.etcd.io/protodoc v0.0.0-20180829002748-484ab544e116
13+
google.golang.org/genproto v0.0.0-20201008135153-289734e2e40c // indirect
14+
gopkg.in/yaml.v2 v2.3.0 // indirect
15+
)

0 commit comments

Comments
 (0)