-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
149 lines (133 loc) · 4.21 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
use fs_extra::dir::CopyOptions;
use glob;
use std::{
env,
error::Error,
fmt,
fs::File,
io::Write,
path::{Path, StripPrefixError},
process::Command,
};
#[derive(Debug)]
struct BuildError(String);
impl fmt::Display for BuildError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "BuildError: {}", self.0)
}
}
impl Error for BuildError {}
impl From<std::io::Error> for BuildError {
fn from(err: std::io::Error) -> Self {
BuildError(format!("stri-prefix-error: {}", err))
}
}
impl From<StripPrefixError> for BuildError {
fn from(err: StripPrefixError) -> Self {
BuildError(format!("io-error: {}", err))
}
}
const UI_PACKAGE_JSON: &str = "ui/package.json";
const UI_TSCONFIG: &str = "ui/tsconfig.json";
const UI_YARN_LOCK: &str = "ui/yarn.lock";
const UI_SRC_DIR: &str = "ui/src";
const UI_PUBLIC_DIR: &str = "ui/public";
const UI_TARGET_PATTERNS: [&str; 7] = [
"static/css/**/*.css",
"static/js/**/*.js",
"*.ico",
"*.ico",
"*.png",
"*.json",
"*.html",
];
fn append_file_bytes(
file: &mut File,
out_path: &Path,
glob_pattern: &str,
) -> Result<(), BuildError> {
let build_path = out_path.join("ui/build");
let glob_pattern = build_path.join(glob_pattern);
let pattern = glob_pattern.to_str().to_owned().unwrap();
let paths = glob::glob(pattern).unwrap();
for result in paths {
match result {
// Trigger a full project rebuild if any of the files printed below has changed
Ok(path) => {
writeln!(
file,
r##"("{name}", include_bytes!(r#"{file_path}"#)),"##,
name = path.strip_prefix(&build_path)?.to_str().unwrap(),
file_path = path.to_str().unwrap(),
)?;
}
Err(err) => return Err(BuildError(format!("glob error: {:?}", err))),
}
}
Ok(())
}
fn main() -> Result<(), BuildError> {
for pattern in &[
UI_PACKAGE_JSON,
UI_TSCONFIG,
UI_YARN_LOCK,
&format!("{}/**/*", UI_PUBLIC_DIR),
&format!("{}/**/*", UI_SRC_DIR),
] {
let paths = glob::glob(pattern).unwrap();
for result in paths {
match result {
// Trigger a full project rebuild if any of the files printed below has changed
Ok(path) => println!("cargo:rerun-if-changed={}", path.to_str().unwrap()),
Err(err) => return Err(BuildError(format!("glob error: {:?}", err))),
}
}
}
let out_dir = env::var("OUT_DIR").unwrap();
let ui_dir = Path::new(&out_dir).join("ui");
std::fs::create_dir_all(ui_dir.clone())?;
let copy_options = CopyOptions {
overwrite: false,
skip_exist: true,
buffer_size: 64000,
copy_inside: true,
depth: 0,
};
fs_extra::copy_items(
&vec![UI_PACKAGE_JSON, UI_TSCONFIG, UI_PUBLIC_DIR, UI_SRC_DIR],
ui_dir.clone(),
©_options,
)
.unwrap();
// Command::new("npm")
// .args(&["install", "--save-dev", "typescript"])
// .current_dir(ui_dir.clone())
// .spawn()
// .expect("failed to run 'npm install --save-dev typescript'");
Command::new("npm")
.args(&["install"])
.current_dir(ui_dir.clone())
.spawn()
.expect("failed to run npm install");
let exit_status = Command::new("npx")
.args(&["react-scripts", "build"])
.current_dir(ui_dir.clone())
.status()?;
match exit_status.code() {
Some(0) => {
let dest_path = Path::new(&out_dir).join("ui_build_assets.rs");
let out_dir = Path::new(&out_dir);
let mut all_the_files = File::create(&dest_path)?;
writeln!(&mut all_the_files, r##"["##,)?;
for pattern in UI_TARGET_PATTERNS.to_vec() {
append_file_bytes(&mut all_the_files, &out_dir, pattern)?;
}
writeln!(&mut all_the_files, r##"]"##,)?;
Ok(())
}
other => Err(BuildError(format!(
"`yarn build` command exited with an unexpected status code: {:?}",
other
))),
}
}