|
use sha2::{Digest, Sha256}; |
|
use std::collections::HashMap; |
|
use std::fs; |
|
use std::io::Result; |
|
use std::path::{Path, PathBuf}; |
|
use std::process::Command; |
|
|
|
|
|
const SUPPORTED_EXTENSIONS: [&str; 3] = ["html", "js", "css"]; |
|
|
|
fn check_and_install_deps() -> Result<()> { |
|
let scripts_dir = Path::new("scripts"); |
|
let node_modules = scripts_dir.join("node_modules"); |
|
|
|
if !node_modules.exists() { |
|
println!("cargo:warning=Installing minifier dependencies..."); |
|
let status = Command::new("npm") |
|
.current_dir(scripts_dir) |
|
.arg("install") |
|
.status()?; |
|
|
|
if !status.success() { |
|
panic!("Failed to install npm dependencies"); |
|
} |
|
println!("cargo:warning=Dependencies installed successfully"); |
|
} |
|
Ok(()) |
|
} |
|
|
|
fn get_files_hash() -> Result<HashMap<PathBuf, String>> { |
|
let mut file_hashes = HashMap::new(); |
|
let static_dir = Path::new("static"); |
|
|
|
if static_dir.exists() { |
|
for entry in fs::read_dir(static_dir)? { |
|
let entry = entry?; |
|
let path = entry.path(); |
|
|
|
|
|
if let Some(ext) = path.extension().and_then(|e| e.to_str()) { |
|
if SUPPORTED_EXTENSIONS.contains(&ext) && !path.to_string_lossy().contains(".min.") |
|
{ |
|
let content = fs::read(&path)?; |
|
let mut hasher = Sha256::new(); |
|
hasher.update(&content); |
|
let hash = format!("{:x}", hasher.finalize()); |
|
file_hashes.insert(path, hash); |
|
} |
|
} |
|
} |
|
} |
|
|
|
Ok(file_hashes) |
|
} |
|
|
|
fn load_saved_hashes() -> Result<HashMap<PathBuf, String>> { |
|
let hash_file = Path::new("scripts/.asset-hashes.json"); |
|
if hash_file.exists() { |
|
let content = fs::read_to_string(hash_file)?; |
|
let hash_map: HashMap<String, String> = serde_json::from_str(&content)?; |
|
Ok(hash_map |
|
.into_iter() |
|
.map(|(k, v)| (PathBuf::from(k), v)) |
|
.collect()) |
|
} else { |
|
Ok(HashMap::new()) |
|
} |
|
} |
|
|
|
fn save_hashes(hashes: &HashMap<PathBuf, String>) -> Result<()> { |
|
let hash_file = Path::new("scripts/.asset-hashes.json"); |
|
let string_map: HashMap<String, String> = hashes |
|
.iter() |
|
.map(|(k, v)| (k.to_string_lossy().into_owned(), v.clone())) |
|
.collect(); |
|
let content = serde_json::to_string_pretty(&string_map)?; |
|
fs::write(hash_file, content)?; |
|
Ok(()) |
|
} |
|
|
|
fn minify_assets() -> Result<()> { |
|
|
|
let current_hashes = get_files_hash()?; |
|
|
|
if current_hashes.is_empty() { |
|
println!("cargo:warning=No files to minify"); |
|
return Ok(()); |
|
} |
|
|
|
|
|
let saved_hashes = load_saved_hashes()?; |
|
|
|
|
|
let files_to_update: Vec<_> = current_hashes |
|
.iter() |
|
.filter(|(path, current_hash)| { |
|
let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(""); |
|
let min_path = path.with_file_name(format!( |
|
"{}.min.{}", |
|
path.file_stem().unwrap().to_string_lossy(), |
|
ext |
|
)); |
|
|
|
|
|
if !min_path.exists() { |
|
return true; |
|
} |
|
|
|
|
|
saved_hashes |
|
.get(*path) |
|
.map_or(true, |saved_hash| saved_hash != *current_hash) |
|
}) |
|
.map(|(path, _)| path.file_name().unwrap().to_string_lossy().into_owned()) |
|
.collect(); |
|
|
|
if files_to_update.is_empty() { |
|
println!("cargo:warning=No files need to be updated"); |
|
return Ok(()); |
|
} |
|
|
|
println!("cargo:warning=Minifying {} files...", files_to_update.len()); |
|
|
|
|
|
let status = Command::new("node") |
|
.arg("scripts/minify.js") |
|
.args(&files_to_update) |
|
.status()?; |
|
|
|
if !status.success() { |
|
panic!("Asset minification failed"); |
|
} |
|
|
|
|
|
save_hashes(¤t_hashes)?; |
|
|
|
Ok(()) |
|
} |
|
|
|
fn main() -> Result<()> { |
|
|
|
println!("cargo:rerun-if-changed=src/chat/aiserver/v1/lite.proto"); |
|
let mut config = prost_build::Config::new(); |
|
|
|
|
|
|
|
|
|
|
|
config |
|
.compile_protos(&["src/chat/aiserver/v1/lite.proto"], &["src/chat/aiserver/v1/"]) |
|
.unwrap(); |
|
|
|
|
|
println!("cargo:rerun-if-changed=scripts/minify.js"); |
|
println!("cargo:rerun-if-changed=scripts/package.json"); |
|
println!("cargo:rerun-if-changed=static"); |
|
|
|
|
|
check_and_install_deps()?; |
|
|
|
|
|
minify_assets()?; |
|
|
|
Ok(()) |
|
} |
|
|