-
Notifications
You must be signed in to change notification settings - Fork 6
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
Code generation command plugin #40
base: main
Are you sure you want to change the base?
Conversation
Motivation: To make it simpler to generate gRPC stubs with `protoc-gen-grpc-swift` and `protoc-gen-swift`. Modifications: * Add a new command plugin `swift package generate-grpc-code-from-protos/path/to/Protos/HelloWorld.proto --import-path /path/to/Protos` * Refactor some errors Result: More convenient code generation
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 looks good so far! Most of the comments are around the UX.
] | ||
), | ||
dependencies: [ | ||
"protoc-gen-grpc-swift", |
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.
"protoc-gen-grpc-swift", | |
.target(name: "protoc-gen-grpc-swift"), |
|
||
// Code generator SwiftPM command | ||
.plugin( | ||
name: "GRPCGeneratorCommand", |
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.
We should include "Protobuf" in the name. I find "Command" a weird suffix but that stems more from me finding the "command plugin" naming weird as well.
name: "GRPCGeneratorCommand", | |
name: "GRPCProtobufGeneratorCommand", |
struct CommandConfig { | ||
var common: GenerationConfig | ||
|
||
var dryRun: Bool |
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.
Love this, great idea!
case "package": | ||
config.common.accessLevel = .`package` | ||
default: | ||
Diagnostics.error("Unknown accessLevel \(value)") |
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.
We should parrot out the name of the argument as passed by the user ("--access-level") rather than the property name.
switch flag { | ||
case .accessLevel: | ||
let accessLevel = argExtractor.extractOption(named: flag.rawValue) | ||
if let value = accessLevel.first { |
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.
If there's more than one value we should either warn or throw an error.
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 feedback applies to all of these options.)
let inputFileURLs = inputFiles.map { URL(fileURLWithPath: $0) } | ||
|
||
// MARK: protoc-gen-grpc-swift | ||
if config.clients != false || config.servers != false { |
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.
These should be non-optional now so can be more idiomatic:
if config.clients != false || config.servers != false { | |
if config.clients || config.servers { |
} | ||
|
||
// MARK: protoc-gen-swift | ||
if config.messages != false { |
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.
if config.messages != false { | |
if config.messages { |
/// - arguments: The arguments to be passed to `protoc`. | ||
func printProtocInvocation(_ executableURL: URL, _ arguments: [String]) { | ||
print("protoc invocation:") | ||
print(" \(executableURL.absoluteStringNoScheme) \\") |
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.
print(" \(executableURL.absoluteStringNoScheme) \\") | |
print("\(executableURL.absoluteStringNoScheme) \\") |
/// - executableURL: The path to the `protoc` executable. | ||
/// - arguments: The arguments to be passed to `protoc`. | ||
func printProtocInvocation(_ executableURL: URL, _ arguments: [String]) { | ||
print("protoc invocation:") |
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.
Not sure this is necessary; protoc ...
will make it obvious.
func printProtocInvocation(_ executableURL: URL, _ arguments: [String]) { | ||
print("protoc invocation:") | ||
print(" \(executableURL.absoluteStringNoScheme) \\") | ||
for argument in arguments[..<arguments.count.advanced(by: -1)] { |
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.
Can't you just do print(arguments.joined(separator: " \\\n "))
?
Motivation:
To make it simpler to generate gRPC stubs with
protoc-gen-grpc-swift
andprotoc-gen-swift
.Modifications:
The command plugin can be invoked from the CLI as:
The plugin has flexible configuration:
protoc
invocations it uses for ease of debugging. The--dry-run
flag can be supplied for this purpose or so that they may be extracted and used separately e.g. in a script.protoc
path is supplied then Swift Package Manager will attempt to locate it.output
directory is supplied then generated files are placed a Swift Package Manager build directory.Result:
More convenient code generation
This PR is split out of #26