82 lines
2.8 KiB
Rust
82 lines
2.8 KiB
Rust
use std::collections::BTreeMap;
|
|
use std::path::Path;
|
|
|
|
fn main() {
|
|
let version = std::env::var("CARGO_PKG_VERSION").unwrap_or_else(|_| "unknown".to_string());
|
|
|
|
let git_hash = std::process::Command::new("git")
|
|
.args(["rev-parse", "--short", "HEAD"])
|
|
.output()
|
|
.ok()
|
|
.and_then(|o| String::from_utf8(o.stdout).ok())
|
|
.map(|s| s.trim().to_string())
|
|
.unwrap_or_else(|| "unknown".to_string());
|
|
|
|
let timestamp = std::process::Command::new("date")
|
|
.args(["-u", "+%Y-%m-%dT%H:%M:%SZ"])
|
|
.output()
|
|
.ok()
|
|
.and_then(|o| String::from_utf8(o.stdout).ok())
|
|
.map(|s| s.trim().to_string())
|
|
.unwrap_or_else(|| "unknown".to_string());
|
|
|
|
println!("cargo:rustc-env=BUILD_VERSION={}", version);
|
|
println!("cargo:rustc-env=BUILD_GIT_HASH={}", git_hash);
|
|
println!("cargo:rustc-env=BUILD_TIMESTAMP={}", timestamp);
|
|
|
|
// ── Schema migration manifest ──
|
|
// Scan release/migrate_*.sql, compute SHA256, embed as JSON string
|
|
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string());
|
|
let release_dir = Path::new(&manifest_dir).join("release");
|
|
|
|
let mut migrations = BTreeMap::new(); // sorted by filename
|
|
if let Ok(entries) = std::fs::read_dir(&release_dir) {
|
|
for entry in entries.flatten() {
|
|
let path = entry.path();
|
|
let fname = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
|
|
if fname.starts_with("migrate_") && fname.ends_with(".sql") {
|
|
if let Ok(content) = std::fs::read(&path) {
|
|
let hash = sha256_hex(&content);
|
|
migrations.insert(fname.to_string(), hash);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Encode as comma-separated: name1:hash1,name2:hash2,...
|
|
let manifest: String = migrations
|
|
.iter()
|
|
.map(|(name, hash)| format!("{}:{}", name, hash))
|
|
.collect::<Vec<_>>()
|
|
.join(",");
|
|
println!("cargo:rustc-env=REQUIRED_MIGRATIONS={}", manifest);
|
|
println!(
|
|
"cargo:info=Embedded {} migration checksums",
|
|
migrations.len()
|
|
);
|
|
}
|
|
|
|
fn sha256_hex(data: &[u8]) -> String {
|
|
use std::io::Write;
|
|
use std::process::{Command, Stdio};
|
|
if let Ok(mut child) = Command::new("shasum")
|
|
.arg("-a")
|
|
.arg("256")
|
|
.stdin(Stdio::piped())
|
|
.stdout(Stdio::piped())
|
|
.spawn()
|
|
{
|
|
if let Some(mut stdin) = child.stdin.take() {
|
|
let _ = stdin.write_all(data);
|
|
}
|
|
if let Ok(out) = child.wait_with_output() {
|
|
if let Ok(s) = String::from_utf8(out.stdout) {
|
|
if let Some(hash) = s.split(' ').next() {
|
|
return hash.to_string();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"unknown".to_string()
|
|
}
|