feat(dtmt): Improve error messages when compiling Lua

Fixes #58.
This commit is contained in:
Lucas Schwiderski 2023-03-08 21:27:29 +01:00
parent 53b24cc045
commit 308613d5fc
Signed by: lucas
GPG key ID: AA12679AAA6DF4D8
4 changed files with 37 additions and 35 deletions

View file

@ -1,4 +1,3 @@
use std::ffi::CString;
use std::io::{Cursor, ErrorKind};
use std::path::{Path, PathBuf};
use std::str::FromStr;
@ -216,7 +215,6 @@ async fn build_bundles(state: Arc<ActionState>) -> Result<Vec<Bundle>> {
let _enter = span.enter();
let lua = build_mod_data_lua(state.clone());
let lua = CString::new(lua).wrap_err("Failed to build CString from mod data Lua string")?;
let file =
lua::compile(MOD_DATA_SCRIPT, &lua).wrap_err("Failed to compile mod data Lua file")?;
@ -437,9 +435,8 @@ async fn patch_boot_bundle(state: Arc<ActionState>) -> Result<Vec<Bundle>> {
let _enter = span.enter();
let lua = include_str!("../../assets/mod_main.lua");
let lua = CString::new(lua).wrap_err("Failed to build CString from mod main Lua string")?;
let file =
lua::compile(MOD_BOOT_SCRIPT, &lua).wrap_err("Failed to compile mod main Lua file")?;
lua::compile(MOD_BOOT_SCRIPT, lua).wrap_err("Failed to compile mod main Lua file")?;
boot_bundle.add_file(file);
}

View file

@ -151,17 +151,6 @@ where
results.into_iter().collect()
}
#[tracing::instrument(skip_all, fields(files = files.len()))]
fn compile_bundle(name: String, files: Vec<BundleFile>) -> Result<Bundle> {
let mut bundle = Bundle::new(name);
for file in files {
bundle.add_file(file);
}
Ok(bundle)
}
#[tracing::instrument]
async fn build_package<P1, P2>(package: P1, root: P2) -> Result<Bundle>
where
@ -182,18 +171,20 @@ where
.await
.wrap_err_with(|| format!("Invalid package file {}", &pkg_name))?;
compile_package_files(&pkg, root)
.await
.wrap_err("Failed to compile package")
.and_then(|files| compile_bundle(pkg_name, files))
.wrap_err("Failed to build bundle")
let files = compile_package_files(&pkg, root).await?;
let mut bundle = Bundle::new(pkg_name);
for file in files {
bundle.add_file(file);
}
Ok(bundle)
}
fn normalize_file_path<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
let path = path.as_ref();
if path.is_absolute() || path.has_root() {
let err = eyre::eyre!("path is absolute: {}", path.display());
let err = eyre::eyre!("Path is absolute: {}", path.display());
return Err(err).with_suggestion(|| "Specify a relative file path.".to_string());
}
@ -302,7 +293,7 @@ pub(crate) async fn run(_ctx: sdk::Context, matches: &ArgMatches) -> Result<()>
let bundle = build_package(path, &cfg.dir).await.wrap_err_with(|| {
format!(
"failed to build package {} in {}",
"Failed to build package '{}' at '{}'",
path.display(),
cfg.dir.display()
)

View file

@ -1,4 +1,3 @@
use std::ffi::CString;
use std::io::{Cursor, Read, Seek, Write};
use std::path::Path;
@ -660,11 +659,8 @@ impl BundleFile {
S: AsRef<str>,
{
match file_type {
BundleFileType::Lua => {
let sjson =
CString::new(sjson.as_ref()).wrap_err("Failed to build CString from SJSON")?;
lua::compile(name, sjson)
}
BundleFileType::Lua => lua::compile(name.clone(), sjson)
.wrap_err_with(|| format!("Failed to compile Lua file '{}'", name)),
BundleFileType::Unknown(_) => {
eyre::bail!("Unknown file type. Cannot compile from SJSON");
}

View file

@ -25,7 +25,7 @@ where
pub fn compile<S, C>(name: S, code: C) -> Result<BundleFile>
where
S: Into<String>,
C: AsRef<CStr>,
C: AsRef<str>,
{
let name = name.into();
let code = code.as_ref();
@ -34,15 +34,33 @@ where
let state = lua::luaL_newstate();
lua::luaL_openlibs(state);
lua::lua_pushstring(state, code.as_ptr() as _);
lua::lua_setglobal(state, b"code\0".as_ptr() as _);
let name = CString::new(name.as_bytes())
.wrap_err_with(|| format!("Cannot convert name into CString: {}", name))?;
lua::lua_pushstring(state, name.as_ptr() as _);
lua::lua_setglobal(state, b"name\0".as_ptr() as _);
match lua::luaL_loadbuffer(
state,
code.as_ptr() as _,
code.len() as _,
name.as_ptr() as _,
) as u32
{
lua::LUA_OK => {}
lua::LUA_ERRSYNTAX => {
let err = lua::lua_tostring(state, -1);
let err = CStr::from_ptr(err).to_string_lossy().to_string();
let run = b"return string.dump(loadstring(code, \"@\" .. name), false)\0";
lua::lua_close(state);
eyre::bail!("Invalid syntax: {}", err);
}
lua::LUA_ERRMEM => {
lua::lua_close(state);
eyre::bail!("Failed to allocate sufficient memory to compile LuaJIT bytecode")
}
_ => unreachable!(),
}
lua::lua_setglobal(state, b"fn\0".as_ptr() as _);
let run = b"return string.dump(fn, false)\0";
match lua::luaL_loadstring(state, run.as_ptr() as _) as u32 {
lua::LUA_OK => {}
lua::LUA_ERRSYNTAX => {