devin15/cursor2api-rust
0
1use sha2::{Digest, Sha256};2use std::collections::HashMap;3use std::fs;4use std::io::Result;5use std::path::{Path, PathBuf};6use std::process::Command;7 8// 支持的文件类型9const SUPPORTED_EXTENSIONS: [&str; 3] = ["html", "js", "css"];10 11fn check_and_install_deps() -> Result<()> {12 let scripts_dir = Path::new("scripts");13 let node_modules = scripts_dir.join("node_modules");14 15 if !node_modules.exists() {16 println!("cargo:warning=Installing minifier dependencies...");17 let status = Command::new("npm")18 .current_dir(scripts_dir)19 .arg("install")20 .status()?;21 22 if !status.success() {23 panic!("Failed to install npm dependencies");24 }25 println!("cargo:warning=Dependencies installed successfully");26 }27 Ok(())28}29 30fn get_files_hash() -> Result<HashMap<PathBuf, String>> {31 let mut file_hashes = HashMap::new();32 let static_dir = Path::new("static");33 34 if static_dir.exists() {35 for entry in fs::read_dir(static_dir)? {36 let entry = entry?;37 let path = entry.path();38 39 // 检查是否是支持的文件类型,且不是已经压缩的文件40 if let Some(ext) = path.extension().and_then(|e| e.to_str()) {41 if SUPPORTED_EXTENSIONS.contains(&ext) && !path.to_string_lossy().contains(".min.")42 {43 let content = fs::read(&path)?;44 let mut hasher = Sha256::new();45 hasher.update(&content);46 let hash = format!("{:x}", hasher.finalize());47 file_hashes.insert(path, hash);48 }49 }50 }51 }52 53 Ok(file_hashes)54}55 56fn load_saved_hashes() -> Result<HashMap<PathBuf, String>> {57 let hash_file = Path::new("scripts/.asset-hashes.json");58 if hash_file.exists() {59 let content = fs::read_to_string(hash_file)?;60 let hash_map: HashMap<String, String> = serde_json::from_str(&content)?;61 Ok(hash_map62 .into_iter()63 .map(|(k, v)| (PathBuf::from(k), v))64 .collect())65 } else {66 Ok(HashMap::new())67 }68}69 70fn save_hashes(hashes: &HashMap<PathBuf, String>) -> Result<()> {71 let hash_file = Path::new("scripts/.asset-hashes.json");72 let string_map: HashMap<String, String> = hashes73 .iter()74 .map(|(k, v)| (k.to_string_lossy().into_owned(), v.clone()))75 .collect();76 let content = serde_json::to_string_pretty(&string_map)?;77 fs::write(hash_file, content)?;78 Ok(())79}80 81fn minify_assets() -> Result<()> {82 // 获取现有文件的哈希83 let current_hashes = get_files_hash()?;84 85 if current_hashes.is_empty() {86 println!("cargo:warning=No files to minify");87 return Ok(());88 }89 90 // 加载保存的哈希值91 let saved_hashes = load_saved_hashes()?;92 93 // 找出需要更新的文件94 let files_to_update: Vec<_> = current_hashes95 .iter()96 .filter(|(path, current_hash)| {97 let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("");98 let min_path = path.with_file_name(format!(99 "{}.min.{}",100 path.file_stem().unwrap().to_string_lossy(),101 ext102 ));103 104 // 检查压缩后的文件是否存在105 if !min_path.exists() {106 return true;107 }108 109 // 检查原始文件是否发生变化110 saved_hashes111 .get(*path)112 .map_or(true, |saved_hash| saved_hash != *current_hash)113 })114 .map(|(path, _)| path.file_name().unwrap().to_string_lossy().into_owned())115 .collect();116 117 if files_to_update.is_empty() {118 println!("cargo:warning=No files need to be updated");119 return Ok(());120 }121 122 println!("cargo:warning=Minifying {} files...", files_to_update.len());123 124 // 运行压缩脚本125 let status = Command::new("node")126 .arg("scripts/minify.js")127 .args(&files_to_update)128 .status()?;129 130 if !status.success() {131 panic!("Asset minification failed");132 }133 134 // 保存新的哈希值135 save_hashes(¤t_hashes)?;136 137 Ok(())138}139 140fn main() -> Result<()> {141 // Proto 文件处理142 println!("cargo:rerun-if-changed=src/chat/aiserver/v1/lite.proto");143 let mut config = prost_build::Config::new();144 // config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]");145 // config.type_attribute(146 // "aiserver.v1.ThrowErrorCheckRequest",147 // "#[derive(serde::Serialize, serde::Deserialize)]"148 // );149 config150 .compile_protos(&["src/chat/aiserver/v1/lite.proto"], &["src/chat/aiserver/v1/"])151 .unwrap();152 153 // 静态资源文件处理154 println!("cargo:rerun-if-changed=scripts/minify.js");155 println!("cargo:rerun-if-changed=scripts/package.json");156 println!("cargo:rerun-if-changed=static");157 158 // 检查并安装依赖159 check_and_install_deps()?;160 161 // 运行资源压缩162 minify_assets()?;163 164 Ok(())165}166 