From f64bd55a3381f4537554714fd491969f9fb3e4e3 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 5 Jul 2021 15:33:39 +0800 Subject: [PATCH] auto generate crate protobuf file and model --- .../flowy-protobuf/src/protobuf/model/mod.rs | 0 rust-lib/flowy-user/src/protobuf/model/mod.rs | 3 + .../flowy-user/src/protobuf/model/user.rs | 295 ++++++++++++++++++ .../flowy-user/src/protobuf/proto/user.proto | 7 + scripts/flowy-tool/Cargo.toml | 1 + scripts/flowy-tool/src/main.rs | 13 +- scripts/flowy-tool/src/proto/ast.rs | 18 +- scripts/flowy-tool/src/proto/builder.rs | 56 ++++ scripts/flowy-tool/src/proto/helper.rs | 98 ++++-- scripts/flowy-tool/src/proto/mod.rs | 2 + scripts/flowy-tool/src/proto/proto_gen.rs | 219 +++++-------- .../template/build_cache/derive_cache.rs | 33 -- .../src/proto/template/build_cache/mod.rs | 3 - .../proto/template/derive_meta/derive_meta.rs | 77 +++++ .../derive_meta.tera} | 0 .../src/proto/template/derive_meta/mod.rs | 3 + scripts/flowy-tool/src/proto/template/mod.rs | 4 +- scripts/makefile/protobuf.toml | 23 +- 18 files changed, 625 insertions(+), 230 deletions(-) create mode 100644 rust-lib/flowy-protobuf/src/protobuf/model/mod.rs create mode 100644 rust-lib/flowy-user/src/protobuf/model/mod.rs create mode 100644 rust-lib/flowy-user/src/protobuf/model/user.rs create mode 100644 rust-lib/flowy-user/src/protobuf/proto/user.proto create mode 100644 scripts/flowy-tool/src/proto/builder.rs delete mode 100644 scripts/flowy-tool/src/proto/template/build_cache/derive_cache.rs delete mode 100644 scripts/flowy-tool/src/proto/template/build_cache/mod.rs create mode 100644 scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs rename scripts/flowy-tool/src/proto/template/{build_cache/derive_cache.tera => derive_meta/derive_meta.tera} (100%) create mode 100644 scripts/flowy-tool/src/proto/template/derive_meta/mod.rs diff --git a/rust-lib/flowy-protobuf/src/protobuf/model/mod.rs b/rust-lib/flowy-protobuf/src/protobuf/model/mod.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rust-lib/flowy-user/src/protobuf/model/mod.rs b/rust-lib/flowy-user/src/protobuf/model/mod.rs new file mode 100644 index 0000000000..887ff36376 --- /dev/null +++ b/rust-lib/flowy-user/src/protobuf/model/mod.rs @@ -0,0 +1,3 @@ + +mod user; +pub use user::*; diff --git a/rust-lib/flowy-user/src/protobuf/model/user.rs b/rust-lib/flowy-user/src/protobuf/model/user.rs new file mode 100644 index 0000000000..e2fda8ffff --- /dev/null +++ b/rust-lib/flowy-user/src/protobuf/model/user.rs @@ -0,0 +1,295 @@ +// This file is generated by rust-protobuf 2.22.1. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `user.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1; + +#[derive(PartialEq,Clone,Default)] +pub struct App { + // message fields + pub id: ::std::string::String, + pub workspace_id: ::std::string::String, + pub name: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a App { + fn default() -> &'a App { + ::default_instance() + } +} + +impl App { + pub fn new() -> App { + ::std::default::Default::default() + } + + // string id = 1; + + + pub fn get_id(&self) -> &str { + &self.id + } + pub fn clear_id(&mut self) { + self.id.clear(); + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: ::std::string::String) { + self.id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_id(&mut self) -> &mut ::std::string::String { + &mut self.id + } + + // Take field + pub fn take_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.id, ::std::string::String::new()) + } + + // string workspace_id = 2; + + + pub fn get_workspace_id(&self) -> &str { + &self.workspace_id + } + pub fn clear_workspace_id(&mut self) { + self.workspace_id.clear(); + } + + // Param is passed by value, moved + pub fn set_workspace_id(&mut self, v: ::std::string::String) { + self.workspace_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_workspace_id(&mut self) -> &mut ::std::string::String { + &mut self.workspace_id + } + + // Take field + pub fn take_workspace_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.workspace_id, ::std::string::String::new()) + } + + // string name = 3; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for App { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.workspace_id)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.id); + } + if !self.workspace_id.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.workspace_id); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.name); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.id.is_empty() { + os.write_string(1, &self.id)?; + } + if !self.workspace_id.is_empty() { + os.write_string(2, &self.workspace_id)?; + } + if !self.name.is_empty() { + os.write_string(3, &self.name)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> App { + App::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "id", + |m: &App| { &m.id }, + |m: &mut App| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "workspace_id", + |m: &App| { &m.workspace_id }, + |m: &mut App| { &mut m.workspace_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &App| { &m.name }, + |m: &mut App| { &mut m.name }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "App", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static App { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(App::new) + } +} + +impl ::protobuf::Clear for App { + fn clear(&mut self) { + self.id.clear(); + self.workspace_id.clear(); + self.name.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for App { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for App { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\nuser.proto\"L\n\x03App\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\ + !\n\x0cworkspace_id\x18\x02\x20\x01(\tR\x0bworkspaceId\x12\x12\n\x04name\ + \x18\x03\x20\x01(\tR\x04nameJ\xcf\x01\n\x06\x12\x04\0\0\x06\x01\n\x08\n\ + \x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x06\x01\n\n\n\x03\ + \x04\0\x01\x12\x03\x02\x08\x0b\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\ + \x12\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\ + \0\x01\x12\x03\x03\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\ + \n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x1c\n\x0c\n\x05\x04\0\x02\x01\ + \x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x17\ + \n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x1a\x1b\n\x0b\n\x04\x04\0\x02\ + \x02\x12\x03\x05\x04\x14\n\x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\n\ + \n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\ + \x02\x03\x12\x03\x05\x12\x13b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/rust-lib/flowy-user/src/protobuf/proto/user.proto b/rust-lib/flowy-user/src/protobuf/proto/user.proto new file mode 100644 index 0000000000..161baa2f05 --- /dev/null +++ b/rust-lib/flowy-user/src/protobuf/proto/user.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message App { + string id = 1; + string workspace_id = 2; + string name = 3; +} diff --git a/scripts/flowy-tool/Cargo.toml b/scripts/flowy-tool/Cargo.toml index 64999206bd..6942f63a28 100644 --- a/scripts/flowy-tool/Cargo.toml +++ b/scripts/flowy-tool/Cargo.toml @@ -13,6 +13,7 @@ tera = { version = "1.5.0" } log = "0.4.11" env_logger = "0.8.2" shell = { git="https://github.com/google/rust-shell.git"} +cmd_lib = "1.1" flowy-ast = { path = "../../rust-lib/flowy-ast" } console = "0.14.0" fancy-regex = "0.5.0" diff --git a/scripts/flowy-tool/src/main.rs b/scripts/flowy-tool/src/main.rs index a3918b9ca7..a1a0154fe2 100644 --- a/scripts/flowy-tool/src/main.rs +++ b/scripts/flowy-tool/src/main.rs @@ -11,17 +11,18 @@ fn main() { if let Some(ref matches) = matches.subcommand_matches("pb-gen") { let rust_source = matches.value_of("rust_source").unwrap(); - let build_cache = matches.value_of("build_cache").unwrap(); + let derive_meta = matches.value_of("derive_meta").unwrap(); let rust_mod_dir = matches.value_of("rust_mod_dir").unwrap(); let flutter_mod_dir = matches.value_of("flutter_mod_dir").unwrap(); let proto_file_output = matches.value_of("proto_file_output").unwrap(); - proto::ProtoGen::new() + proto::ProtoGenBuilder::new() .set_rust_source_dir(rust_source) - .set_build_cache_dir(build_cache) + .set_derive_meta_dir(derive_meta) .set_rust_mod_dir(rust_mod_dir) .set_flutter_mod_dir(flutter_mod_dir) .set_proto_file_output_dir(proto_file_output) + .build() .gen(); } } @@ -38,11 +39,11 @@ pub fn app<'a, 'b>() -> App<'a, 'b> { Arg::with_name("rust_source") .long("rust_source") .value_name("DIRECTORY") - .help("The directory to the rust code"), + .help("Directory of the cargo workspace"), ) .arg( - Arg::with_name("build_cache") - .long("build_cache") + Arg::with_name("derive_meta") + .long("derive_meta") .value_name("PATH") .help("Caching information used by flowy-derive"), ) diff --git a/scripts/flowy-tool/src/proto/ast.rs b/scripts/flowy-tool/src/proto/ast.rs index c54e923906..3c0848bcc5 100644 --- a/scripts/flowy-tool/src/proto/ast.rs +++ b/scripts/flowy-tool/src/proto/ast.rs @@ -5,20 +5,22 @@ use flowy_ast::*; use syn::Item; use walkdir::WalkDir; -pub fn parse_crate_protobuf(root: &str, proto_output_dir: &str) -> Vec { - log::info!("Generate proto file from {}", root); +pub fn parse_crate_protobuf(root: &str) -> Vec { let domains_info = get_crate_domain_directory(root); domains_info - .iter() - .map(|domain| { - let files = parse_files_protobuf(&domain.path, proto_output_dir); - CrateProtoInfo::new(&domain, files) + .into_iter() + .map(|crate_info| { + let files = parse_files_protobuf(&crate_info); + CrateProtoInfo::from_crate_info(crate_info, files) }) .collect::>() } -fn parse_files_protobuf(root: &str, proto_output_dir: &str) -> Vec { +fn parse_files_protobuf(crate_info: &CrateInfo) -> Vec { let mut gen_proto_vec: Vec = vec![]; + let root = crate_info.domain_path.as_str(); + let proto_output_dir = crate_info.proto_file_output_dir(); + // file_stem https://doc.rust-lang.org/std/path/struct.Path.html#method.file_stem for (path, file_name) in WalkDir::new(root) .into_iter() @@ -41,7 +43,7 @@ fn parse_files_protobuf(root: &str, proto_output_dir: &str) -> Vec, + proto_file_output_dir: Option, + rust_mod_dir: Option, + flutter_mod_dir: Option, + derive_meta_dir: Option, +} + +impl ProtoGenBuilder { + pub fn new() -> Self { + ProtoGenBuilder { + rust_source_dir: None, + proto_file_output_dir: None, + rust_mod_dir: None, + flutter_mod_dir: None, + derive_meta_dir: None, + } + } + + pub fn set_rust_source_dir(mut self, dir: &str) -> Self { + self.rust_source_dir = Some(dir.to_string()); + self + } + + pub fn set_proto_file_output_dir(mut self, dir: &str) -> Self { + self.proto_file_output_dir = Some(dir.to_string()); + self + } + + pub fn set_rust_mod_dir(mut self, dir: &str) -> Self { + self.rust_mod_dir = Some(dir.to_string()); + self + } + + pub fn set_flutter_mod_dir(mut self, dir: &str) -> Self { + self.flutter_mod_dir = Some(dir.to_string()); + self + } + + pub fn set_derive_meta_dir(mut self, dir: &str) -> Self { + self.derive_meta_dir = Some(dir.to_string()); + self + } + + pub fn build(self) -> ProtoGen { + ProtoGen { + rust_source_dir: self.rust_source_dir.unwrap(), + proto_file_output_dir: self.proto_file_output_dir.unwrap(), + rust_mod_dir: self.rust_mod_dir.unwrap(), + flutter_mod_dir: self.flutter_mod_dir.unwrap(), + derive_meta_dir: self.derive_meta_dir.unwrap(), + } + } +} diff --git a/scripts/flowy-tool/src/proto/helper.rs b/scripts/flowy-tool/src/proto/helper.rs index 78f9a39558..f32593c356 100644 --- a/scripts/flowy-tool/src/proto/helper.rs +++ b/scripts/flowy-tool/src/proto/helper.rs @@ -1,23 +1,48 @@ use walkdir::WalkDir; +#[derive(Clone)] pub struct CrateInfo { - pub name: String, - pub path: String, + pub crate_folder_name: String, + pub domain_path: String, + pub crate_path: String, } pub struct CrateProtoInfo { pub files: Vec, - pub name: String, - pub path: String, + pub inner: CrateInfo, +} + +impl CrateInfo { + fn protobuf_crate_name(&self) -> String { + format!("{}/src/protobuf", self.crate_path) + } + + pub fn proto_file_output_dir(&self) -> String { + let dir = format!("{}/proto", self.protobuf_crate_name()); + self.create_file_if_not_exist(dir.as_ref()); + dir + } + + pub fn proto_struct_output_dir(&self) -> String { + let dir = format!("{}/model", self.protobuf_crate_name()); + self.create_file_if_not_exist(dir.as_ref()); + dir + } + + pub fn crate_mod_file(&self) -> String { + format!("{}/mod.rs", self.proto_struct_output_dir()) + } + + fn create_file_if_not_exist(&self, dir: &str) { + if !std::path::Path::new(&dir).exists() { + std::fs::create_dir_all(&dir).unwrap(); + } + } } impl CrateProtoInfo { - pub fn new(info: &CrateInfo, files: Vec) -> Self { - Self { - files, - name: info.name.to_owned(), - path: info.path.to_owned(), - } + pub fn from_crate_info(inner: CrateInfo, files: Vec) -> Self { + Self { files, inner } } } @@ -34,21 +59,22 @@ pub fn get_crate_domain_directory(root: &str) -> Vec { .into_iter() .filter_entry(|e| !is_hidden(e)) .filter_map(|e| e.ok()) - .filter(|e| is_domain_dir(e)) - .map(|e| CrateInfo { - //TODO: get the crate name from toml file - name: e - .path() - .parent() - .unwrap() - .parent() - .unwrap() - .file_stem() - .unwrap() - .to_str() - .unwrap() - .to_string(), - path: e.path().to_str().unwrap().to_string(), + .filter(|e| is_crate_dir(e)) + .flat_map(|e| { + // Assert e.path().parent() will be the crate dir + let path = e.path().parent().unwrap(); + let crate_folder_name = path.file_stem().unwrap().to_str().unwrap().to_string(); + if crate_folder_name == "flowy-user".to_owned() { + let crate_path = path.to_str().unwrap().to_string(); + let domain_path = format!("{}/src/domain", crate_path); + Some(CrateInfo { + crate_folder_name, + domain_path, + crate_path, + }) + } else { + None + } }) .collect::>() } @@ -62,6 +88,28 @@ pub fn is_domain_dir(e: &walkdir::DirEntry) -> bool { } } +pub fn is_crate_dir(e: &walkdir::DirEntry) -> bool { + let cargo = e.path().file_stem().unwrap().to_str().unwrap().to_string(); + cargo == "Cargo".to_string() +} + +pub fn domain_dir_from(e: &walkdir::DirEntry) -> Option { + let domain = e.path().file_stem().unwrap().to_str().unwrap().to_string(); + if e.file_type().is_dir() && domain == "domain".to_string() { + Some(e.path().to_str().unwrap().to_string()) + } else { + None + } +} + +pub fn is_proto_file(e: &walkdir::DirEntry) -> bool { + if e.path().extension().is_none() { + return false; + } + let ext = e.path().extension().unwrap().to_str().unwrap().to_string(); + ext == "proto".to_string() +} + pub fn is_hidden(entry: &walkdir::DirEntry) -> bool { entry .file_name() diff --git a/scripts/flowy-tool/src/proto/mod.rs b/scripts/flowy-tool/src/proto/mod.rs index ed94e08a24..be4bf7f33c 100644 --- a/scripts/flowy-tool/src/proto/mod.rs +++ b/scripts/flowy-tool/src/proto/mod.rs @@ -1,6 +1,8 @@ mod ast; +mod builder; mod helper; mod proto_gen; mod template; +pub use builder::*; pub use proto_gen::*; diff --git a/scripts/flowy-tool/src/proto/proto_gen.rs b/scripts/flowy-tool/src/proto/proto_gen.rs index be69de7f4f..ad5bea15f9 100644 --- a/scripts/flowy-tool/src/proto/proto_gen.rs +++ b/scripts/flowy-tool/src/proto/proto_gen.rs @@ -2,175 +2,100 @@ use crate::proto::ast::*; use crate::proto::helper::*; use crate::{proto::template::*, util::*}; use flowy_ast::*; +use shell::*; use std::{fs::OpenOptions, io::Write}; use syn::Item; use walkdir::WalkDir; pub struct ProtoGen { - rust_source_dir: Option, - proto_file_output_dir: Option, - rust_mod_dir: Option, - flutter_mod_dir: Option, - build_cache_dir: Option, + pub(crate) rust_source_dir: String, + pub(crate) proto_file_output_dir: String, + pub(crate) rust_mod_dir: String, + pub(crate) flutter_mod_dir: String, + pub(crate) derive_meta_dir: String, } impl ProtoGen { - pub fn new() -> Self { - ProtoGen { - rust_source_dir: None, - proto_file_output_dir: None, - rust_mod_dir: None, - flutter_mod_dir: None, - build_cache_dir: None, - } - } - - pub fn set_rust_source_dir(mut self, dir: &str) -> Self { - self.rust_source_dir = Some(dir.to_string()); - self - } - - pub fn set_proto_file_output_dir(mut self, dir: &str) -> Self { - self.proto_file_output_dir = Some(dir.to_string()); - self - } - - pub fn set_rust_mod_dir(mut self, dir: &str) -> Self { - self.rust_mod_dir = Some(dir.to_string()); - self - } - - pub fn set_flutter_mod_dir(mut self, dir: &str) -> Self { - self.flutter_mod_dir = Some(dir.to_string()); - self - } - - pub fn set_build_cache_dir(mut self, build_cache_dir: &str) -> Self { - self.build_cache_dir = Some(build_cache_dir.to_string()); - self - } - pub fn gen(&self) { - let infos = parse_crate_protobuf( - self.rust_source_dir.as_ref().unwrap().as_ref(), - self.proto_file_output_dir.as_ref().unwrap().as_ref(), - ); - self.write_proto_files(&infos); - self.gen_derive(&infos); - self.update_rust_flowy_protobuf_mod_file(&infos); + let crate_proto_infos = parse_crate_protobuf(self.rust_source_dir.as_ref()); + + write_proto_files(&crate_proto_infos); + + run_protoc(&crate_proto_infos); + + write_derive_meta(&crate_proto_infos, self.derive_meta_dir.as_ref()); + + write_rust_crate_protobuf(&crate_proto_infos); } +} - fn gen_derive(&self, crate_infos: &Vec) { - let file_proto_infos = crate_infos - .iter() - .map(|ref crate_info| &crate_info.files) - .flatten() - .collect::>(); +fn write_proto_files(crate_infos: &Vec) { + for crate_info in crate_infos { + let dir = crate_info.inner.proto_file_output_dir(); + crate_info.files.iter().for_each(|info| { + let proto_file_path = format!("{}/{}.proto", dir, &info.file_name); + save_content_to_file_with_diff_prompt( + &info.generated_content, + proto_file_path.as_ref(), + false, + ); + }); + } +} - let structs: Vec = file_proto_infos - .iter() - .map(|info| info.structs.clone()) - .flatten() - .collect(); - let enums: Vec = file_proto_infos - .iter() - .map(|info| info.enums.clone()) - .flatten() - .collect(); - let derive_file = self.build_cache_dir.as_ref().unwrap().clone(); - - let mut derive_template = ProtobufDeriveCache::new(structs, enums); - let new_content = derive_template.render().unwrap(); - let old_content = read_file(derive_file.as_ref()).unwrap(); - if new_content.clone() == old_content { - return; - } - // println!("{}", diff_lines(&old_content, &new_content)); +fn write_rust_crate_protobuf(crate_infos: &Vec) { + for crate_info in crate_infos { + let mod_path = crate_info.inner.crate_mod_file(); match OpenOptions::new() .create(true) .write(true) .append(false) .truncate(true) - .open(&derive_file) + .open(&mod_path) { Ok(ref mut file) => { - file.write_all(new_content.as_bytes()).unwrap(); + let mut mod_file_content = String::new(); + for (_, file_name) in WalkDir::new(crate_info.inner.proto_file_output_dir()) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().is_dir() == false) + .map(|e| { + ( + e.path().to_str().unwrap().to_string(), + e.path().file_stem().unwrap().to_str().unwrap().to_string(), + ) + }) + { + let c = format!("\nmod {}; \npub use {}::*; \n", &file_name, &file_name); + mod_file_content.push_str(c.as_ref()); + } + file.write_all(mod_file_content.as_bytes()).unwrap(); } Err(err) => { - panic!("Failed to open log file: {}", err); - } - } - } - - fn write_proto_files(&self, crate_infos: &Vec) { - for crate_info in crate_infos { - crate_info.files.iter().for_each(|info| { - // let dir = format!( - // "{}/{}", - // self.proto_file_output_dir.as_ref().unwrap(), - // &crate_info.name, - // ); - let dir = format!("{}", self.proto_file_output_dir.as_ref().unwrap(),); - - if !std::path::Path::new(&dir).exists() { - std::fs::create_dir_all(&dir).unwrap(); - } - - let proto_file_path = format!("{}/{}.proto", dir, &info.file_name); - let new_content = info.generated_content.clone(); - save_content_to_file_with_diff_prompt( - &new_content, - proto_file_path.as_ref(), - false, - ); - }); - } - } - - fn update_rust_flowy_protobuf_mod_file(&self, crate_infos: &Vec) { - for crate_info in crate_infos { - // let dir = format!( - // "{}/{}-pb", - // self.rust_mod_dir.as_ref().unwrap(), - // &crate_info.name, - // ); - - let dir = format!("{}/model", self.rust_mod_dir.as_ref().unwrap(),); - if !std::path::Path::new(&dir).exists() { - std::fs::create_dir_all(&dir).unwrap(); - } - let mod_path = format!("{}/mod.rs", dir); - - match OpenOptions::new() - .create(false) - .write(true) - .append(false) - .truncate(true) - .open(&mod_path) - { - Ok(ref mut file) => { - let mut mod_file_content = String::new(); - for (_, file_name) in - WalkDir::new(self.proto_file_output_dir.as_ref().unwrap().clone()) - .into_iter() - .filter_map(|e| e.ok()) - .filter(|e| e.file_type().is_dir() == false) - .map(|e| { - ( - e.path().to_str().unwrap().to_string(), - e.path().file_stem().unwrap().to_str().unwrap().to_string(), - ) - }) - { - let c = format!("\nmod {}; \npub use {}::*; \n", &file_name, &file_name); - mod_file_content.push_str(c.as_ref()); - } - file.write_all(mod_file_content.as_bytes()).unwrap(); - } - Err(err) => { - panic!("Failed to open file: {}", err); - } + panic!("Failed to open file: {}", err); } } } } + +fn run_protoc(crate_infos: &Vec) { + // protoc --rust_out=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/src/model \ + // --proto_path=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define \ + // ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define/*.proto + + for crate_info in crate_infos { + let rust_out = crate_info.inner.proto_struct_output_dir(); + let proto_path = crate_info.inner.proto_file_output_dir(); + + for proto_file in WalkDir::new(&proto_path) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| is_proto_file(e)) + .map(|e| e.path().to_str().unwrap().to_string()) + { + cmd_lib::run_cmd! { + protoc --rust_out=${rust_out} --proto_path=${proto_path} ${proto_file} + }; + } + } +} diff --git a/scripts/flowy-tool/src/proto/template/build_cache/derive_cache.rs b/scripts/flowy-tool/src/proto/template/build_cache/derive_cache.rs deleted file mode 100644 index dfcf8ae2d6..0000000000 --- a/scripts/flowy-tool/src/proto/template/build_cache/derive_cache.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::util::get_tera; -use tera::{Context, Tera}; - -pub struct ProtobufDeriveCache { - context: Context, - structs: Vec, - enums: Vec, -} - -#[allow(dead_code)] -impl ProtobufDeriveCache { - pub fn new(structs: Vec, enums: Vec) -> Self { - return ProtobufDeriveCache { - context: Context::new(), - structs, - enums, - }; - } - - pub fn render(&mut self) -> Option { - self.context.insert("names", &self.structs); - self.context.insert("enums", &self.enums); - - let tera = get_tera("build_cache"); - match tera.render("derive_cache.tera", &self.context) { - Ok(r) => Some(r), - Err(e) => { - log::error!("{:?}", e); - None - } - } - } -} diff --git a/scripts/flowy-tool/src/proto/template/build_cache/mod.rs b/scripts/flowy-tool/src/proto/template/build_cache/mod.rs deleted file mode 100644 index 049d77bd33..0000000000 --- a/scripts/flowy-tool/src/proto/template/build_cache/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod derive_cache; - -pub use derive_cache::*; diff --git a/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs b/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs new file mode 100644 index 0000000000..a348f0006e --- /dev/null +++ b/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs @@ -0,0 +1,77 @@ +use crate::proto::helper::{CrateProtoInfo, FileProtoInfo}; +use crate::util::{get_tera, read_file}; +use std::fs::OpenOptions; +use std::io::Write; +use tera::{Context, Tera}; + +pub struct ProtobufDeriveMeta { + context: Context, + structs: Vec, + enums: Vec, +} + +#[allow(dead_code)] +impl ProtobufDeriveMeta { + pub fn new(structs: Vec, enums: Vec) -> Self { + return ProtobufDeriveMeta { + context: Context::new(), + structs, + enums, + }; + } + + pub fn render(&mut self) -> Option { + self.context.insert("names", &self.structs); + self.context.insert("enums", &self.enums); + + let tera = get_tera("derive_meta"); + match tera.render("derive_meta.tera", &self.context) { + Ok(r) => Some(r), + Err(e) => { + log::error!("{:?}", e); + None + } + } + } +} + +pub fn write_derive_meta(crate_infos: &Vec, derive_meta_dir: &str) { + let file_proto_infos = crate_infos + .iter() + .map(|ref crate_info| &crate_info.files) + .flatten() + .collect::>(); + + let structs: Vec = file_proto_infos + .iter() + .map(|info| info.structs.clone()) + .flatten() + .collect(); + let enums: Vec = file_proto_infos + .iter() + .map(|info| info.enums.clone()) + .flatten() + .collect(); + + let mut derive_template = ProtobufDeriveMeta::new(structs, enums); + let new_content = derive_template.render().unwrap(); + let old_content = read_file(derive_meta_dir).unwrap(); + if new_content.clone() == old_content { + return; + } + // println!("{}", diff_lines(&old_content, &new_content)); + match OpenOptions::new() + .create(true) + .write(true) + .append(false) + .truncate(true) + .open(derive_meta_dir) + { + Ok(ref mut file) => { + file.write_all(new_content.as_bytes()).unwrap(); + } + Err(err) => { + panic!("Failed to open log file: {}", err); + } + } +} diff --git a/scripts/flowy-tool/src/proto/template/build_cache/derive_cache.tera b/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.tera similarity index 100% rename from scripts/flowy-tool/src/proto/template/build_cache/derive_cache.tera rename to scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.tera diff --git a/scripts/flowy-tool/src/proto/template/derive_meta/mod.rs b/scripts/flowy-tool/src/proto/template/derive_meta/mod.rs new file mode 100644 index 0000000000..d9625ff928 --- /dev/null +++ b/scripts/flowy-tool/src/proto/template/derive_meta/mod.rs @@ -0,0 +1,3 @@ +mod derive_meta; + +pub use derive_meta::*; diff --git a/scripts/flowy-tool/src/proto/template/mod.rs b/scripts/flowy-tool/src/proto/template/mod.rs index ae487e485a..2ef3646ff7 100644 --- a/scripts/flowy-tool/src/proto/template/mod.rs +++ b/scripts/flowy-tool/src/proto/template/mod.rs @@ -1,5 +1,5 @@ -mod build_cache; +mod derive_meta; mod proto_file; -pub use build_cache::*; +pub use derive_meta::*; pub use proto_file::*; diff --git a/scripts/makefile/protobuf.toml b/scripts/makefile/protobuf.toml index e1cecbde21..82458dea62 100644 --- a/scripts/makefile/protobuf.toml +++ b/scripts/makefile/protobuf.toml @@ -1,19 +1,30 @@ [tasks.pb] -dependencies = ["gen_pb_file", "gen_rust_pb"] +dependencies = ["gen_pb_file"] [tasks.gen_pb_file] script = [ """ pb_gen_bin=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/flowy-tool/Cargo.toml rust_source=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/ + rust_lib=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib + flutter_lib=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages - build_cache=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-derive/src/derive_cache/derive_cache.rs - proto_file_output=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/define - rust_mod_dir=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-protobuf/src/ - flutter_mod_dir=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/flutter-lib/packages/flowy_protobuf/lib/ + rust_flowy_protobuf=${rust_lib}/flowy-protobuf + flutter_flowy_protobuf=${flutter_lib}/flowy_protobuf - cargo run --manifest-path ${pb_gen_bin} pb-gen --rust_source=${rust_source} --build_cache=${build_cache} --proto_file_output=${proto_file_output} --rust_mod_dir=${rust_mod_dir} --flutter_mod_dir=${flutter_mod_dir} + derive_meta=${rust_lib}/flowy-derive/src/derive_cache/derive_cache.rs + proto_file_output=${rust_flowy_protobuf}/define + rust_mod_dir=${rust_flowy_protobuf}/src/ + flutter_mod_dir=${flutter_flowy_protobuf}/src/ + + cargo run \ + --manifest-path ${pb_gen_bin} pb-gen \ + --rust_source=${rust_source} \ + --derive_meta=${derive_meta} \ + --proto_file_output=${proto_file_output} \ + --rust_mod_dir=${rust_mod_dir} \ + --flutter_mod_dir=${flutter_mod_dir} """, ] script_runner = "@shell"