Skip to content
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

Add Prost and Tonic rules. #2033

Merged
merged 31 commits into from
Jun 30, 2023
Merged

Conversation

freeformstu
Copy link
Contributor

@freeformstu freeformstu commented Jun 25, 2023

Verification Evidence:

Helloworld server/client:

Server:

$ bazel run //proto/prost/private/tests/proto/services/helloworld:server
INFO: Analyzed target //proto/prost/private/tests/proto/services/helloworld:server (1 packages loaded, 5 targets configured).
INFO: Found 1 target...
Target //proto/prost/private/tests/proto/services/helloworld:server up-to-date:
  bazel-bin/proto/prost/private/tests/proto/services/helloworld/server
INFO: Elapsed time: 0.124s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/proto/prost/private/tests/proto/services/helloworld/server
GreeterServer listening on [::1]:50051
Got a request from Some([::1]:38592)

Client:

$ bazel run //proto/prost/private/tests/proto/services/helloworld:client
INFO: Analyzed target //proto/prost/private/tests/proto/services/helloworld:client (0 packages loaded, 2 targets configured).
INFO: Found 1 target...
Target //proto/prost/private/tests/proto/services/helloworld:client up-to-date:
  bazel-bin/proto/prost/private/tests/proto/services/helloworld/client
INFO: Elapsed time: 0.110s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/proto/prost/private/tests/proto/services/helloworld/client
RESPONSE=Response { metadata: MetadataMap { headers: {"content-type": "application/grpc", "date": "Sun, 25 Jun 2023 07:05:50 GMT", "grpc-status": "0"} }, message: HelloReply { message: "Hello Tonic!" }, extensions: Extensions }

Echo server/client:

Server:

$ bazel run //proto/prost/private/tests/proto/services/echo:server
INFO: Analyzed target //proto/prost/private/tests/proto/services/echo:server (212 packages loaded, 5417 targets configured).
INFO: Found 1 target...
Target //proto/prost/private/tests/proto/services/echo:server up-to-date:
  bazel-bin/proto/prost/private/tests/proto/services/echo/server
INFO: Elapsed time: 18.678s, Critical Path: 0.02s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/proto/prost/private/tests/proto/services/echo/server
EchoServer::server_streaming_echo
        client connected from: Some([::1]:56434)
        client disconnected
EchoServer::bidirectional_streaming_echo
        stream ended
EchoServer::bidirectional_streaming_echo
        client disconnected: broken pipe
        stream ended

Client:

$ bazel run //proto/prost/private/tests/proto/services/echo:client
INFO: Analyzed target //proto/prost/private/tests/proto/services/echo:client (24 packages loaded, 179 targets configured).
INFO: Found 1 target...
Target //proto/prost/private/tests/proto/services/echo:client up-to-date:
  bazel-bin/proto/prost/private/tests/proto/services/echo/client
INFO: Elapsed time: 0.163s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/proto/prost/private/tests/proto/services/echo/client
Streaming echo:
        received: foo
        received: foo
        received: foo
        received: foo
        received: foo

Bidirectional stream echo:
        received message: `msg 01`
        received message: `msg 02`
        received message: `msg 03`
        received message: `msg 04`
        received message: `msg 05`
        received message: `msg 06`
        received message: `msg 07`
        received message: `msg 08`
        received message: `msg 09`
        received message: `msg 10`
        received message: `msg 11`
        received message: `msg 12`
        received message: `msg 13`
        received message: `msg 14`
        received message: `msg 15`
        received message: `msg 16`
        received message: `msg 17`

Bidirectional stream echo (kill client with CTLR+C):
        received message: `msg 01`
        received message: `msg 02`
        received message: `msg 03`
        received message: `msg 04`
        received message: `msg 05`
        received message: `msg 06`
        received message: `msg 07`
        received message: `msg 08`
        received message: `msg 09`
        received message: `msg 10`
        received message: `msg 11`
        received message: `msg 12`
        received message: `msg 13`
        received message: `msg 14`
        received message: `msg 15`

closes #915
closes #478

@freeformstu freeformstu force-pushed the dev/prost-and-tonic branch 2 times, most recently from faf828f to aa14aa4 Compare June 25, 2023 07:25
@freeformstu freeformstu force-pushed the dev/prost-and-tonic branch 2 times, most recently from c799f09 to 61d1586 Compare June 25, 2023 07:47
@freeformstu
Copy link
Contributor Author

