file.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. use console::Style;
  2. use similar::{ChangeTag, TextDiff};
  3. use std::{
  4. fs::{File, OpenOptions},
  5. io::{Read, Write},
  6. path::Path,
  7. };
  8. use tera::Tera;
  9. use walkdir::WalkDir;
  10. pub fn read_file(path: &str) -> Option<String> {
  11. let mut file = File::open(path).unwrap_or_else(|_| panic!("Unable to open file at {}", path));
  12. let mut content = String::new();
  13. match file.read_to_string(&mut content) {
  14. Ok(_) => Some(content),
  15. Err(e) => {
  16. log::error!("{}, with error: {:?}", path, e);
  17. Some("".to_string())
  18. }
  19. }
  20. }
  21. pub fn save_content_to_file_with_diff_prompt(content: &str, output_file: &str, _force_write: bool) {
  22. if Path::new(output_file).exists() {
  23. let old_content = read_file(output_file).unwrap();
  24. let new_content = content.to_owned();
  25. let write_to_file = || match OpenOptions::new()
  26. .create(true)
  27. .write(true)
  28. .append(false)
  29. .truncate(true)
  30. .open(output_file)
  31. {
  32. Ok(ref mut file) => {
  33. file.write_all(new_content.as_bytes()).unwrap();
  34. }
  35. Err(err) => {
  36. panic!("Failed to open log file: {}", err);
  37. }
  38. };
  39. if new_content != old_content {
  40. print_diff(old_content, new_content.clone());
  41. write_to_file()
  42. // if force_write {
  43. // write_to_file()
  44. // } else {
  45. // if Confirm::new().with_prompt("Override?").interact().unwrap() {
  46. // write_to_file()
  47. // } else {
  48. // tracing::info!("never mind then :(");
  49. // }
  50. // }
  51. }
  52. } else {
  53. match OpenOptions::new()
  54. .create(true)
  55. .write(true)
  56. .open(output_file)
  57. {
  58. Ok(ref mut file) => file.write_all(content.as_bytes()).unwrap(),
  59. Err(err) => panic!("Open or create to {} fail: {}", output_file, err),
  60. }
  61. }
  62. }
  63. pub fn print_diff(old_content: String, new_content: String) {
  64. let diff = TextDiff::from_lines(&old_content, &new_content);
  65. for op in diff.ops() {
  66. for change in diff.iter_changes(op) {
  67. let (sign, style) = match change.tag() {
  68. ChangeTag::Delete => ("-", Style::new().red()),
  69. ChangeTag::Insert => ("+", Style::new().green()),
  70. ChangeTag::Equal => (" ", Style::new()),
  71. };
  72. match change.tag() {
  73. ChangeTag::Delete => {
  74. print!("{}{}", style.apply_to(sign).bold(), style.apply_to(change));
  75. }
  76. ChangeTag::Insert => {
  77. print!("{}{}", style.apply_to(sign).bold(), style.apply_to(change));
  78. }
  79. ChangeTag::Equal => {}
  80. };
  81. }
  82. println!("---------------------------------------------------");
  83. }
  84. }
  85. pub fn get_tera(directory: &str) -> Tera {
  86. let mut root = "./scripts/flowy-tool/src/".to_owned();
  87. root.push_str(directory);
  88. let root_absolute_path = std::fs::canonicalize(root)
  89. .unwrap()
  90. .as_path()
  91. .display()
  92. .to_string();
  93. let mut template_path = format!("{}/**/*.tera", root_absolute_path);
  94. if cfg!(windows) {
  95. // remove "\\?\" prefix on windows
  96. template_path = format!("{}/**/*.tera", &root_absolute_path[4..]);
  97. }
  98. match Tera::new(template_path.as_ref()) {
  99. Ok(t) => t,
  100. Err(e) => {
  101. log::error!("Parsing error(s): {}", e);
  102. ::std::process::exit(1);
  103. }
  104. }
  105. }
  106. pub fn is_crate_dir(e: &walkdir::DirEntry) -> bool {
  107. let cargo = e.path().file_stem().unwrap().to_str().unwrap().to_string();
  108. cargo == *"Cargo"
  109. }
  110. pub fn is_proto_file(e: &walkdir::DirEntry) -> bool {
  111. if e.path().extension().is_none() {
  112. return false;
  113. }
  114. let ext = e.path().extension().unwrap().to_str().unwrap().to_string();
  115. ext == *"proto"
  116. }
  117. pub fn is_hidden(entry: &walkdir::DirEntry) -> bool {
  118. entry
  119. .file_name()
  120. .to_str()
  121. .map(|s| s.starts_with('.'))
  122. .unwrap_or(false)
  123. }
  124. pub fn create_dir_if_not_exist(dir: &str) {
  125. if !std::path::Path::new(&dir).exists() {
  126. std::fs::create_dir_all(&dir).unwrap();
  127. }
  128. }
  129. pub(crate) fn walk_dir<F1, F2>(dir: &str, filter: F2, mut path_and_name: F1)
  130. where
  131. F1: FnMut(String, String),
  132. F2: Fn(&walkdir::DirEntry) -> bool,
  133. {
  134. for (path, name) in WalkDir::new(dir)
  135. .into_iter()
  136. .filter_map(|e| e.ok())
  137. .filter(|e| filter(e))
  138. .map(|e| {
  139. (
  140. e.path().to_str().unwrap().to_string(),
  141. e.path().file_stem().unwrap().to_str().unwrap().to_string(),
  142. )
  143. })
  144. {
  145. path_and_name(path, name);
  146. }
  147. }
  148. #[allow(dead_code)]
  149. pub fn suffix_relative_to_path(path: &str, base: &str) -> String {
  150. let base = Path::new(base);
  151. let path = Path::new(path);
  152. path.strip_prefix(base)
  153. .unwrap()
  154. .to_str()
  155. .unwrap()
  156. .to_owned()
  157. }