-
Notifications
You must be signed in to change notification settings - Fork 434
Document use of the build plugin #2176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
6cb362c
9e70d5c
5df133f
299f6b8
9b9c1ad
3d2e229
5a33c78
7c0d31d
03aafc5
31dfa48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -4,8 +4,6 @@ Learn how to generate stubs for gRPC Swift from a service defined using the Prot | |||||||||||||
|
||||||||||||||
## Overview | ||||||||||||||
|
||||||||||||||
### Using protoc | ||||||||||||||
|
||||||||||||||
If you've used Protocol Buffers before then generating gRPC Swift stubs should be simple. If you're | ||||||||||||||
unfamiliar with Protocol Buffers then you should get comfortable with the concepts before | ||||||||||||||
continuing; the [Protocol Buffers website](https://protobuf.dev/) is a great place to start. | ||||||||||||||
|
@@ -16,7 +14,17 @@ The [`grpc-swift-protobuf`](https://github.com/grpc/grpc-swift-protobuf) package | |||||||||||||
> `protoc-gen-grpc-swift` only generates gRPC stubs, it doesn't generate messages. You must use | ||||||||||||||
> `protoc-gen-swift` to generate messages in addition to gRPC Stubs. | ||||||||||||||
|
||||||||||||||
To generate gRPC stubs for your `.proto` files you must run the `protoc` command with | ||||||||||||||
The protoc plugin can be used from the command line directly, passed to `protoc`, or | ||||||||||||||
you can make use of a convenience which adds the stub generation to the Swift build graph. | ||||||||||||||
The automatic gRPC Swift stub generation makes use of a [Swift Package Manager build plugin]( | ||||||||||||||
https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/Plugins.md) to use the | ||||||||||||||
`.proto` files as inputs to the build graph, input them into `protoc` using `protoc-gen-grpc-swift` | ||||||||||||||
and `protoc-gen-swift` as needed, and make the resulting gRPC Swift stubs available to code | ||||||||||||||
against without committing them as source. The build plugin may be invoked either from the command line or from Xcode. | ||||||||||||||
|
||||||||||||||
### Using protoc | ||||||||||||||
|
||||||||||||||
To generate gRPC stubs for your `.proto` files directly you must run the `protoc` command with | ||||||||||||||
the `--grpc-swift_out=<DIRECTORY>` option: | ||||||||||||||
|
||||||||||||||
```console | ||||||||||||||
|
@@ -69,7 +77,7 @@ allows you to specify a mapping from `.proto` files to the Swift module they are | |||||||||||||
allows the code generator to add appropriate imports to your generated stubs. This is described in | ||||||||||||||
more detail in the [SwiftProtobuf documentation](https://github.com/apple/swift-protobuf/blob/main/Documentation/PLUGIN.md). | ||||||||||||||
|
||||||||||||||
#### Building the plugin | ||||||||||||||
#### Building the protoc plugin | ||||||||||||||
|
||||||||||||||
> The version of `protoc-gen-grpc-swift` you use mustn't be newer than the version of | ||||||||||||||
> the `grpc-swift-protobuf` you're using. | ||||||||||||||
|
@@ -83,3 +91,83 @@ swift build --product protoc-gen-grpc-swift | |||||||||||||
|
||||||||||||||
This command will build the plugin into `.build/debug` directory. You can get the full path using | ||||||||||||||
`swift build --show-bin-path`. | ||||||||||||||
|
||||||||||||||
## Using the build plugin | ||||||||||||||
|
||||||||||||||
The build plugin (`GRPCProtobufGenerator`) is a great choice for convenient dynamic code generation, however it does come with some limitations. | ||||||||||||||
Because it generates the gRPC Swift stubs as part of the build it has the requirement that `protoc` must be guaranteed | ||||||||||||||
to be available at compile time. Also because of a limitation of Swift Package Manager build plugins, the plugin | ||||||||||||||
|
Because it generates the gRPC Swift stubs as part of the build it has the requirement that `protoc` must be guaranteed | |
to be available at compile time. Also because of a limitation of Swift Package Manager build plugins, the plugin | |
Because it generates the gRPC Swift stubs as part of the build it has the requirement that `protoc` must be available at compile time. Also because of a limitation of Swift Package Manager build plugins, the plugin |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't actually true. The reason you can't use this build plugin in non-leaf packages is that it forces an implicit build time dependency on protoc
which might not always be available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks for pointing that out! I'll have to refresh my knowledge of the docs.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to write in the active voice, e.g. "The build plugin detects .proto
files in the source tree and invokes protoc
once for each file."
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: active voice
"You must adopt Swift Package Manager build plugins on a per-target basis by modifying your package manifest (Package.swift file). To do this, declare the grpc-swift-protobuf
package as a dependency and add the plugin to your desired targets.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use an example name that gives more of hint as to where it could / should be used, e.g "echo-server"
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no directory named Source
so it shouldn't be in a fixed-width font:
are included in the target's source directory (below relevant the `Source` directory) and that you have | |
are included in the target's source directory (below relevant the source directory) and that you have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to make reference to the Sources
directory but I think the sentence is muddled so I've dropped it.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Active voice:
"You must provide a configuration file in the directory which encloses all .proto
files (in the same directory or a parent). Configuration files, written in JSON, tell the build plugin about the options used for protoc
invocations. You must name the file grpc-swift-proto-generator-config.json
and structure it in the following format:"
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to mention that this change never actually got made, the config is still using useAccessLevelOnImports
. I can fix that up though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| `generate.servers` | `true`, `false` | `True` | Generate server stubs | | |
| `generate.clients` | `true`, `false` | `True` | Generate client stubs | | |
| `generate.messages` | `true`, `false` | `True` | Generate message stubs | | |
| `generate.servers` | `true`, `false` | `true` | Generate server stubs | | |
| `generate.clients` | `true`, `false` | `true` | Generate client stubs | | |
| `generate.messages` | `true`, `false` | `true` | Generate message stubs | |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we're describing JSON, these should be strings
| `generatedSource.accessLevel` | `public`, `package`, `internal` | `internal` | Access level for generated stubs | | |
| `generatedSource.accessLevel` | `"public"`, `"package"`, `"internal"` | `"internal"` | Access level for generated stubs | |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's JSON the default is null
, but that has meaning which we should describe
| `protoc.executablePath` | N/A | N/A (attempted discovery) | Path to the `protoc` executable | | |
| `protoc.executablePath` | N/A | null | |
| Path to the `protoc` executable. Autodetected if the `null`. | |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description is wrong here. Also like above we put the default as null
and explain that the directory of the config file is used if null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should pull this further up (so that it's the second paragraph) and make it more concise. We can then expand in each section. I'd like it so that the overview is like a landing page; you're giving the reader a brief introduction and then giving them a choice (manual generation with protoc vs. automated with build plugin.)
To that end it might be worth swapping the two around and having the build plugin first (progressive disclosure?).