@UebelAndre, could you review?

@UebelAndre UebelAndre self-requested a review June 25, 2023 12:32
@UebelAndre UebelAndre changed the title Setup Prost and Tonic rules. Add Prost and Tonic rules. Jun 25, 2023
Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks amazing! You're certainly gonna make a large portion of the rules_rust community very happy. This has been a long desired change.

Just a couple of questions 😄

proto/prost/private/tests/proto/a/BUILD.bazel Outdated Show resolved Hide resolved
proto/prost/private/protoc_wrapper.rs Outdated Show resolved Hide resolved
proto/prost/repositories.bzl Outdated Show resolved Hide resolved
proto/repositories.bzl Show resolved Hide resolved
proto/prost/private/prost.bzl Outdated Show resolved Hide resolved
proto/prost/private/prost.bzl Show resolved Hide resolved
Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also make sure the new rules show up in the rust_proto docs? I think all you'd need to do is update the following
https://github.com/bazelbuild/rules_rust/blob/0.24.1/docs/BUILD.bazel#L115-L125

@UebelAndre
Copy link
Collaborator

As for failing CI, I think it would be fine to bump the min tested Rust and Bazel version for this. As for the failing windows builds, I don't think there's enough info in the error to say what's going on

Error: "IO error: The system cannot find the file specified. (os error 2)"

Copy link
Collaborator

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is super exciting, thanks for putting it together!!

I tried to use it in some of my internal repos, and ran into some issues - curious if you have thoughts on how to solve them. The major issue is around protos which live in separate packages - I just created freeformstu#2 with an example - there are two issues which come up, one is around detecting multiple outputs with the same name, and if you work around that, there are issues where you have multiple lib.rs files which need to live in the same crate in order to be able to import symbols from each other (or which would need to know the crate name of the other crates things depend on to be able to include that in the use statements)...

