-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy pathbuild.rs
160 lines (146 loc) · 4.64 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
use std::{
fs::{self, Metadata},
path::PathBuf,
time::SystemTime,
};
macro_rules! p {
($($tokens: tt)*) => {
println!("cargo:warning={}", format!($($tokens)*))
}
}
struct Dirs {
js_dist_source: PathBuf,
js_dist_tmp: PathBuf,
src_browser: PathBuf,
browser_root: PathBuf,
}
fn main() -> std::io::Result<()> {
// Uncomment this line if you want faster builds during development
// return Ok(());
const BROWSER_ROOT: &str = "../browser/";
let dirs: Dirs = {
Dirs {
js_dist_source: PathBuf::from("../browser/data-browser/dist"),
js_dist_tmp: PathBuf::from("./assets_tmp"),
src_browser: PathBuf::from("../browser/data-browser/src"),
browser_root: PathBuf::from(BROWSER_ROOT),
}
};
println!("cargo:rerun-if-changed={}", BROWSER_ROOT);
if should_build(&dirs) {
build_js(&dirs);
let _ = fs::remove_dir_all(&dirs.js_dist_tmp);
dircpy::copy_dir(&dirs.js_dist_source, &dirs.js_dist_tmp)?;
} else if dirs.js_dist_tmp.exists() {
p!("Found {}, skipping copy", dirs.js_dist_tmp.display());
} else {
p!(
"Could not find {} , copying from {}",
dirs.js_dist_tmp.display(),
dirs.js_dist_source.display()
);
dircpy::copy_dir(&dirs.js_dist_source, &dirs.js_dist_tmp)?;
}
// Makes the static files available for compilation
static_files::resource_dir(&dirs.js_dist_tmp)
.build()
.unwrap_or_else(|_e| {
panic!(
"failed to open data browser assets from {}",
dirs.js_dist_tmp.display()
)
});
Ok(())
}
fn should_build(dirs: &Dirs) -> bool {
if !dirs.browser_root.exists() {
p!("Could not find browser folder, assuming this is a `cargo publish` run. Skipping JS build.");
return false;
}
// Check if any JS files were modified since the last build
if let Ok(tmp_dist_index_html) =
std::fs::metadata(format!("{}/index.html", dirs.js_dist_tmp.display()))
{
let has_changes = walkdir::WalkDir::new(&dirs.src_browser)
.into_iter()
.filter_entry(|entry| {
entry
.file_name()
.to_str()
.map(|s| !s.starts_with(".DS_Store"))
.unwrap_or(false)
})
.any(|entry| is_older_than(&entry.unwrap(), &tmp_dist_index_html));
if has_changes {
return true;
}
p!("No changes in JS source files, skipping JS build.");
false
} else if dirs.src_browser.exists() {
p!(
"No JS dist folder found at {}, but did find source folder {}, building...",
dirs.js_dist_tmp.display(),
dirs.src_browser.display()
);
true
} else {
p!(
"Could not find index.html in {}. Skipping JS build.",
dirs.js_dist_tmp.display()
);
false
}
}
/// Runs JS package manager to install packages and build the JS bundle
fn build_js(dirs: &Dirs) {
let pkg_manager = "pnpm";
p!("install js packages...");
std::process::Command::new(pkg_manager)
.current_dir(&dirs.browser_root)
.args(["install"])
.output()
.unwrap_or_else(|_| {
panic!(
"Failed to install js packages. Make sure you have {} installed.",
pkg_manager
)
});
p!("build js assets...");
let out = std::process::Command::new(pkg_manager)
.current_dir(&dirs.browser_root)
.args(["run", "build"])
.output()
.expect("Failed to build js bundle");
// Check if out contains errors
if out.status.success() {
p!("js build successful");
} else {
let stdout = String::from_utf8_lossy(&out.stdout);
let stderr = String::from_utf8_lossy(&out.stderr);
panic!("js build failed:\nStdout:\n{}\nStderr:\n{}", stdout, stderr);
}
}
fn is_older_than(dir_entry: &walkdir::DirEntry, dist_meta: &Metadata) -> bool {
let dist_time = dist_meta
.modified()
.unwrap()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
if dir_entry.path().is_file() {
let src_time = dir_entry
.metadata()
.unwrap()
.modified()
.unwrap()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
if src_time >= dist_time {
p!(
"Source file modified: {:?}, rebuilding...",
dir_entry.path()
);
return true;
}
}
false
}