From fab0182f86d885209b98e25c35fd99f6253868c0 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Mon, 15 Jul 2024 16:57:48 +0200 Subject: [PATCH] Commit generated code without requiring protoc for crate consumers --- Cargo.toml | 2 - build.rs | 10 - .../generated/dev.restate.service.protocol.rs | 545 ++++++++++++++++++ src/service_protocol/messages.rs | 2 +- tests/bootstrap.rs | 34 ++ 5 files changed, 580 insertions(+), 13 deletions(-) delete mode 100644 build.rs create mode 100644 src/service_protocol/generated/dev.restate.service.protocol.rs create mode 100644 tests/bootstrap.rs diff --git a/Cargo.toml b/Cargo.toml index 2c7143d..b015a26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,4 @@ sha2 = "0.11.0-pre.3" googletest = "0.11.0" test-log = { version = "0.2.16", default-features = false, features = ["trace", "color"] } assert2 = "0.3.14" - -[build-dependencies] prost-build = "0.13" \ No newline at end of file diff --git a/build.rs b/build.rs deleted file mode 100644 index 37097f9..0000000 --- a/build.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() -> std::io::Result<()> { - prost_build::Config::new() - .bytes(["."]) - .protoc_arg("--experimental_allow_proto3_optional") - .compile_protos( - &["service-protocol/dev/restate/service/protocol.proto"], - &["service-protocol"], - )?; - Ok(()) -} diff --git a/src/service_protocol/generated/dev.restate.service.protocol.rs b/src/service_protocol/generated/dev.restate.service.protocol.rs new file mode 100644 index 0000000..5f4960f --- /dev/null +++ b/src/service_protocol/generated/dev.restate.service.protocol.rs @@ -0,0 +1,545 @@ +// This file is @generated by prost-build. +/// Type: 0x0000 + 0 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StartMessage { + /// Unique id of the invocation. This id is unique across invocations and won't change when replaying the journal. + #[prost(bytes = "bytes", tag = "1")] + pub id: ::prost::bytes::Bytes, + /// Invocation id that can be used for logging. + /// The user can use this id to address this invocation in admin and status introspection apis. + #[prost(string, tag = "2")] + pub debug_id: ::prost::alloc::string::String, + #[prost(uint32, tag = "3")] + pub known_entries: u32, + /// protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED + #[prost(message, repeated, tag = "4")] + pub state_map: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "5")] + pub partial_state: bool, + /// If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + #[prost(string, tag = "6")] + pub key: ::prost::alloc::string::String, +} +/// Nested message and enum types in `StartMessage`. +pub mod start_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct StateEntry { + #[prost(bytes = "bytes", tag = "1")] + pub key: ::prost::bytes::Bytes, + /// If value is an empty byte array, + /// then it means the value is empty and not "missing" (e.g. empty string). + #[prost(bytes = "bytes", tag = "2")] + pub value: ::prost::bytes::Bytes, + } +} +/// Type: 0x0000 + 1 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CompletionMessage { + #[prost(uint32, tag = "1")] + pub entry_index: u32, + #[prost(oneof = "completion_message::Result", tags = "13, 14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `CompletionMessage`. +pub mod completion_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(message, tag = "13")] + Empty(super::Empty), + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Type: 0x0000 + 2 +/// Implementations MUST send this message when suspending an invocation. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SuspensionMessage { + /// This list represents any of the entry_index the invocation is waiting on to progress. + /// The runtime will resume the invocation as soon as one of the given entry_index is completed. + /// This list MUST not be empty. + /// False positive, entry_indexes is a valid plural of entry_indices. + /// + /// + /// protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED + #[prost(uint32, repeated, tag = "1")] + pub entry_indexes: ::prost::alloc::vec::Vec, +} +/// Type: 0x0000 + 3 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ErrorMessage { + /// The code can be any HTTP status code, as described + /// In addition, we define the following error codes that MAY be used by the SDK for better error reporting: + /// * JOURNAL_MISMATCH = 570, that is when the SDK cannot replay a journal due to the mismatch between the journal and the actual code. + /// * PROTOCOL_VIOLATION = 571, that is when the SDK receives an unexpected message or an expected message variant, given its state. + #[prost(uint32, tag = "1")] + pub code: u32, + /// Contains a concise error message, e.g. Throwable#getMessage() in Java. + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, + /// Contains a verbose error description, e.g. the exception stacktrace. + #[prost(string, tag = "3")] + pub description: ::prost::alloc::string::String, + /// Entry that caused the failure. This may be outside the current stored journal size. + /// If no specific entry caused the failure, the current replayed/processed entry can be used. + #[prost(uint32, optional, tag = "4")] + pub related_entry_index: ::core::option::Option, + /// Name of the entry that caused the failure. + #[prost(string, optional, tag = "5")] + pub related_entry_name: ::core::option::Option<::prost::alloc::string::String>, + /// Entry type. + #[prost(uint32, optional, tag = "6")] + pub related_entry_type: ::core::option::Option, +} +/// Type: 0x0000 + 4 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct EntryAckMessage { + #[prost(uint32, tag = "1")] + pub entry_index: u32, +} +/// Type: 0x0000 + 5 +/// Implementations MUST send this message when the invocation lifecycle ends. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct EndMessage {} +/// Completable: No +/// Fallible: No +/// Type: 0x0400 + 0 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InputEntryMessage { + #[prost(message, repeated, tag = "1")] + pub headers: ::prost::alloc::vec::Vec
, + #[prost(bytes = "bytes", tag = "14")] + pub value: ::prost::bytes::Bytes, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, +} +/// Completable: No +/// Fallible: No +/// Type: 0x0400 + 1 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OutputEntryMessage { + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "output_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `OutputEntryMessage`. +pub mod output_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0800 + 0 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetStateEntryMessage { + #[prost(bytes = "bytes", tag = "1")] + pub key: ::prost::bytes::Bytes, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "get_state_entry_message::Result", tags = "13, 14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `GetStateEntryMessage`. +pub mod get_state_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(message, tag = "13")] + Empty(super::Empty), + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: No +/// Fallible: No +/// Type: 0x0800 + 1 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetStateEntryMessage { + #[prost(bytes = "bytes", tag = "1")] + pub key: ::prost::bytes::Bytes, + #[prost(bytes = "bytes", tag = "3")] + pub value: ::prost::bytes::Bytes, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, +} +/// Completable: No +/// Fallible: No +/// Type: 0x0800 + 2 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClearStateEntryMessage { + #[prost(bytes = "bytes", tag = "1")] + pub key: ::prost::bytes::Bytes, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, +} +/// Completable: No +/// Fallible: No +/// Type: 0x0800 + 3 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClearAllStateEntryMessage { + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0800 + 4 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetStateKeysEntryMessage { + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "get_state_keys_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `GetStateKeysEntryMessage`. +pub mod get_state_keys_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct StateKeys { + #[prost(bytes = "bytes", repeated, tag = "1")] + pub keys: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(message, tag = "14")] + Value(StateKeys), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0800 + 8 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetPromiseEntryMessage { + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "get_promise_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `GetPromiseEntryMessage`. +pub mod get_promise_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0800 + 9 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PeekPromiseEntryMessage { + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "peek_promise_entry_message::Result", tags = "13, 14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `PeekPromiseEntryMessage`. +pub mod peek_promise_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(message, tag = "13")] + Empty(super::Empty), + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0800 + A +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CompletePromiseEntryMessage { + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + /// The value to use to complete the promise + #[prost(oneof = "complete_promise_entry_message::Completion", tags = "2, 3")] + pub completion: ::core::option::Option, + #[prost(oneof = "complete_promise_entry_message::Result", tags = "13, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `CompletePromiseEntryMessage`. +pub mod complete_promise_entry_message { + /// The value to use to complete the promise + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Completion { + #[prost(bytes, tag = "2")] + CompletionValue(::prost::bytes::Bytes), + #[prost(message, tag = "3")] + CompletionFailure(super::Failure), + } + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + /// Returns empty if value was set successfully + #[prost(message, tag = "13")] + Empty(super::Empty), + /// Returns a failure if the promise was already completed + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0C00 + 0 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SleepEntryMessage { + /// Wake up time. + /// The time is set as duration since UNIX Epoch. + #[prost(uint64, tag = "1")] + pub wake_up_time: u64, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "sleep_entry_message::Result", tags = "13, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `SleepEntryMessage`. +pub mod sleep_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(message, tag = "13")] + Empty(super::Empty), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: Yes +/// Fallible: Yes +/// Type: 0x0C00 + 1 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CallEntryMessage { + #[prost(string, tag = "1")] + pub service_name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub handler_name: ::prost::alloc::string::String, + #[prost(bytes = "bytes", tag = "3")] + pub parameter: ::prost::bytes::Bytes, + #[prost(message, repeated, tag = "4")] + pub headers: ::prost::alloc::vec::Vec
, + /// If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + #[prost(string, tag = "5")] + pub key: ::prost::alloc::string::String, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "call_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `CallEntryMessage`. +pub mod call_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: No +/// Fallible: Yes +/// Type: 0x0C00 + 2 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OneWayCallEntryMessage { + #[prost(string, tag = "1")] + pub service_name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub handler_name: ::prost::alloc::string::String, + #[prost(bytes = "bytes", tag = "3")] + pub parameter: ::prost::bytes::Bytes, + /// Time when this BackgroundInvoke should be executed. + /// The time is set as duration since UNIX Epoch. + /// If this value is not set, equal to 0, or past in time, + /// the runtime will execute this BackgroundInvoke as soon as possible. + #[prost(uint64, tag = "4")] + pub invoke_time: u64, + #[prost(message, repeated, tag = "5")] + pub headers: ::prost::alloc::vec::Vec
, + /// If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + #[prost(string, tag = "6")] + pub key: ::prost::alloc::string::String, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, +} +/// Completable: Yes +/// Fallible: No +/// Type: 0x0C00 + 3 +/// Awakeables are addressed by an identifier exposed to the user. See the spec for more details. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AwakeableEntryMessage { + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "awakeable_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `AwakeableEntryMessage`. +pub mod awakeable_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: No +/// Fallible: Yes +/// Type: 0x0C00 + 4 +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CompleteAwakeableEntryMessage { + /// Identifier of the awakeable. See the spec for more details. + #[prost(string, tag = "1")] + pub id: ::prost::alloc::string::String, + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "complete_awakeable_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `CompleteAwakeableEntryMessage`. +pub mod complete_awakeable_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// Completable: No +/// Fallible: No +/// Type: 0x0C00 + 5 +/// Flag: RequiresRuntimeAck +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RunEntryMessage { + /// Entry name + #[prost(string, tag = "12")] + pub name: ::prost::alloc::string::String, + #[prost(oneof = "run_entry_message::Result", tags = "14, 15")] + pub result: ::core::option::Option, +} +/// Nested message and enum types in `RunEntryMessage`. +pub mod run_entry_message { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Result { + #[prost(bytes, tag = "14")] + Value(::prost::bytes::Bytes), + #[prost(message, tag = "15")] + Failure(super::Failure), + } +} +/// This failure object carries user visible errors, +/// e.g. invocation failure return value or failure result of an InvokeEntryMessage. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Failure { + /// The code can be any HTTP status code, as described + #[prost(uint32, tag = "1")] + pub code: u32, + /// Contains a concise error message, e.g. Throwable#getMessage() in Java. + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Header { + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub value: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct Empty {} +/// Service protocol version. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ServiceProtocolVersion { + Unspecified = 0, + /// initial service protocol version + V1 = 1, +} +impl ServiceProtocolVersion { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + ServiceProtocolVersion::Unspecified => "SERVICE_PROTOCOL_VERSION_UNSPECIFIED", + ServiceProtocolVersion::V1 => "V1", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SERVICE_PROTOCOL_VERSION_UNSPECIFIED" => Some(Self::Unspecified), + "V1" => Some(Self::V1), + _ => None, + } + } +} diff --git a/src/service_protocol/messages.rs b/src/service_protocol/messages.rs index 0eccb23..1c622f6 100644 --- a/src/service_protocol/messages.rs +++ b/src/service_protocol/messages.rs @@ -36,7 +36,7 @@ impl WriteableRestateMessage for M { } } -include!(concat!(env!("OUT_DIR"), "/dev.restate.service.protocol.rs")); +include!("./generated/dev.restate.service.protocol.rs"); macro_rules! impl_message_traits { ($name:ident: core) => { diff --git a/tests/bootstrap.rs b/tests/bootstrap.rs new file mode 100644 index 0000000..5b15d16 --- /dev/null +++ b/tests/bootstrap.rs @@ -0,0 +1,34 @@ +// Thanks! https://github.com/tokio-rs/console/blob/5f6faa22d944735c2b8c312cac03b35a4ab228ef/console-api/tests/bootstrap.rs +// MIT License + +use std::{path::PathBuf, process::Command}; + +#[test] +fn bootstrap() { + let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let out_dir = root_dir.join("src/service_protocol/generated"); + + if let Err(error) = prost_build::Config::new() + .bytes(["."]) + .protoc_arg("--experimental_allow_proto3_optional") + .out_dir(out_dir.clone()) + .compile_protos( + &[root_dir.join("service-protocol/dev/restate/service/protocol.proto")], + &[root_dir.join("service-protocol")], + ) + { + panic!("failed to compile `console-api` protobuf: {}", error); + } + + let status = Command::new("git") + .arg("diff") + .arg("--exit-code") + .arg("--") + .arg(out_dir) + .status(); + match status { + Ok(status) if !status.success() => panic!("You should commit the protobuf files"), + Err(error) => panic!("failed to run `git diff`: {}", error), + Ok(_) => {} + } +}