pulumi/sdk/proto/generate.sh
joeduffy b0d91ad9a9 Make Protobuf/gRPC compilation repeatable
I tried to re-generate the Protobuf/gRPC files, but generate.sh seems to
have assumed I manually built the Dockerfile ahead-of-time (unless I'm
missing something -- very possible). Unfortunately, when I went to do
that, I ended up with a handful of errors, most of them due to
differences in versions. (We probably want to think about pinning them.)

To remedy both issues, I've fixed up the Dockerfile so that it works for
me at least, and added a build step to the front of generate.sh.
2018-08-04 10:27:36 -07:00

68 lines
2.9 KiB
Bash
Executable file

#!/bin/bash
#
# This script regenerates all Protobuf/gRPC client files.
#
# For now, it must be run manually, and the results are checked into source control. Eventually we
# might choose to automate this process as part of the overall build so that it's less manual and
# hence error prone.
#
# This script relies only on Docker. The container holds the installation of gRPC, tools, etc., for
# different langauges, so nothing is else required to be installed on your machine.
set -e
# First build our Protobuf/gRPC compiler Docker image, so dev machines don't need it.
echo "* Building Protobuf/gRPC compilers:"
docker build -t pulumi/protobuf-builder .
DOCKER_RUN="docker run -it --rm -v $(pwd)/../python:/python -v $(pwd)/../nodejs:/nodejs -v $(pwd):/local pulumi/protobuf-builder"
PROTOC="$DOCKER_RUN protoc"
# `status.proto` is in our source tree so that we can implement initialization failure in the
# dynamic client (written in JS) using the protobuf notion of "details" -- arbitrary protobuf
# messages packaged up inside of an error. Hence, `JS_PROTO_FILES` includes it and `PROTO_FILES`
# does not.
PROTO_FILES=$(find . -name "*.proto" -not -name "status.proto")
JS_PROTO_FILES=$(find . -name "*.proto")
echo "* Generating Protobuf/gRPC SDK files:"
echo -e "\tVERSION: $($PROTOC --version)"
echo -e "Generated by version $($PROTOC --version) of protoc" > ./grpc_version.txt
GO_PULUMIRPC=./go
GO_PROTOFLAGS="plugins=grpc"
echo -e "\tGo: $GO_PULUMIRPC [$GO_PROTOFLAGS]"
mkdir -p $GO_PULUMIRPC
$PROTOC --go_out=$GO_PROTOFLAGS:$GO_PULUMIRPC $PROTO_FILES
JS_PULUMIRPC=/nodejs/proto/
JS_PROTOFLAGS="import_style=commonjs,binary"
echo -e "\tJS: $JS_PULUMIRPC [$JS_PROTOFLAGS]"
$PROTOC --js_out=$JS_PROTOFLAGS:$JS_PULUMIRPC --grpc_out=$JS_PULUMIRPC --plugin=protoc-gen-grpc=/usr/local/bin/grpc_tools_node_protoc_plugin $JS_PROTO_FILES
function on_exit() {
rm -rf "$TEMP_DIR"
}
# Protoc for Python has a bug where, if your proto files are all in the same directory relative
# to one another, imports of said proto files will produce imports that don't work using Python 3.
#
# Since our proto files are all in the same directory, this little bit of sed rewrites the broken
# imports that protoc produces, of the form
# import foo_pb2 as bar
# to the form
# from . import foo_pb2 as bar
# This form is semantically equivalent and is accepted by both Python 2 and Python 3.
trap on_exit EXIT
echo -e "\tPython temp dir: $TEMP_DIR"
$DOCKER_RUN /bin/bash -c 'PY_PULUMIRPC=/python/lib/pulumi/runtime/proto/ && \
echo -e "\tPython: $PY_PULUMIRPC" && \
TEMP_DIR="/tmp/python-build" && \
echo -e "\tPython temp dir: $TEMP_DIR" && \
mkdir -p "$TEMP_DIR" && \
python -m grpc_tools.protoc -I./ --python_out="$TEMP_DIR" --grpc_python_out="$TEMP_DIR" *.proto && \
sed -i "s/^import \([^ ]*\)_pb2 as \([^ ]*\)$/from . import \1_pb2 as \2/" "$TEMP_DIR"/*.py && \
cp "$TEMP_DIR"/*.py "$PY_PULUMIRPC"'
echo "* Done."