浏览代码

export flutter protobuf model through protobuf.dart

appflowy 3 年之前
父节点
当前提交
2fca817136

+ 1 - 0
app_flowy/packages/flowy_sdk/lib/protobuf.dart

@@ -1,3 +1,4 @@
+// Auto-generated, do not edit 
 export 'protobuf/sign_in.pbjson.pb.dart';
 export 'protobuf/sign_in.pb.pb.dart';
 export 'protobuf/ffi_response.pbjson.pb.dart';

+ 8 - 0
rust-lib/.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 8 - 0
rust-lib/.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/rust-lib.iml" filepath="$PROJECT_DIR$/.idea/rust-lib.iml" />
+    </modules>
+  </component>
+</project>

+ 20 - 0
rust-lib/.idea/rust-lib.iml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="CPP_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/dart-ffi/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-ast/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-derive/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-derive/tests" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-log/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-sdk/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-sdk/tests" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-sys/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-sys/tests" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/flowy-user/src" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 6 - 0
rust-lib/.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+  </component>
+</project>

+ 1 - 0
rust-lib/dart-ffi/src/protobuf/model/mod.rs

@@ -1,3 +1,4 @@
+// Auto-generated, do not edit 
 
 mod ffi_response; 
 pub use ffi_response::*; 

+ 1 - 0
rust-lib/flowy-user/src/protobuf/model/mod.rs

@@ -1,3 +1,4 @@
+// Auto-generated, do not edit 
 
 mod sign_up; 
 pub use sign_up::*; 

+ 6 - 8
scripts/flowy-tool/src/proto/ast.rs

@@ -1,13 +1,17 @@
+use crate::proto::crate_info::*;
 use crate::proto::helper::*;
 use crate::proto::template::{EnumTemplate, StructTemplate};
 use crate::util::*;
+use fancy_regex::Regex;
 use flowy_ast::*;