Ideally we'd have a strategy for how we're going to address these issues before merging (though we don't need to solve them up-front); right now each of these proto_library structures work out of the box exactly as-is for other languages (e.g. Go), and it wouldn't be ideal for people to need to change the strucutre of their proto_library targets in order to add Rust support.

But as I say, super excited to see this progress, I'm looking forward to using this and getting to delete a bunch of hacky cargo_build_script targets!

@freeformstu
Copy link
Contributor Author

Alright, the latest changes fixed all of @illicitonion 's additional test cases.

Everything is passing except for the windows builds which are only failing on a subset of the tests. I am seeing the following error:

ERROR: proto/prost/private/tests/complex_imports/googleapis/google/longrunning/BUILD.bazel:5:14: Compiling Rust rlib longrunning_proto (1 files) failed: (Exit 1): process_wrapper.exe failed: error executing command (from target //proto/prost/private/tests/complex_imports/googleapis/google/longrunning:longrunning_proto) bazel-out\x64_windows-opt-exec-2B5CBBC6\bin\util\process_wrapper\process_wrapper.exe --arg-file ... (remaining 132 arguments skipped)
error: output file bazel-out/x64_windows-fastbuild/bin/proto/prost/private/tests/complex_imports/googleapis/google/longrunning\liblongrunning_proto--1984293944.rmeta is not writeable -- check its permissions   

error: aborting due to previous error

I thought this was an issue with file path length, which it still could be, but I think it might be an issue with any external dependency on windows. All of these tests pass on the other platforms, and most of the tests pass, as long as they're not depending on the Google protobuf definitions.

@UebelAndre & @illicitonion - any ideas about how to fix this last issue? If it is just a file length issue, I could just make those test cases incompatible with WIndows so we can get this merged in.

Copy link
Collaborator

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great, thanks so much for putting it together!

I've tested out switching a complex application to use use these rules instead of existing cargo_build_scripts, and things looked a lot tidier - I've left a few comments to discuss, but generally this is looking really solid to me.

.bazelci/presubmit.yml Show resolved Hide resolved
name = "default_prost_toolchain_impl",
prost_plugin = "//proto/prost/private/3rdparty/crates:protoc-gen-prost__protoc-gen-prost",
prost_plugin_flag = "--plugin=protoc-gen-prost=%s",
prost_runtime = ":prost_runtime",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about providing a default toolchain with a rules_rust-private runtime... When trying this out in some of my private repos, I spent quite a while chasing "X doesn't implement trait Y" issues because of my copy of tonic and prost, despite being the same version numbers, being distinct libraries from the bundled ones, before eventually realising I needed to make and register my own toolchain.

I suspect most of our users will need to specify their own toolchains for this reason, and given how inscrutible the errors are, I'd lean towards documenting this as a required step, and not supplying a default at all...

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, users should just define their own toolchain to avoid any of this confusion. I'll get this deleted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the toolchain into private/BUILD.bazel and stopped automatically registering it in the public proto dependencies macros.

proto/prost/private/3rdparty/BUILD.bazel Show resolved Hide resolved
all_rs_files.insert(path);
}
} else if let Some(name) = path.file_name() {
if name == "_" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When does this happen? Can you add a comment?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, and I double checked that this is absolutely necessary. It shows up specifically when the package name is empty. I have added a comment.

proto/prost/private/protoc_wrapper.rs Show resolved Hide resolved
proto/prost/private/protoc_wrapper.rs Outdated Show resolved Hide resolved
proto/prost/private/protoc_wrapper.rs Outdated Show resolved Hide resolved
proto/prost/private/protoc_wrapper.rs Outdated Show resolved Hide resolved
.bazelci/presubmit.yml Show resolved Hide resolved
all_rs_files.insert(path);
}
} else if let Some(name) = path.file_name() {
if name == "_" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proto/prost/private/prost.bzl Outdated Show resolved Hide resolved
@freeformstu
Copy link
Contributor Author

I removed the bazel remote apis tests because they're causing infra issues. If I keep them added I get windows path length issues. If I depend on the remote execution protos via @bazel_remote_apis, tonic doesn't generate anything.

I am definitely open to reverting my most recent commit to add them back. Open to suggestions!

Copy link
Collaborator

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - I have a couple of comments outstanding, but otherwise this looks great as-is and I'm excited to start using it! Thanks again for the great work!

Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work! Thank you so much for contributing these fantastic rules!

@aaronmondal
Copy link

aaronmondal commented Jul 2, 2023

@illicitonion @freeformstu I believe there is still some issue remaining that you mentioned regarding googleapis and remoteapis. The failed CI runs for 74e5b08 seem to also indicate that this is not just a windows issue. Curiously, I can get client.proto to build fine, but annotations.proto still fails:

rust_prost_library(
    name = "annotations",
    proto = "@googleapis//google/api:annotations_proto",
)
ERROR: /home/aaron/.cache/bazel/_bazel_aaron/36db8dcbcbc6b1f82b5ba98ed0247b3e/external/googleapis/google/api/BUILD.bazel:9:14: TonicGenProto @googleapis//google/api:annotatio
ns_proto failed: (Exit 101): protoc_wrapper failed: error executing command (from target @googleapis//google/api:annotations_proto) 
  (cd /home/aaron/.cache/bazel/_bazel_aaron/36db8dcbcbc6b1f82b5ba98ed0247b3e/sandbox/linux-sandbox/612/execroot/turbo-cache && \
  exec env - \
    PATH=/home/aaron/.cache/bazelisk/downloads/bazelbuild/bazel-6.2.1-linux-x86_64/bin:/home/aaron/.bun/bin:/home/aaron/.bun/bin:/home/aaron/.bun/bin:/home/aaron/.nix-profile
/bin:/nix/var/nix/profiles/default/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/opt/bin:/usr/lib/llvm/16/bin:/home/aaron/Downloads/node/node-v18.16.0-linux-x64/bin:/home/aaro
n/.cargo/bin:/home/aaron/.local/bin:/home/aaron/Downloads/node/node-v18.16.0-linux-x64/bin:/home/aaron/.cargo/bin:/home/aaron/.local/bin:/home/aaron/Downloads/node/node-v18.1
6.0-linux-x64/bin:/home/aaron/.cargo/bin:/home/aaron/.local/bin \
  bazel-out/k8-opt-exec-2B5CBBC6/bin/external/rules_rust/proto/prost/private/protoc_wrapper '--protoc=bazel-out/k8-opt-exec-2B5CBBC6/bin/external/com_google_protobuf/protoc' 
'--label=@googleapis//google/api:annotations_proto' '--out_librs=bazel-out/k8-fastbuild/bin/external/googleapis/google/api/annotations_proto.lib.tonic.rs' '--package_info_out
put=annotations_proto=bazel-out/k8-fastbuild/bin/external/googleapis/google/api/annotations_proto.tonic_package_info' '--deps_info=bazel-out/k8-fastbuild/bin/external/googlea
pis/google/api/annotations_proto.tonic_deps_info' '--prost_opt=compile_well_known_types' '--descriptor_set=bazel-out/k8-fastbuild/bin/external/googleapis/google/api/annotatio
ns_proto-descriptor-set.proto.bin' '--plugin=protoc-gen-tonic=bazel-out/k8-opt-exec-2B5CBBC6/bin/external/crate_index__protoc-gen-tonic-0.2.2/protoc-gen-tonic__bin' '--tonic_
opt=no_include' '--tonic_opt=compile_well_known_types' --is_tonic '--rustfmt=external/rustfmt_nightly-2023-06-01__x86_64-unknown-linux-gnu_tools/bin/rustfmt' '--prost_out=baz
el-out/k8-fastbuild/bin' '--plugin=protoc-gen-prost=bazel-out/k8-opt-exec-2B5CBBC6/bin/external/crate_index__protoc-gen-prost-0.2.2/protoc-gen-prost__bin' '--proto_path=exter
nal/googleapis' '--proto_path=bazel-out/k8-fastbuild/bin/external/com_google_protobuf/_virtual_imports/descriptor_proto' '-Igoogle/api/annotations.proto=external/googleapis/g
oogle/api/annotations.proto' '-Igoogle/api/http.proto=external/googleapis/google/api/http.proto' '-Igoogle/protobuf/descriptor.proto=bazel-out/k8-fastbuild/bin/external/com_g
oogle_protobuf/_virtual_imports/descriptor_proto/google/protobuf/descriptor.proto' external/googleapis/google/api/annotations.proto)
# Configuration: ca63adb307a1bd0f693440015ddae19ec8302707b6d51da41eab328714b1af2a
# Execution platform: @local_config_platform//:host

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
thread 'main' panicked at 'No .rs files were generated by prost.', external/rules_rust/proto/prost/private/protoc_wrapper.rs:724:9

@UebelAndre
Copy link
Collaborator

@illicitonion @freeformstu I believe there is still some issue remaining that you mentioned regarding googleapis and remoteapis.

Thanks for finding this! I think it should be tracked in a separate issue though. I opened #2046

Silcet pushed a commit to Silcet/rules_rust that referenced this pull request Jul 10, 2023
* Setup Prost and Tonic rules.

* Regenerate documentation

* Add more tests.

* Add more tests and address feedback.

* Regenerate documentation

* Add to proto docs page.

* Bump min supported bazel version.

* buildifier

* Always enable backtracing.

* Add more info to failing rename.

* Set min rust version to 1.62.0

* Handle rust keywords as package names.

* exclude windows from prost toolchain support.

* buildifier

* redundant

* Use prost-types to parse the file descriptor set.

* Cleanup and more tests.

* Move prost-types to toolchain definition.

* fix rustfmt

* Add example of building protos with complex imports

* impl Display

* Fix all tests

* Add rust checks for the complex import protos.

* Address feedback

* Fix buildifier

* Depend on remote-apis repo.

* Remove bazel remote apis due to file length and transitive dependency issues.

* Update patch and docs.

* Regenerate documentation

* Regenerate documentation

* Update docs.

---------

Co-authored-by: Daniel Wagner-Hall <dwagnerhall@apple.com>
Silcet pushed a commit to Silcet/rules_rust that referenced this pull request Jul 10, 2023
* Setup Prost and Tonic rules.

* Regenerate documentation

* Add more tests.

* Add more tests and address feedback.

* Regenerate documentation

* Add to proto docs page.

* Bump min supported bazel version.

* buildifier

* Always enable backtracing.

* Add more info to failing rename.

* Set min rust version to 1.62.0

* Handle rust keywords as package names.

* exclude windows from prost toolchain support.

* buildifier

* redundant

* Use prost-types to parse the file descriptor set.

* Cleanup and more tests.

* Move prost-types to toolchain definition.

* fix rustfmt

* Add example of building protos with complex imports

* impl Display

* Fix all tests

* Add rust checks for the complex import protos.

* Address feedback

* Fix buildifier

* Depend on remote-apis repo.

* Remove bazel remote apis due to file length and transitive dependency issues.

* Update patch and docs.

* Regenerate documentation

* Regenerate documentation

* Update docs.

---------

Co-authored-by: Daniel Wagner-Hall <dwagnerhall@apple.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FR: Add tonic/prost rules Protobuf rules using Tonic
4 participants