-
Notifications
You must be signed in to change notification settings - Fork 1
/
build.rs
162 lines (139 loc) · 5.87 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// cargo:rerun-if-changed=build.rs
use core::str::Split;
use serde::{Deserialize};
use std::cell::RefCell;
use std::collections::HashMap;
use std::fs;
use std::result::Result;
use std::error::Error;
use std::path::Display;
use walkdir::WalkDir;
#[path = "src/utils/walk_injection.rs"] mod walk_injection;
use walk_injection::KeyValue;
#[derive(Deserialize)]
struct CargoTOML {
package: CargoPackage,
}
#[derive(Deserialize)]
struct CargoPackage {
version: String,
}
fn main() -> Result<(), Box<dyn Error>> {
update_help_command_with_version_from_cargo()?;
inject_documentation_addon_to_source_code_before_compile()?;
return inject_new_ember_app_to_source_code_before_compile();
}
fn update_help_command_with_version_from_cargo() -> Result<(), Box<dyn Error>> {
let package_details: CargoTOML =
toml::from_str(fs::read_to_string("Cargo.toml")?.as_str())?;
let mber_version = package_details.package.version;
let help_code = fs::read_to_string("src/commands/help.rs")?;
let help_code_version_line = help_code
.lines()
.find(|line| line.trim_start().starts_with("let version ="))
.expect("cant find version line!")
.trim();
return Ok(fs::write(
"src/commands/help.rs",
help_code.replace(
help_code_version_line,
format!("let version = \"{}\";", mber_version).as_str(),
),
)?);
}
fn inject_new_ember_app_to_source_code_before_compile() -> Result<(), Box<dyn Error>> {
let file_system_map = build_hashmap_from_file_directory_with_filter("ember-app-boilerplate", |entry| {
return match entry.path().display().to_string().as_str() {
"ember-app-boilerplate/node_modules" | "ember-app-boilerplate/package-lock.json" |
"ember-app-boilerplate/tmp" => false,
_ => true
};
});
let json_string = serde_json::to_string(&file_system_map)?;
return Ok(fs::write(
"src/injections/new_ember_application.rs",
format!(
"pub fn as_str() -> &'static str {{\nreturn r##\"\n{}\"##;\n}}",
json_string
),
)?);
}
fn inject_documentation_addon_to_source_code_before_compile() -> Result<(), Box<dyn Error>> {
let file_system_map = build_hashmap_from_file_directory_with_filter("_vendor/mber-documentation", |_| { return true });
let flat_documentation_fs_hashmap = walk_injection::flatten_fs_hashmap_in_binary(file_system_map.into_inner(), vec![]);
let json_string = serde_json::to_string(&flat_documentation_fs_hashmap)?;
return Ok(fs::write(
"src/injections/documentation.rs",
format!(
"pub fn as_str() -> &'static str {{\nreturn r##\"\n{}\"##;\n}}",
json_string
),
)?);
}
fn build_hashmap_from_file_directory_with_filter<F>(directory_string: &str, filter_function: F) -> RefCell<HashMap<String, KeyValue>>
where F: FnMut(&walkdir::DirEntry) -> bool {
let walker = WalkDir::new(directory_string).into_iter().filter_entry(filter_function);
let mut file_system_map: RefCell<HashMap<String, KeyValue>> = RefCell::new(HashMap::new());
for entry in walker {
let entry = entry.expect("ENTRY NOT FOUND");
match entry.file_type().is_dir() {
true => check_and_set_directory_map_to_map(&mut file_system_map, entry.path().display()),
false => find_directory_map_and_insert_file(&mut file_system_map, entry.path().display())
}
}
return file_system_map;
}
fn check_and_set_directory_map_to_map(
file_system_map: &mut RefCell<HashMap<String, KeyValue>>,
path: Display,
) {
let full_path = path.to_string();
let directories = full_path.split("/");
for (index, directory) in directories.clone().enumerate() {
let mut mutable_file_system_map = file_system_map.borrow_mut();
if let None = mutable_file_system_map.get(&String::from(directory)) {
let target_hash_map =
get_from_directory_map_from_map(&mut mutable_file_system_map, &directories, index);
target_hash_map
.entry(String::from(directory))
.or_insert(KeyValue::RefCell(HashMap::new()));
};
}
}
fn get_from_directory_map_from_map<'a>(
hashmap: &'a mut HashMap<String, KeyValue>,
directories_list: &Split<&str>,
directory_index: usize,
) -> &'a mut HashMap<String, KeyValue> {
let directory_list: Vec<&str> = directories_list.clone().collect::<Vec<_>>(); // NOTE: this is correct but optimize it!
let target_directory_list = directory_list.get(0..directory_index).expect("TARGET_DIRECTORY_LIST CANNOT BE SLICED");
return target_directory_list.iter().enumerate().fold(
hashmap,
|acc: &mut HashMap<String, KeyValue>,
(_index, directory_name)|
-> &mut HashMap<String, KeyValue> {
println!("{}", directory_name);
match acc.get_mut(*directory_name).expect("CANNOT FIND THE DIRECTORY ON REFCELL HASHMAP") {
KeyValue::RefCell(something) => something,
_ => panic!(
"{} must exist in the fs directory mapping in memory!",
directory_name
)
}
},
);
}
fn find_directory_map_and_insert_file(
file_system_map: &mut RefCell<HashMap<String, KeyValue>>,
path: Display,
) {
let path_string = path.to_string();
let file_name = &path_string.split("/").last().expect("SPLIT / DIDNT work on path_string");
let path_list = &path_string.split("/");
let directory_path_index = &path_list.clone().count().wrapping_sub(1);
let contents = fs::read(&path_string).expect(format!("couldnt read {}", path_string).as_str());
let mut full_map = file_system_map.borrow_mut();
let target_hash_map =
get_from_directory_map_from_map(&mut full_map, &path_list, *directory_path_index);
target_hash_map.insert(file_name.to_string(), KeyValue::Vec(contents));
}