use anyhow::Result; use crabsoup_mlua_analyze::LuaAnalyzerBuilder; use mlua::Compiler; use std::path::PathBuf; fn compile_script(input: &[u8], has_require: bool) -> Vec { let mut compiler = Compiler::new() .set_optimization_level(2) .set_type_info_level(1); if has_require { compiler = compiler.set_mutable_globals(vec!["require".to_string(), "require_env".to_string()]); } compiler.compile(input) } pub fn main() -> Result<()> { let mut out_path = PathBuf::from(std::env::var("OUT_DIR")?); out_path.push("luau_compiled"); std::fs::create_dir_all(&out_path)?; let mut all_paths = Vec::new(); let mut analyze = LuaAnalyzerBuilder::new(); analyze.add_definitions("defs_shared.d_lua", include_str!("lua/defs/defs_shared.d_lua")); analyze .add_definitions("defs_standalone.d_lua", include_str!("lua/defs/defs_standalone.d_lua")); let analyze = analyze.build(); for path in glob::glob("lua/**/*")? { let path = path?; let file_name = path.file_name().unwrap().to_string_lossy(); let suffix = path.strip_prefix("lua/")?; let str_path = path .to_string_lossy() .strip_prefix("lua/") .unwrap() .to_string(); if path.is_file() && (file_name.ends_with(".lua") || file_name.ends_with(".luau")) { let mut output = out_path.clone(); output.push(suffix); let script = std::fs::read_to_string(&path)?; let name = path.file_name().unwrap().to_string_lossy(); let result = analyze.check(&name, &script, false); if result.iter().any(|x| x.is_error) { println!("{result:#?}"); panic!("Error in script: {name}"); } let mut parent = output.clone(); parent.pop(); std::fs::create_dir_all(parent)?; std::fs::write( &output, compile_script(script.as_bytes(), !suffix.starts_with("app/")), )?; all_paths.push((str_path, output.to_string_lossy().to_string())); } else if path.is_file() { all_paths.push((str_path, path.canonicalize()?.to_string_lossy().to_string())); } println!("cargo::rerun-if-changed={}", path.display()); } out_path.pop(); out_path.push("luau_modules.rs"); let mut push_lines = Vec::new(); for (k, v) in all_paths { push_lines.push(format!(r#"map.insert({k:?}, include_bytes!({v:?}).as_slice());"#)); } let push_lines = push_lines.join("\n"); std::fs::write( out_path, format!( r#" fn load_lua_sources() -> crate::wyhash::WyHashMap<&'static str, &'static [u8]> {{ let mut map = crate::wyhash::WyHashMap::default(); {push_lines} map }} "# ), )?; Ok(()) }