+use lazy_static::lazy_static;
+use std::{fs::File, io::Read, path::Path};
 use syn::Item;
 use walkdir::WalkDir;
 
 pub fn parse_crate_protobuf(root: &str) -> Vec<CrateProtoInfo> {
-    let domains_info = get_crate_domain_directory(root);
-    domains_info
+    let crate_infos = parse_crate_info_from_path(root);
+    crate_infos
         .into_iter()
         .map(|crate_info| {
             let proto_output_dir = crate_info.proto_file_output_dir();
@@ -45,8 +49,6 @@ fn parse_files_protobuf(proto_crate_path: &str, proto_output_dir: &str) -> Vec<F
         let ast =
             syn::parse_file(read_file(&path).unwrap().as_ref()).expect("Unable to parse file");
         let structs = get_ast_structs(&ast);
-
-        // println!("😁 {} - {}", path, file_name);
         let proto_file_path = format!("{}/{}.proto", &proto_output_dir, &file_name);
         let mut proto_file_content = parse_or_init_proto_file(proto_file_path.as_ref());
 
@@ -154,10 +156,6 @@ pub struct Struct<'a> {
     pub fields: Vec<ASTField<'a>>,
 }
 
-use fancy_regex::Regex;
-use lazy_static::lazy_static;
-use std::{fs::File, io::Read, path::Path};
-
 lazy_static! {
     static ref SYNTAX_REGEX: Regex = Regex::new("syntax.*;").unwrap();
     static ref IMPORT_REGEX: Regex = Regex::new("(import\\s).*;").unwrap();

+ 132 - 0
scripts/flowy-tool/src/proto/crate_info.rs

@@ -0,0 +1,132 @@
+use crate::config::FlowyConfig;
+use crate::proto::helper::*;
+use std::fs::OpenOptions;
+use std::io::Write;
+use walkdir::WalkDir;
+
+#[derive(Clone)]
+pub struct CrateInfo {
+    pub crate_folder_name: String,
+    pub proto_crate_paths: Vec<String>,
+    pub crate_path: String,
+}
+
+pub struct CrateProtoInfo {
+    pub files: Vec<FileProtoInfo>,
+    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());
+        create_dir_if_not_exist(dir.as_ref());
+        dir
+    }
+
+    pub fn proto_struct_output_dir(&self) -> String {
+        let dir = format!("{}/model", self.protobuf_crate_name());
+        create_dir_if_not_exist(dir.as_ref());
+        dir
+    }
+
+    pub fn proto_model_mod_file(&self) -> String {
+        format!("{}/mod.rs", self.proto_struct_output_dir())
+    }
+}
+
+impl CrateProtoInfo {
+    pub fn from_crate_info(inner: CrateInfo, files: Vec<FileProtoInfo>) -> Self {
+        Self { files, inner }
+    }
+
+    pub fn create_crate_mod_file(&self) {
+        // mod model;
+        // pub use model::*;
+        let mod_file_path = format!("{}/mod.rs", self.inner.protobuf_crate_name());
+        let content = r#"
+mod model;
+pub use model::*;
+        "#;
+        match OpenOptions::new()
+            .create(true)
+            .write(true)
+            .append(false)
+            .truncate(true)
+            .open(&mod_file_path)
+        {
+            Ok(ref mut file) => {
+                file.write_all(content.as_bytes()).unwrap();
+            }
+            Err(err) => {
+                panic!("Failed to open protobuf mod file: {}", err);
+            }
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct FileProtoInfo {
+    pub file_name: String,
+    pub structs: Vec<String>,
+    pub enums: Vec<String>,
+    pub generated_content: String,
+}
+
+pub fn parse_crate_info_from_path(root: &str) -> Vec<CrateInfo> {
+    WalkDir::new(root)
+        .into_iter()
+        .filter_entry(|e| !is_hidden(e))
+        .filter_map(|e| e.ok())
+        .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_path = path.to_str().unwrap().to_string();
+            let crate_folder_name = path.file_stem().unwrap().to_str().unwrap().to_string();
+            let flowy_config_file = format!("{}/Flowy.toml", crate_path);
+
+            if std::path::Path::new(&flowy_config_file).exists() {
+                let config = FlowyConfig::from_toml_file(flowy_config_file.as_ref());
+                let crate_path = path.to_str().unwrap().to_string();
+                let proto_crate_paths = config
+                    .proto_crates
+                    .iter()
+                    .map(|name| format!("{}/{}", crate_path, name))
+                    .collect::<Vec<String>>();
+                Some(CrateInfo {
+                    crate_folder_name,
+                    proto_crate_paths,
+                    crate_path,
+                })
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<CrateInfo>>()
+}
+
+pub struct FlutterProtobufInfo {
+    package_path: String,
+}
+impl FlutterProtobufInfo {
+    pub fn new(root: &str) -> Self {
+        FlutterProtobufInfo {
+            package_path: root.to_owned(),
+        }
+    }
+
+    pub fn model_dir(&self) -> String {
+        let model_dir = format!("{}/protobuf", self.package_path);
+        create_dir_if_not_exist(model_dir.as_ref());
+        model_dir
+    }
+
+    pub fn mod_file_path(&self) -> String {
+        let mod_file_path = format!("{}/protobuf.dart", self.package_path);
+        mod_file_path
+    }
+}

+ 0 - 110
scripts/flowy-tool/src/proto/helper.rs

@@ -1,113 +1,3 @@
-use crate::config::*;
-use std::fs::OpenOptions;
-use std::io::Write;
-use walkdir::WalkDir;
-
-#[derive(Clone)]
-pub struct CrateInfo {
-    pub crate_folder_name: String,
-    pub proto_crate_paths: Vec<String>,
-    pub crate_path: String,
-}
-
-pub struct CrateProtoInfo {
-    pub files: Vec<FileProtoInfo>,
-    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());
-        create_dir_if_not_exist(dir.as_ref());
-        dir
-    }
-
-    pub fn proto_struct_output_dir(&self) -> String {
-        let dir = format!("{}/model", self.protobuf_crate_name());
-        create_dir_if_not_exist(dir.as_ref());
-        dir
-    }
-
-    pub fn proto_model_mod_file(&self) -> String {
-        format!("{}/mod.rs", self.proto_struct_output_dir())
-    }
-}
-
-impl CrateProtoInfo {
-    pub fn from_crate_info(inner: CrateInfo, files: Vec<FileProtoInfo>) -> Self {
-        Self { files, inner }
-    }
-
-    pub fn create_crate_mod_file(&self) {
-        // mod model;
-        // pub use model::*;
-        let mod_file_path = format!("{}/mod.rs", self.inner.protobuf_crate_name());
-        let content = r#"
-mod model;
-pub use model::*;
-        "#;
-        match OpenOptions::new()
-            .create(true)
-            .write(true)
-            .append(false)
-            .truncate(true)
-            .open(&mod_file_path)
-        {
-            Ok(ref mut file) => {
-                file.write_all(content.as_bytes()).unwrap();
-            }
-            Err(err) => {
-                panic!("Failed to open protobuf mod file: {}", err);
-            }
-        }
-    }
-}
-
-#[derive(Debug)]
-pub struct FileProtoInfo {
-    pub file_name: String,
-    pub structs: Vec<String>,
-    pub enums: Vec<String>,
-    pub generated_content: String,
-}
-
-pub fn get_crate_domain_directory(root: &str) -> Vec<CrateInfo> {
-    WalkDir::new(root)
-        .into_iter()
-        .filter_entry(|e| !is_hidden(e))
-        .filter_map(|e| e.ok())
-        .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_path = path.to_str().unwrap().to_string();
-            let crate_folder_name = path.file_stem().unwrap().to_str().unwrap().to_string();
-            let flowy_config_file = format!("{}/Flowy.toml", crate_path);
-
-            if std::path::Path::new(&flowy_config_file).exists() {
-                let config = FlowyConfig::from_toml_file(flowy_config_file.as_ref());
-                let crate_path = path.to_str().unwrap().to_string();
-                let proto_crate_paths = config
-                    .proto_crates
-                    .iter()
-                    .map(|name| format!("{}/{}", crate_path, name))
-                    .collect::<Vec<String>>();
-                Some(CrateInfo {
-                    crate_folder_name,
-                    proto_crate_paths,
-                    crate_path,
-                })
-            } else {
-                None
-            }
-        })
-        .collect::<Vec<CrateInfo>>()
-}
-
 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()

+ 1 - 0
scripts/flowy-tool/src/proto/mod.rs

@@ -1,5 +1,6 @@
 mod ast;
 mod builder;
+mod crate_info;
 mod helper;
 mod proto_gen;
 mod template;

+ 13 - 14
scripts/flowy-tool/src/proto/proto_gen.rs

@@ -1,10 +1,8 @@
 use crate::proto::ast::*;
+use crate::proto::crate_info::*;
 use crate::proto::helper::*;
 use crate::{proto::template::*, util::*};
-
 use std::{fs::OpenOptions, io::Write};
-
-use std::fs::File;
 use walkdir::WalkDir;
 
 pub struct ProtoGen {
@@ -18,15 +16,15 @@ impl ProtoGen {
         let crate_proto_infos = parse_crate_protobuf(self.rust_source_dir.as_ref());
         write_proto_files(&crate_proto_infos);
 
+        // FIXME: ignore unchanged file to reduce time cost
         run_rust_protoc(&crate_proto_infos);
         write_rust_crate_mod_file(&crate_proto_infos);
-
-        let package_root = self.flutter_package_lib.as_ref();
-        let model_dir = format!("{}/protobuf", package_root);
-        run_flutter_protoc(&crate_proto_infos, model_dir.as_ref());
-        write_flutter_crate_mod_file(package_root, model_dir.as_ref());
-
         write_derive_meta(&crate_proto_infos, self.derive_meta_dir.as_ref());
+
+        // FIXME: ignore unchanged file to reduce time cost
+        let flutter_package = FlutterProtobufInfo::new(self.flutter_package_lib.as_ref());
+        run_flutter_protoc(&crate_proto_infos, &flutter_package);
+        write_flutter_protobuf_package_mod_file(&flutter_package);
     }
 }
 
@@ -74,8 +72,9 @@ fn write_rust_crate_mod_file(crate_infos: &Vec<CrateProtoInfo>) {
     }
 }
 
