feat: schema version tracking, SHA256 integrity, setup scripts, bug fixes

This commit is contained in:
Accusys
2026-05-15 18:06:36 +08:00
parent 0e73d2a2ce
commit c41f7e0c6e
567 changed files with 55195 additions and 24 deletions

View File

@@ -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()
}