about summary refs log tree commit diff
path: root/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs97
1 files changed, 97 insertions, 0 deletions
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..417f61c
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,97 @@
+use std::{
+  env, fs,
+  io::Write,
+  path::{Path, PathBuf},
+};
+
+const IGNORE_DIRS: &[&str] = &[];
+
+const IGNORE_FILES: &[&str] = &["main.lua"];
+
+fn main() {
+  let crate_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
+  let lua_src = crate_root.join("lua_src");
+  let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+  let out_file = out_dir.join("bundled_modules.rs");
+
+  println!("cargo:rerun-if-changed=lua_src");
+
+  let mut entries: Vec<(String, String)> = Vec::new();
+  collect(&lua_src, &lua_src, &mut entries);
+
+  // Files are sorted alphabetically here to make output deterministic
+  entries.sort_by(|a, b| a.0.cmp(&b.0));
+
+  let mut out = match fs::File::create(&out_file) {
+    Ok(f) => f,
+    Err(e) => {
+      eprintln!(
+        "ERROR: could not write to '{}': {e}",
+        out_file.display()
+      );
+      std::process::exit(1);
+    }
+  };
+
+  writeln!(out, "// AUTO-GENERATED by build.rs").unwrap();
+  writeln!(out, "pub const BUNDLED_MODULES: &[(&str, &str)] = &[").unwrap();
+
+  for (module_name, rel_path) in &entries {
+    writeln!(
+            out,
+            r#"    ("{module_name}", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lua_src/{rel_path}"))),"#
+        ).unwrap();
+  }
+
+  writeln!(out, "];").unwrap();
+
+  eprintln!("INFORMATION: Bundled {} Lua module(s)", entries.len());
+  for (name, path) in &entries {
+    eprintln!("               {name:30} ← lua_src/{path}");
+  }
+}
+
+fn collect(root: &Path, dir: &Path, out: &mut Vec<(String, String)>) {
+  let entries = match fs::read_dir(dir) {
+    Ok(e) => e,
+    Err(e) => {
+      eprintln!("ERROR: could not read '{}': {e}", dir.display());
+      return;
+    }
+  };
+
+  for entry in entries.flatten() {
+    let path = entry.path();
+    let file_name = path.file_name().unwrap().to_string_lossy();
+
+    if path.is_dir() {
+      if IGNORE_DIRS.contains(&file_name.as_ref()) {
+        eprintln!("INFORMATION: skipping directory lua_src/{file_name}/");
+        continue;
+      }
+      collect(root, &path, out);
+      continue;
+    }
+
+    if path.extension().and_then(|e| e.to_str()) != Some("lua") {
+      continue;
+    }
+
+    let rel = path.strip_prefix(root).unwrap();
+    let rel_str = rel.to_string_lossy();
+
+    if IGNORE_FILES.contains(&rel_str.as_ref()) {
+      eprintln!("INFORMATION: skipping file 'lua_src/{rel_str}'");
+      continue;
+    }
+
+    let module_name = rel
+      .with_extension("")
+      .components()
+      .map(|c| c.as_os_str().to_string_lossy())
+      .collect::<Vec<_>>()
+      .join(".");
+
+    out.push((module_name, rel_str.replace('\\', "/")));
+  }
+}