-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathgen-proto.sh
More file actions
executable file
·363 lines (279 loc) · 7.59 KB
/
gen-proto.sh
File metadata and controls
executable file
·363 lines (279 loc) · 7.59 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#! /usr/bin/env bash
# Tool to regenerate protobuf code as needed
#
# - it tacks on a version number for use by the individual tools
# - it supports git and mercurial version#
#
# NB:
# o the attempt at decoding dirty repo state for mercurial is
# borked. It doesn't know about untracked files
#
# (c) 2016 Sudhi Herle
#
# License: GPLv2
# Relative path to protobuf sources
# e.g. "a.proto b.proto"
Protobufs="internal/pb/hdr.proto internal/pb/key.proto"
#set -x
# -- DO NOT CHANGE ANYTHING AFTER THIS --
Z=`basename $0`
PWD=`pwd`
Static=0
Dryrun=0
Prodver=""
Repover=""
Verbose=0
Go=`which go`
Arch=
Bindir=$PWD/bin
#e=echo
#set -x
# Go module proxy URL
GoModProxy="https://proxy.golang.org"
ProtobufRepo="google.golang.org/protobuf"
VTProtoRepo="github.com/planetscale/vtprotobuf"
# tools.go definition
Tools_go=./tools.go
die() {
echo "$Z: $@" 1>&2
exit 0
}
warn() {
echo "$Z: $@" 1>&2
}
case $BASH_VERSION in
4.*|5.*) ;;
*) die "I need bash 4.x to run!"
;;
esac
# Fetch the latest version of the given tool
gettool_version_latest() {
local mod=$1; shift
local jq=`which jq`
local curl=`which curl`
[ -z "$jq" ] && die "can't find jq; please install it"
[ -z "$curl" ] && die "can't find curl; please install it"
local ver=$($curl -s "${GoModProxy}/${mod}/@latest" | $jq .Version | tr -d '"' ) || die "can't run curl"
echo $ver
}
show_tool_versions() {
# Lets find the latest versions
local pb_latest=$(gettool_version_latest $ProtobufRepo)
local vt_latest=$(gettool_version_latest $VTProtoRepo)
set -- $($Go list -m $ProtobufRepo)
local pb_mod=$2
set -- $($Go list -m $VTProtoRepo)
local vt_mod=$2
echo "$ProtobufRepo: $pb_mod [latest $pb_latest]"
echo "$VTProtoRepo: $vt_mod [latest $vt_latest]"
exit 0
}
getvcs_version() {
local rev=
local prodv=
local git=`which git`
local hg=`which hg`
if [ -n "$git" ]; then
local xrev=$(git describe --always --dirty --long --abbrev=12) || exit 1
rev="git:$xrev"
prodv=$(git tag --list | sort -V | tail -1)
elif [ -n "$hg" ]; then
local xrev=$(hg id --id) || exit 1
local brev=${xrev%+}
if [ "$brev" != "$xrev" ]; then
rev="hg:${brev}+dirty"
else
rev="hg:${brev}"
fi
prodv=$(hg log -r "branch(stable) and tag()" -T "{tags}\n" | sort -V | tail -1)
else
warn "no git or hg found; can't get VCS info"
rev="UNKNOWN-VER"
fi
[ -n "$Prodver" ] && prodv=$Prodver
echo "$rev $prodv"
return 0
}
read -r Repover Prodver <<< $(getvcs_version)
usage() {
declare -a progv=($Progs)
declare n=${#progv[@]}
declare pstr=
for ((i=0; i < n; i++)); do
local ent=${progv[$i]}
local dir=${ent%%:*}
local tool=${ent##*:}
pstr=$(printf "$pstr\n\t%s $Prodver $Repover (from ./%s)" $tool $dir)
done
cat <<EOF
$0 - A Go tool that builds protobuf code as needed.
Usage: $0
$0 [options]
Options:
-h, --help Show this help message and quit
-n, --dry-run Dry-run, don't actually build anything [False]
-v, --verbose Build verbosely (adds "-v" to go tooling) [False]
--check-tools Show the latest version of the protobuf tools
--vet Run "go vet" on modules named on the command line [False]
-x Run in debug/trace mode [False]
--print-arch Print the target architecture and exit
EOF
exit 0
}
host=`uname|tr '[A-Z]' '[a-z]'`
Tool=
args=
Printarch=0
#set -x
ac_prev=
for ac_option
do
shift
if [ -n "$ac_prev" ]; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
case "$ac_option" in
-*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) ac_optarg= ;;
esac
case "$ac_option" in
--help|-h|--hel|--he|--h)
usage;
;;
--vet)
Tool=vet
;;
--mod)
Tool=mod
;;
-v|--verbose)
Verbose=1
;;
--dry-run|-n)
Dryrun=1
;;
--debug|-x)
set -x
;;
--print-arch)
Printarch=1
;;
--check-tools)
show_tool_versions
;;
*) # first non option terminates option processing.
# we gather all remaining args and bundle them up.
args="$args $ac_option"
for xx
do
args="$args $xx"
done
break
;;
esac
done
[ $Dryrun -gt 0 ] && e=echo
# let every error abort
set -e
# build a tool that runs on the host - if needed.
hosttool() {
local out=$1
local src=$2
local name="$(basename $out)"
# build per the go.mod file
# build it and stash it in the hostdir
echo "Building $name from $src .."
$e $Go build -o $out $src || die "can't build $name"
return 0
}
# check if a .proto file is newer than generated files
# Return "shell true" if files need to be regenerated
needs_regen() {
local fn=$1; shift
local base=${fn%.proto}
local pbgo=${base}.pb.go
local vtgo=${base}_vtproto.pb.go
[ -f $pbgo -a -f $vtgo ] || return 0
[ $fn -nt $pbgo -o $fn -nt $vtgo ] && return 0
return 1
}
# protobuf gen
buildproto() {
local pbgo=protoc-gen-go
local vtgo=protoc-gen-go-vtproto
local pbgo_src="$ProtobufRepo/cmd/$pbgo"
local vtgo_src="$VTProtoRepo/cmd/$vtgo"
local pc
local args="$*"
local pgen=$(type -p protoc)
[ -z $pgen ] && die "install protoc tools (protobuf on macports)"
# Check to see if tools.go is present
if [ ! -f $Tools_go ]; then
cat <<_EOF > $Tools_go
//go:build tools
package tools
import (
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
_ "github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto"
)
_EOF
$e $Go mod tidy
fi
local gogen=$Hostbindir/$pbgo
local vtgen=$Hostbindir/$vtgo
# install protoc-gen-go and vtproto tools locally; we want to
# pin these tools to the specific versions in go.mod
# tools.go captures the essential tooling dependency in go.mod
[ -x $gogen ] || hosttool $gogen $pbgo_src
[ -x $vtgen ] || hosttool $vtgen $vtgo_src
local pwd=$(pwd)
for f in $args; do
needs_regen $f || continue
$e $pgen \
--go_out=$pwd --plugin protoc-gen-go="$gogen" \
--go_opt="paths=source_relative" \
--go-vtproto_out=$pwd --plugin protoc-gen-go-vtproto="$vtgen" \
--go-vtproto_opt="paths=source_relative,features=marshal+unmarshal+size" \
$f || die "can't generate protobuf output for $f .."
done
return 0
}
# the rest has to execute in the context of main shell (not funcs)
hostos=$($Go env GOHOSTOS) || exit 1
hostcpu=$($Go env GOHOSTARCH) || exit 1
if [ $Printarch -gt 0 ]; then
echo "$hostos-$hostcpu"
exit 0
fi
# This is where build outputs go
Hostbindir=$Bindir/$hostos-$hostcpu
export PATH=$Hostbindir:$PATH
[ -d $Hostbindir ] || mkdir -p $Hostbindir
# Do Protobufs if needed
if [ -z "$Protobufs" ]; then
warn "No protobuf files; nothing to do .."
exit 0
fi
vflag=""
[ $Verbose -gt 0 ] && vflag="-v"
case $Tool in
test)
set -- $args
$e $Go test $vflag "$@"
;;
vet)
set -- $args
$e $Go vet $vflag "$@"
;;
mod)
set -- $args
$e $Go mod $vflag "$@"
;;
*) # Default is to build programs
set +e
buildproto $Protobufs
set -e
esac
# vim: ft=sh:expandtab:ts=4:sw=4:tw=84: