-
Notifications
You must be signed in to change notification settings - Fork 5.9k
/
Copy pathgenerate-proto.sh
executable file
·168 lines (146 loc) · 7.18 KB
/
generate-proto.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#! /usr/bin/env bash
# This script auto-generates protobuf related files. It is intended to be run manually when either
# API types are added/modified, or server gRPC calls are added. The generated files should then
# be checked into source control.
set -x
set -o errexit
set -o nounset
set -o pipefail
# shellcheck disable=SC2128
PROJECT_ROOT=$(
cd "$(dirname "${BASH_SOURCE}")"/..
pwd
)
PATH="${PROJECT_ROOT}/dist:${PATH}"
GOPATH=$(go env GOPATH)
GOPATH_PROJECT_ROOT="${GOPATH}/src/github.com/argoproj/argo-cd"
# output tool versions
go version
protoc --version
swagger version
jq --version
export GO111MODULE=off
# Generate pkg/apis/<group>/<apiversion>/(generated.proto,generated.pb.go)
# NOTE: any dependencies of our types to the k8s.io apimachinery types should be added to the
# --apimachinery-packages= option so that go-to-protobuf can locate the types, but prefixed with a
# '-' so that go-to-protobuf will not generate .proto files for it.
PACKAGES=(
github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1
)
APIMACHINERY_PKGS=(
+k8s.io/apimachinery/pkg/util/intstr
+k8s.io/apimachinery/pkg/api/resource
+k8s.io/apimachinery/pkg/runtime/schema
+k8s.io/apimachinery/pkg/runtime
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/api/core/v1
k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
)
export GO111MODULE=on
[ -e ./v3 ] || ln -s . v3
[ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}")
# protoc_include is the include directory containing the .proto files distributed with protoc binary
if [ -d /dist/protoc-include ]; then
# containerized codegen build
protoc_include=/dist/protoc-include
else
# local codegen build
protoc_include=${PROJECT_ROOT}/dist/protoc-include
fi
# go-to-protobuf expects dependency proto files to be in $GOPATH/src. Copy them there.
rm -rf "${GOPATH}/src/github.com/gogo/protobuf" && mkdir -p "${GOPATH}/src/github.com/gogo" && cp -r "${PROJECT_ROOT}/vendor/github.com/gogo/protobuf" "${GOPATH}/src/github.com/gogo"
rm -rf "${GOPATH}/src/k8s.io/apimachinery" && mkdir -p "${GOPATH}/src/k8s.io" && cp -r "${PROJECT_ROOT}/vendor/k8s.io/apimachinery" "${GOPATH}/src/k8s.io"
rm -rf "${GOPATH}/src/k8s.io/api" && mkdir -p "${GOPATH}/src/k8s.io" && cp -r "${PROJECT_ROOT}/vendor/k8s.io/api" "${GOPATH}/src/k8s.io"
rm -rf "${GOPATH}/src/k8s.io/apiextensions-apiserver" && mkdir -p "${GOPATH}/src/k8s.io" && cp -r "${PROJECT_ROOT}/vendor/k8s.io/apiextensions-apiserver" "${GOPATH}/src/k8s.io"
go-to-protobuf \
--go-header-file="${PROJECT_ROOT}"/hack/custom-boilerplate.go.txt \
--packages="$(
IFS=,
echo "${PACKAGES[*]}"
)" \
--apimachinery-packages="$(
IFS=,
echo "${APIMACHINERY_PKGS[*]}"
)" \
--proto-import="${PROJECT_ROOT}"/vendor \
--proto-import="${protoc_include}" \
--output-dir="${GOPATH}/src/"
# go-to-protobuf modifies vendored code. Re-vendor code so it's available for subsequent steps.
go mod vendor
# Either protoc-gen-go, protoc-gen-gofast, or protoc-gen-gogofast can be used to build
# server/*/<service>.pb.go from .proto files. golang/protobuf and gogo/protobuf can be used
# interchangeably. The difference in the options are:
# 1. protoc-gen-go - official golang/protobuf
#GOPROTOBINARY=go
# 2. protoc-gen-gofast - fork of golang golang/protobuf. Faster code generation
#GOPROTOBINARY=gofast
# 3. protoc-gen-gogofast - faster code generation and gogo extensions and flexibility in controlling
# the generated go code (e.g. customizing field names, nullable fields)
GOPROTOBINARY=gogofast
# Generate server/<service>/(<service>.pb.go|<service>.pb.gw.go)
MOD_ROOT=${GOPATH}/pkg/mod
grpc_gateway_version=$(go list -m github.com/grpc-ecosystem/grpc-gateway | awk '{print $NF}' | head -1)
GOOGLE_PROTO_API_PATH=${MOD_ROOT}/github.com/grpc-ecosystem/grpc-gateway@${grpc_gateway_version}/third_party/googleapis
GOGO_PROTOBUF_PATH=${PROJECT_ROOT}/vendor/github.com/gogo/protobuf
PROTO_FILES=$(find "$PROJECT_ROOT" \( -name "*.proto" -and -path '*/server/*' -or -path '*/reposerver/*' -and -name "*.proto" -or -path '*/cmpserver/*' -and -name "*.proto" -or -path '*/commitserver/*' -and -name "*.proto" -or -path '*/util/askpass/*' -and -name "*.proto" \) | sort)
for i in ${PROTO_FILES}; do
protoc \
-I"${PROJECT_ROOT}" \
-I"${protoc_include}" \
-I./vendor \
-I"$GOPATH"/src \
-I"${GOOGLE_PROTO_API_PATH}" \
-I"${GOGO_PROTOBUF_PATH}" \
--${GOPROTOBINARY}_out=plugins=grpc:"$GOPATH"/src \
--grpc-gateway_out=logtostderr=true:"$GOPATH"/src \
--swagger_out=logtostderr=true:. \
"$i"
done
# This file is generated but should not be checked in.
rm util/askpass/askpass.swagger.json
[ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}"
[ -L ./v3 ] && rm -rf v3
# collect_swagger gathers swagger files into a subdirectory
collect_swagger() {
SWAGGER_ROOT="$1"
SWAGGER_OUT="${PROJECT_ROOT}/assets/swagger.json"
PRIMARY_SWAGGER=$(mktemp)
COMBINED_SWAGGER=$(mktemp)
cat <<EOF >"${PRIMARY_SWAGGER}"
{
"swagger": "2.0",
"info": {
"title": "Consolidate Services",
"description": "Description of all APIs",
"version": "version not set"
},
"paths": {}
}
EOF
rm -f "${SWAGGER_OUT}"
find "${SWAGGER_ROOT}" -name '*.swagger.json' -exec swagger mixin --ignore-conflicts "${PRIMARY_SWAGGER}" '{}' \+ >"${COMBINED_SWAGGER}"
jq -r 'del(.definitions[].properties[]? | select(."$ref"!=null and .description!=null).description) | del(.definitions[].properties[]? | select(."$ref"!=null and .title!=null).title) |
# The "array" and "map" fields have custom unmarshaling. Modify the swagger to reflect this.
.definitions.v1alpha1ApplicationSourcePluginParameter.properties.array = {"description":"Array is the value of an array type parameter.","type":"array","items":{"type":"string"}} |
del(.definitions.v1alpha1OptionalArray) |
.definitions.v1alpha1ApplicationSourcePluginParameter.properties.map = {"description":"Map is the value of a map type parameter.","type":"object","additionalProperties":{"type":"string"}} |
del(.definitions.v1alpha1OptionalMap) |
# Output for int64 is incorrect, because it is based on proto definitions, where int64 is a string. In our JSON API, we expect int64 to be an integer. https://github.com/grpc-ecosystem/grpc-gateway/issues/219
(.definitions[]?.properties[]? | select(.type == "string" and .format == "int64")) |= (.type = "integer")
' "${COMBINED_SWAGGER}" |
jq '.definitions.v1Time.type = "string" | .definitions.v1Time.format = "date-time" | del(.definitions.v1Time.properties)' |
jq '.definitions.v1alpha1ResourceNode.allOf = [{"$ref": "#/definitions/v1alpha1ResourceRef"}] | del(.definitions.v1alpha1ResourceNode.properties.resourceRef) ' \
>"${SWAGGER_OUT}"
/bin/rm "${PRIMARY_SWAGGER}" "${COMBINED_SWAGGER}"
}
# clean up generated swagger files (should come after collect_swagger)
clean_swagger() {
SWAGGER_ROOT="$1"
find "${SWAGGER_ROOT}" -name '*.swagger.json' -delete
}
collect_swagger server
clean_swagger server
clean_swagger reposerver
clean_swagger controller
clean_swagger cmpserver
clean_swagger commitserver