-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
97 lines (88 loc) · 3.6 KB
/
Copy pathbuild.rs
File metadata and controls
97 lines (88 loc) · 3.6 KB
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
use std::io::Write;
fn main() {
embuild::espidf::sysenv::output();
// Determine if this build has WiFi support.
// ESP32, ESP32-C6, etc: always have WiFi (built-in radio).
// ESP32-P4: only with the "p4-wifi" feature (WiFi via companion ESP32-C6 chip).
let mcu = std::env::var("MCU").unwrap_or_default();
let has_wifi = match mcu.as_str() {
"esp32p4" => std::env::var("CARGO_FEATURE_P4_WIFI").is_ok(),
_ => true,
};
if has_wifi {
println!("cargo:rustc-cfg=has_wifi");
}
if std::env::var("CARGO_FEATURE_MQTT").is_ok() {
println!("cargo:rustc-cfg=has_mqtt");
}
println!("cargo:rerun-if-env-changed=MCU");
// Gzip the Vite-built frontend HTML at build time (saves ~29KB heap at runtime).
// Run `cd frontend && npm run build` before `cargo build` if dist is missing.
let version = app_version();
let frontend_path = "frontend/dist/index.html";
let html = std::fs::read_to_string(frontend_path).unwrap_or_else(|_| {
panic!(
"{frontend_path} not found — run `cd frontend && npm install && npm run build` first"
)
});
let html = html.replace("__RUSTY_COLLARS_APP_VERSION__", &version);
let mut encoder = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::best());
encoder
.write_all(html.as_bytes())
.expect("gzip encode failed");
let compressed = encoder.finish().expect("gzip finish failed");
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
let gz_path = std::path::Path::new(&out_dir).join("frontend.html.gz");
std::fs::write(&gz_path, &compressed).expect("write frontend.html.gz failed");
// Raw HTML is also embedded so the server can serve identity bodies to
// clients that do not advertise gzip support (RFC 9110 §12.5.3).
let raw_path = std::path::Path::new(&out_dir).join("frontend.html");
std::fs::write(&raw_path, html.as_bytes()).expect("write frontend.html failed");
println!(
"cargo:warning=Frontend: {}B raw -> {}B gzip ({:.0}% reduction)",
html.len(),
compressed.len(),
(1.0 - compressed.len() as f64 / html.len() as f64) * 100.0
);
println!(
"cargo:rustc-env=RUSTY_COLLARS_APP_VERSION={}",
version
);
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=Cargo.toml");
println!("cargo:rerun-if-changed=src");
println!("cargo:rerun-if-changed=frontend");
}
fn app_version() -> String {
let package_version = std::env::var("CARGO_PKG_VERSION").expect("missing CARGO_PKG_VERSION");
let git_revision =
git_output(&["rev-parse", "--short=12", "HEAD"]).unwrap_or_else(|| "nogit".to_string());
let dirty_suffix = if git_is_dirty() { "-dirty" } else { "" };
let build_unix_s = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("system time before UNIX_EPOCH")
.as_secs();
format!("{package_version}+{git_revision}{dirty_suffix}.{build_unix_s}")
}
fn git_is_dirty() -> bool {
match std::process::Command::new("git")
.args(["status", "--porcelain", "--untracked-files=no"])
.output()
{
Ok(output) => !output.stdout.is_empty(),
Err(_) => false,
}
}
fn git_output(args: &[&str]) -> Option<String> {
let output = std::process::Command::new("git").args(args).output().ok()?;
if !output.status.success() {
return None;
}
let value = String::from_utf8(output.stdout).ok()?;
let trimmed = value.trim();
if trimmed.is_empty() {
None
} else {
Some(trimmed.to_string())
}
}