diff --git a/rust/BUILD b/rust/BUILD index 5754ef3a85..8b6bb61b89 100644 --- a/rust/BUILD +++ b/rust/BUILD @@ -294,11 +294,45 @@ pkg_zip( ], ) +pkg_files( + name = "protobuf_codegen_files", + srcs = glob(["protobuf_codegen/src/*"]) + ["protobuf_codegen/Cargo.toml"], + strip_prefix = strip_prefix.from_root("rust/protobuf_codegen"), +) + +pkg_zip( + name = "codegen_crate", + srcs = [ + ":protobuf_codegen_files", + "//:LICENSE", + ], + visibility = ["//rust:__pkg__"], +) + +pkg_files( + name = "codegen_example_files", + srcs = glob(["protobuf_codegen/example/**/*"]), + strip_prefix = strip_prefix.from_root("rust/protobuf_codegen/example"), +) + +pkg_zip( + name = "codegen_example", + srcs = [ + ":codegen_example_files", + "//:LICENSE", + ], + visibility = ["//rust:__pkg__"], +) + sh_binary( name = "cargo_test", srcs = ["cargo_test.sh"], data = [ + ":codegen_crate", + ":codegen_example", ":rust_crate", + "//:protoc", + "//upb_generator/minitable:protoc-gen-upb_minitable", ], deps = ["@bazel_tools//tools/bash/runfiles"], ) diff --git a/rust/cargo_test.sh b/rust/cargo_test.sh index d9a9ce949d..46460c9b3f 100755 --- a/rust/cargo_test.sh +++ b/rust/cargo_test.sh @@ -35,10 +35,33 @@ mkdir $CARGO_HOME CRATE_ROOT=$TMP_DIR/protobuf mkdir $CRATE_ROOT -CRATE_ZIP=$(rlocation com_google_protobuf/rust/rust_crate.zip) +PROTOBUF_ZIP=$(rlocation com_google_protobuf/rust/rust_crate.zip) -unzip -d $CRATE_ROOT $CRATE_ZIP -cd $CRATE_ROOT +unzip -d $CRATE_ROOT $PROTOBUF_ZIP + +CODEGEN_ROOT=$TMP_DIR/protobuf_codegen +mkdir $CODEGEN_ROOT + +CODEGEN_ZIP=$(rlocation com_google_protobuf/rust/codegen_crate.zip) + +unzip -d $CODEGEN_ROOT $CODEGEN_ZIP + +EXAMPLE_ROOT=$TMP_DIR/codegen_example +mkdir $EXAMPLE_ROOT + +EXAMPLE_ZIP=$(rlocation com_google_protobuf/rust/codegen_example.zip) +unzip -d $EXAMPLE_ROOT $EXAMPLE_ZIP + +cd $CRATE_ROOT # Run all tests except doctests CARGO_HOME=$CARGO_HOME cargo test --lib --bins --tests + +cd $CODEGEN_ROOT +CARGO_HOME=$CARGO_HOME cargo test --lib --bins --tests + +PROTOC=$(rlocation com_google_protobuf/protoc) +PROTOC_GEN_UPB_MINITABLE=$(rlocation com_google_protobuf/upb_generator/minitable/protoc-gen-upb_minitable) + +cd $EXAMPLE_ROOT +CARGO_HOME=$CARGO_HOME PROTOC=$PROTOC PROTOC_GEN_UPB_MINITABLE=$PROTOC_GEN_UPB_MINITABLE cargo test diff --git a/rust/protobuf_codegen/example/Cargo.toml b/rust/protobuf_codegen/example/Cargo.toml new file mode 100644 index 0000000000..e95d55900d --- /dev/null +++ b/rust/protobuf_codegen/example/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "protobuf-codegen-example" +version = "0.1.0" +edition = "2021" + +[dependencies] +protobuf = { path = "../protobuf" } + +[build-dependencies] +protobuf-codegen = { path = "../protobuf_codegen" } \ No newline at end of file diff --git a/rust/protobuf_codegen/example/build.rs b/rust/protobuf_codegen/example/build.rs new file mode 100644 index 0000000000..4b80e1e8af --- /dev/null +++ b/rust/protobuf_codegen/example/build.rs @@ -0,0 +1,14 @@ +use protobuf_codegen::CodeGen; +use std::env; + +fn main() { + let mut codegen = CodeGen::new(); + codegen + .protoc_path(env::var("PROTOC").expect("PROTOC should be set to the path to protoc")) + .protoc_gen_upb_minitable_path(env::var("PROTOC_GEN_UPB_MINITABLE").expect( + "PROTOC_GEN_UPB_MINITABLE should be set to the path to protoc-gen-upb_minitable", + )) + .inputs(["foo.proto", "bar/bar.proto"]) + .include("proto"); + codegen.compile().unwrap(); +} diff --git a/rust/protobuf_codegen/example/proto/bar/bar.proto b/rust/protobuf_codegen/example/proto/bar/bar.proto new file mode 100644 index 0000000000..463e07a437 --- /dev/null +++ b/rust/protobuf_codegen/example/proto/bar/bar.proto @@ -0,0 +1,9 @@ +edition = "2023"; + +package proto_example; + +message Bar { + int32 int = 1; + repeated int32 numbers = 2; + string name = 3; +} diff --git a/rust/protobuf_codegen/example/proto/foo.proto b/rust/protobuf_codegen/example/proto/foo.proto new file mode 100644 index 0000000000..92bc3952f9 --- /dev/null +++ b/rust/protobuf_codegen/example/proto/foo.proto @@ -0,0 +1,12 @@ +edition = "2023"; + +package proto_example; + +import "bar/bar.proto"; + +message Foo { + int32 int = 1; + repeated int32 numbers = 2; + string name = 3; + Bar bar = 4; +} diff --git a/rust/protobuf_codegen/example/src/main.rs b/rust/protobuf_codegen/example/src/main.rs new file mode 100644 index 0000000000..4b82be6abc --- /dev/null +++ b/rust/protobuf_codegen/example/src/main.rs @@ -0,0 +1,33 @@ +#[path = "protos/foo.u.pb.rs"] +mod protos; + +use protobuf::proto; + +use protos::Foo; + +fn main() { + let foo = proto!(Foo { name: "foo", bar: __ { name: "bar" } }); + dbg!(foo); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn set_strings() { + let foo = proto!(Foo { name: "foo", bar: __ { name: "bar" } }); + + assert_eq!(foo.name(), "foo"); + assert_eq!(foo.bar().name(), "bar"); + } + + #[test] + fn set_ints() { + let foo = proto!(Foo { int: 42, bar: __ { numbers: [1, 2, 3] } }); + + assert_eq!(foo.int(), 42); + let nums: Vec<_> = foo.bar().numbers().iter().collect(); + assert_eq!(nums, vec![1, 2, 3]); + } +} diff --git a/rust/protobuf_codegen/src/lib.rs b/rust/protobuf_codegen/src/lib.rs index 1c64efd82d..db2998a0e3 100644 --- a/rust/protobuf_codegen/src/lib.rs +++ b/rust/protobuf_codegen/src/lib.rs @@ -1,5 +1,5 @@ use std::fs::{self, OpenOptions}; -use std::io::{self, prelude::*}; +use std::io::prelude::*; use std::path::{Path, PathBuf}; use walkdir::WalkDir; @@ -84,6 +84,10 @@ impl CodeGen { for input in &self.inputs { cmd.arg(input); } + if !self.output_dir.exists() { + // Attempt to make the directory if it doesn't exist + let _ = std::fs::create_dir(&self.output_dir); + } cmd.arg(format!("--rust_out={}", self.output_dir.display())) .arg("--rust_opt=experimental-codegen=enabled,kernel=upb") .arg(format!("--plugin=protoc-gen-upb={}", self.protoc_gen_upb_path.display())) @@ -91,8 +95,7 @@ impl CodeGen { "--plugin=protoc-gen-upb_minitable={}", self.protoc_gen_upb_minitable_path.display() )) - .arg(format!("--upb_minitable_out={}", self.output_dir.display())) - .arg(format!("--upb_out={}", self.output_dir.display())); + .arg(format!("--upb_minitable_out={}", self.output_dir.display())); for include in &self.includes { cmd.arg(format!("--proto_path={}", include.display())); } diff --git a/upb_generator/minitable/BUILD b/upb_generator/minitable/BUILD index b1b05b97ba..a5eadfed93 100644 --- a/upb_generator/minitable/BUILD +++ b/upb_generator/minitable/BUILD @@ -93,6 +93,7 @@ bootstrap_cc_binary( visibility = [ "//editions/codegen_tests:__pkg__", "//net/proto2/contrib/protoc_explorer:__pkg__", + "//rust:__pkg__", "//third_party/prototiller/transformer:__pkg__", ], )