CoolFace
Apppublic

devin15/cursor2api-rust

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
build.rs166 linesDownload Raw Back to root
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(&current_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