Skip to content

Commit

Permalink
Add example for gateway generation (#18)
Browse files Browse the repository at this point in the history
Improve the docs for where custom plugins should be defined and add an
example with grpc-gateway.
  • Loading branch information
emcfarlane authored Feb 8, 2024
1 parent c68f583 commit ddcaa81
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 11 deletions.
27 changes: 19 additions & 8 deletions cmd/protoc-gen-multi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ In this example, we’ll demonstrate how to package the following plugins into t
- `protoc-gen-go-grpc`
- `protoc-gen-go`
- `protoc-gen-go-vtproto`
- `protoc-gen-grpc-gateway`


### Step 1 - Create an organization to push custom plugin(s)
Expand All @@ -36,18 +37,22 @@ Create a docker image with all the protoc plugins desired, plus `protoc-gen-mult
```dockerfile
# syntax=docker/dockerfile:1.6
FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS build
# Install plugins.
ARG TARGETOS TARGETARCH

# Add custom plugins here
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go install -ldflags "-s -w" google.golang.org/protobuf/cmd/protoc-gen-go@v1.32
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go install -ldflags "-s -w" google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go install -ldflags "-s -w" github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v0.5.0
go install -ldflags "-s -w" google.golang.org/protobuf/cmd/protoc-gen-go@v1.32 \
&& go install -ldflags "-s -w" google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3 \
&& go install -ldflags "-s -w" github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v0.5.0 \
&& go install -ldflags "-s -w" github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.19

# Install protoc-gen-multi, must be installed.
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go install -ldflags "-s -w" github.com/bufbuild/tools/cmd/protoc-gen-multi@latest

# Move binaries prefixed with GOOS_GOARCH to /go/bin.
RUN mv /go/bin/$TARGETOS_$TARGETARCH/* /go/bin || true

# Build final image.
FROM scratch
COPY --from=build --link /etc/passwd /etc/passwd
Expand All @@ -66,26 +71,32 @@ docker buildx build --platform linux/amd64 -t buf.example.com/custom-plugins/mul

At the very minimum you’ll need the following fields set:

```bash
```yaml
version: v1
name: buf.example.com/custom-plugins/multi
plugin_version: v0.1.0
output_languages:
- go
registry:
# Add the runtime deps required by your plugins for the generated SDK.
go:
deps:
- module: google.golang.org/protobuf
version: v1.32.0
- module: google.golang.org/grpc
version: v1.3.0
- module: github.com/grpc-ecosystem/grpc-gateway/v2
version: v2.19
# Add the options to invoke each plugin for the generated SDK.
opts:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
- --go-vtproto_out=.
- --go-vtproto_opt=paths=source_relative,features=marshal+unmarshal+size
- --grpc-gateway_out=.
- --grpc-gateway_opt=paths=source_relative,generate_unbound_methods=true
```
Note that typically a `buf.plugin.yaml` file defines a single plugin. However, in this case, we have three different plugins with different versions. So the version specified here should be whatever makes sense for your setup.
Expand All @@ -98,7 +109,7 @@ There are additional fields that can be set. Please refer to the `buf.plugin.yam
```bash
buf beta registry plugin push \
--visibility public \
--image buf.example.com/custom-plugins/multi:v1.0.0 \
--image buf.example.com/custom-plugins/multi:v0.1.0 \
--override-remote=buf.example.com
```

Expand Down
1 change: 1 addition & 0 deletions cmd/protoc-gen-multi/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gen
24 changes: 24 additions & 0 deletions cmd/protoc-gen-multi/example/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# syntax=docker/dockerfile:1.6
FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS build
ARG TARGETOS TARGETARCH

# Add custom plugins here
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go install -ldflags "-s -w" google.golang.org/protobuf/cmd/protoc-gen-go@v1.32 \
&& go install -ldflags "-s -w" google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3 \
&& go install -ldflags "-s -w" github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v0.5.0 \
&& go install -ldflags "-s -w" github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.19

# Install protoc-gen-multi, must be installed.
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go install -ldflags "-s -w" github.com/bufbuild/tools/cmd/protoc-gen-multi@latest

# Move binaries prefixed with GOOS_GOARCH to /go/bin.
RUN mv /go/bin/$TARGETOS_$TARGETARCH/* /go/bin || true

# Build final image.
FROM scratch
COPY --from=build --link /etc/passwd /etc/passwd
COPY --from=build /go/bin/ /bin
USER nobody
ENTRYPOINT [ "protoc-gen-multi" ]
19 changes: 19 additions & 0 deletions cmd/protoc-gen-multi/example/buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: v1
managed:
enabled: true
go_package_prefix:
default: "example.com"
plugins:
# Use the plugin as a remote plugin.
# NB: ensure BSR registry and version matches.
- plugin: bufbuild.internal/local/multi:v1.0.3
out: gen
# Set the below options to invoke different commands.
opt: --go_out=.
--go_opt=paths=source_relative
--go-grpc_out=.
--go-grpc_opt=paths=source_relative
--go-vtproto_out=.
--go-vtproto_opt=paths=source_relative,features=marshal+unmarshal+size
--grpc-gateway_out=.
--grpc-gateway_opt=paths=source_relative,generate_unbound_methods=true
25 changes: 25 additions & 0 deletions cmd/protoc-gen-multi/example/buf.plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: v1
name: bufbuild.internal/local/multi # Change me to your BSR plugin repository.
plugin_version: v0.1.0 # Change me to your version.
output_languages:
- go
registry:
# Add the runtime deps required by your plugins for the generated SDK.
go:
deps:
- module: google.golang.org/protobuf
version: v1.32
- module: google.golang.org/grpc
version: v1.3
- module: github.com/grpc-ecosystem/grpc-gateway/v2
version: v2.19
# Add the options to invoke each plugin for the generated SDK.
opts:
- --go_out=.
- --go_opt=paths=source_relative
- --go-grpc_out=.
- --go-grpc_opt=paths=source_relative
- --go-vtproto_out=.
- --go-vtproto_opt=paths=source_relative,features=marshal+unmarshal+size
- --grpc-gateway_out=.
- --grpc-gateway_opt=paths=source_relative,generate_unbound_methods=true
1 change: 1 addition & 0 deletions cmd/protoc-gen-multi/example/buf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version: v1
28 changes: 28 additions & 0 deletions cmd/protoc-gen-multi/example/proto/example/example.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2023 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package acme.example;

message GreetRequest {
string name = 1;
}
message GreetResponse {
string message = 1;
}

service GreeterServier {
rpc Greet(GreetRequest) returns (GreetResponse);
}
5 changes: 4 additions & 1 deletion cmd/protoc-gen-multi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ func parsePlugins(args []string) ([]plugin, error) {
name := strings.TrimSuffix(value, "_opt")
plugin := getPlugin(name)
plugin.name = name
plugin.opt = arg
if plugin.opt != "" {
plugin.opt += "," // Separate multiple opt flags with a comma.
}
plugin.opt += arg
} else {
return nil, fmt.Errorf("expected suffix \"_opt\" or \"_out\": %q", flag)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/protoc-gen-multi/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestGenerateMulti(t *testing.T) {
if err := protojson.Unmarshal(requestExample, &request); err != nil {
t.Fatal(err)
}
request.Parameter = proto.String("--go_out=gen --go_opt=paths=source_relative --go-vtproto_out=gen --go-vtproto_opt=paths=source_relative")
request.Parameter = proto.String("--go_out=gen --go_opt=paths=source_relative --go-vtproto_out=gen --go-vtproto_opt=paths=source_relative --go-vtproto_opt=features=marshal+unmarshal+size")
var response pluginpb.CodeGeneratorResponse
if err := generate(context.Background(), nil, &request, &response); err != nil {
t.Fatal(err)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: v1
name: bufbuild.internal/local/multi
plugin_version: v1.0.0
plugin_version: v0.1.0
output_languages:
- go
registry:
Expand Down

0 comments on commit ddcaa81

Please sign in to comment.