fdeantoni / prost-wkt

Prost Well-Known-Types serialization and deserialization.
Apache License 2.0
76 stars 35 forks source link

Appears to break with Prost 0.10 #17

Closed wagenet closed 2 years ago

wagenet commented 2 years ago

Where things worked with Prost 0.9, they now fail with 0.10.

error: failed to run custom build command for `my-package v0.1.0 (PATH/my-package)`

Caused by:
  process didn't exit successfully: `PATH/target/debug/build/my-package-509801f93119b765/build-script-build` (exit status: 101)

  --- stderr
  thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', /Users/peterwagenet/.cargo/registry/src/github.com-1ecc6299db9ec823/prost-wkt-build-0.3.0/src/lib.rs:18:77
  stack backtrace:
     0: rust_begin_unwind
               at /rustc/99f967e7ed97803517e5fad18d27698cab977808/library/std/src/panicking.rs:584:5
     1: core::panicking::panic_fmt
               at /rustc/99f967e7ed97803517e5fad18d27698cab977808/library/core/src/panicking.rs:143:14
     2: core::result::unwrap_failed
               at /rustc/99f967e7ed97803517e5fad18d27698cab977808/library/core/src/result.rs:1749:5
     3: core::result::Result<T,E>::unwrap
               at /rustc/99f967e7ed97803517e5fad18d27698cab977808/library/core/src/result.rs:1065:23
     4: prost_wkt_build::add_serde
               at /Users/peterwagenet/.cargo/registry/src/github.com-1ecc6299db9ec823/prost-wkt-build-0.3.0/src/lib.rs:18:29
     5: build_script_build::main
               at ./build.rs:43:5
     6: core::ops::function::FnOnce::call_once
               at /rustc/99f967e7ed97803517e5fad18d27698cab977808/library/core/src/ops/function.rs:227:5
  note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
warning: build failed, waiting for other jobs to finish...
error: build failed

build.rs:

use prost_wkt_build::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let out_dir = std::path::Path::new("proto/generated");

    if out_dir.exists() {
        remove_dir_all::remove_dir_all(out_dir)?;
    }

    std::fs::create_dir_all(out_dir)?;

    let descriptor_file = out_dir.join("my-proto_descriptor.bin");

    tonic_build::configure()
        .out_dir(out_dir)
        .build_server(true)
        .type_attribute(".", "#[derive(::serde::Serialize,::serde::Deserialize)]")
        .extern_path(".google.protobuf.Any", "::prost_wkt_types::Any")
        .extern_path(".google.protobuf.Timestamp", "::prost_wkt_types::Timestamp")
        .extern_path(".google.protobuf.Value", "::prost_wkt_types::Value")
        .file_descriptor_set_path(&descriptor_file)
        .compile(
            &["proto/my-proto.proto"],
        )?;

    let descriptor_bytes = std::fs::read(descriptor_file).unwrap();

    let descriptor = FileDescriptorSet::decode(&descriptor_bytes[..]).unwrap();

    prost_wkt_build::add_serde(out_dir.to_path_buf(), descriptor);

    Ok(())
}
bjchambers commented 2 years ago

I'm running into this too. It looks like the panic is in trying to write to the file for google.protobuf. Specifically, within the add_serde call, there is this, which panics because the rust_path does not exist for the file `.

pub fn add_serde(out: PathBuf, descriptor: FileDescriptorSet) {
    for fd in &descriptor.file {
        let package_name = match fd.package {
            Some(ref pkg) => pkg,
            None => continue,
        };

        let rust_path = out.join(format!("{}.rs", package_name));
        let mut rust_file = OpenOptions::new().append(true).open(rust_path).unwrap();

        ...
    }
}

I added the following to my build.rs to see what the descriptor contained and compared to the contents of my output directory. It showed that the descriptor had:

    for fd in &descriptor.file {
        let package_name = match fd.package {
            Some(ref pkg) => pkg,
            None => continue,
        };

        let messages: Vec<_> = fd.message_type.iter().map(|m| m.name()).collect();
        println!("Rust Path: {:?}: {:?}", package_name, messages);
    }

    prost_wkt_build::add_serde(out_dir, descriptor);

It showed the decscriptor contained these entries for google.protobuf, but there is no google.protobuf.rs:

  Rust Path: "google.protobuf": ["Empty"]
  Rust Path: "google.protobuf": ["Timestamp"]
  Rust Path: "google.protobuf": ["DoubleValue", "FloatValue", "Int64Value", "UInt64Value", "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue"]
bjchambers commented 2 years ago

Also, FWIW confirmed that upgrading the Cargo.toml in this crate and the example to prost 0.10 causes the same failures.