feat: schema version tracking, SHA256 integrity, setup scripts, bug fixes
This commit is contained in:
57
build.rs
57
build.rs
@@ -1,3 +1,6 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let version = std::env::var("CARGO_PKG_VERSION").unwrap_or_else(|_| "unknown".to_string());
|
||||
|
||||
@@ -20,4 +23,58 @@ fn main() {
|
||||
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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user