-fn write_flutter_crate_mod_file(package_root: &str, model_dir: &str) {
-    let mod_path = format!("{}/protobuf.dart", package_root);
+fn write_flutter_protobuf_package_mod_file(package_info: &FlutterProtobufInfo) {
+    let mod_path = package_info.mod_file_path();
+    let model_dir = package_info.model_dir();
     match OpenOptions::new()
         .create(true)
         .write(true)
@@ -87,7 +86,7 @@ fn write_flutter_crate_mod_file(package_root: &str, model_dir: &str) {
             let mut mod_file_content = String::new();
             mod_file_content.push_str("// Auto-generated, do not edit \n");
             walk_dir(
-                model_dir,
+                model_dir.as_ref(),
                 |e| e.file_type().is_dir() == false,
                 |_, name| {
                     let c = format!("export 'protobuf/{}.pb.dart';\n", &name);
@@ -125,8 +124,8 @@ fn run_rust_protoc(crate_infos: &Vec<CrateProtoInfo>) {
     }
 }
 
-fn run_flutter_protoc(crate_infos: &Vec<CrateProtoInfo>, model_dir: &str) {
-    create_dir_if_not_exist(model_dir.as_ref());
+fn run_flutter_protoc(crate_infos: &Vec<CrateProtoInfo>, package_info: &FlutterProtobufInfo) {
+    let model_dir = package_info.model_dir();
     for crate_info in crate_infos {
         let proto_path = crate_info.inner.proto_file_output_dir();
         walk_dir(

+ 1 - 1
scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs

@@ -1,4 +1,4 @@
-use crate::proto::helper::{CrateProtoInfo, FileProtoInfo};
+use crate::proto::crate_info::{CrateProtoInfo, FileProtoInfo};
 use crate::util::{get_tera, read_file};
 use std::fs::OpenOptions;
 use std::io::Write;

+ 10 - 9
scripts/flowy-tool/src/util/file.rs

@@ -40,15 +40,16 @@ pub fn save_content_to_file_with_diff_prompt(content: &str, output_file: &str, f
         };
         if new_content != old_content {
             print_diff(old_content.clone(), new_content.clone());
-            if force_write {
-                write_to_file()
-            } else {
-                if Confirm::new().with_prompt("Override?").interact().unwrap() {
-                    write_to_file()
-                } else {
-                    log::info!("never mind then :(");
-                }
-            }
+            write_to_file()
+            // if force_write {
+            //     write_to_file()
+            // } else {
+            //     if Confirm::new().with_prompt("Override?").interact().unwrap() {
+            //         write_to_file()
+            //     } else {
+            //         log::info!("never mind then :(");
+            //     }
+            // }
         }
     } else {
         match OpenOptions::new()