Skip to content

Commit

Permalink
Merge pull request #2188 from alerque/snafu
Browse files Browse the repository at this point in the history
Properly format errors, avoid erroring after already triggering an error
  • Loading branch information
alerque authored Dec 5, 2024
2 parents 154f441 + 6dc7e6d commit cdc3ba9
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 43 deletions.
2 changes: 0 additions & 2 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ globals = {
"luautf8",
"pl",
"fluent",
"executablePath",
"extendSilePath",
}
max_line_length = false
ignore = {
Expand Down
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ version = "0.15.7"
[dependencies.anyhow]
version = "1.0"

[dependencies.snafu]
version = "0.8"

[dependencies.clap]
version = "4.4"
optional = true
Expand Down
4 changes: 2 additions & 2 deletions core/sile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,10 @@ local function runEvals (evals, arg)
for _, snippet in ipairs(evals) do
local pId = SILE.traceStack:pushText(snippet)
local status, func = pcall(load, snippet)
if status then
if status and type(func) == "function" then
func()
else
SU.error(("Error parsing code provided in --%s snippet: %s"):format(arg, func))
SU.error(("Error parsing code provided in --%s snippet: %s"):format(arg, snippet))
end
SILE.traceStack:pop(pId)
end
Expand Down
2 changes: 1 addition & 1 deletion core/utilities/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ function utilities.error (message, isbug)
utilities.warn(message, isbug)
_skip_traceback_levels = 2
io.stderr:flush()
SILE.outputter:finish() -- Only really useful from the REPL but no harm in trying
SILE.outputter:finish()
SILE.scratch.caughterror = true
error("", 2)
end
Expand Down
13 changes: 7 additions & 6 deletions outputters/libtexpdf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,13 @@ end
function outputter._endHook (_) end

function outputter:finish ()
self:_ensureInit()
pdf.endpage()
self:runHooks("prefinish")
pdf.finish()
started = false
lastkey = nil
if started then
pdf.endpage()
self:runHooks("prefinish")
pdf.finish()
started = false
lastkey = nil
end
end

function outputter.getCursor (_)
Expand Down
1 change: 0 additions & 1 deletion rusile.rockspec.in
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ build = {
"ru@PACKAGE_NAME@",
},
}

35 changes: 30 additions & 5 deletions src/bin/sile.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,42 @@
use sile::cli::Cli;

use snafu::prelude::*;

use clap::{CommandFactory, FromArgMatches};

use sile::cli::Cli;
use sile::Result;
#[derive(Snafu)]
enum Error {
#[snafu(display("{}", source))]
Args { source: clap::error::Error },

#[snafu(display("{}", source))]
Runtime { source: anyhow::Error },

#[snafu(display("{}", source))]
Version { source: anyhow::Error },
}

// Deeper error types are reported using the Debug trait, but we handle them via Snafu and the Display trait.
// So we delegate. c.f. https://github.com/shepmaster/snafu/issues/110
impl std::fmt::Debug for Error {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(self, fmt)
}
}

type Result<T, E = Error> = std::result::Result<T, E>;

fn main() -> Result<()> {
let version = option_env!("VERGEN_GIT_DESCRIBE").unwrap_or_else(|| env!("CARGO_PKG_VERSION"));
let version = version.replacen('-', ".r", 1);
let long_version = sile::version()?
let long_version = sile::version()
.context(VersionSnafu)?
.strip_prefix("SILE ")
.unwrap_or("")
.to_string();
let app = Cli::command().version(version).long_version(long_version);
let matches = app.get_matches();
let args = Cli::from_arg_matches(&matches).expect("Unable to parse arguments");
let args = Cli::from_arg_matches(&matches).context(ArgsSnafu)?;
sile::run(
args.input,
args.backend,
Expand All @@ -29,6 +53,7 @@ fn main() -> Result<()> {
args.r#use,
args.quiet,
args.traceback,
)?;
)
.context(RuntimeSnafu)?;
Ok(())
}
3 changes: 2 additions & 1 deletion src/embed.rs.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extern "C-unwind" {
/// Register a Lua function in the loaders/searchers table to return C modules linked into the CLI
/// binary and another to return embedded Lua resources as Lua modules. See discussion in mlua:
/// https://github.com/khvzak/mlua/discussions/322
pub fn inject_embedded_loaders(lua: &Lua) {
pub fn inject_embedded_loaders(lua: Lua) -> crate::Result<Lua> {
let package: LuaTable = lua.globals().get("package").unwrap();
let loaders: LuaTable = match package.get("loaders").unwrap() {
LuaValue::Table(loaders) => loaders,
Expand Down Expand Up @@ -164,4 +164,5 @@ pub fn inject_embedded_loaders(lua: &Lua) {
})
.unwrap();
loaders.push(embedded_ftl_loader).unwrap();
Ok(lua)
}
55 changes: 30 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// rust-embed include attributes have issues with lots of matches...
#![recursion_limit = "2048"]

use mlua::prelude::*;

#[cfg(not(feature = "static"))]
use mlua::chunk;
use mlua::prelude::*;
use std::{env, path::PathBuf};
use std::env;
use std::path::PathBuf;

#[cfg(feature = "cli")]
pub mod cli;

Expand All @@ -16,29 +19,30 @@ pub mod types;
pub type Result<T> = anyhow::Result<T>;

pub fn start_luavm() -> crate::Result<Lua> {
let lua = unsafe { Lua::unsafe_new() };
let mut lua = unsafe { Lua::unsafe_new() };
#[cfg(feature = "static")]
crate::embed::inject_embedded_loaders(&lua);
inject_paths(&lua);
load_sile(&lua);
inject_version(&lua);
{
lua = embed::inject_embedded_loaders(lua)?;
}
lua = inject_paths(lua)?;
lua = load_sile(lua)?;
lua = inject_version(lua)?;
Ok(lua)
}

pub fn inject_paths(lua: &Lua) {
pub fn inject_paths(lua: Lua) -> crate::Result<Lua> {
#[cfg(feature = "static")]
lua.load(r#"require("core.pathsetup")"#)
.set_name("relative pathsetup loader")
.exec()
.unwrap();
.exec()?;
#[cfg(not(feature = "static"))]
{
let datadir = env!("CONFIGURE_DATADIR").to_string();
let sile_path = match env::var("SILE_PATH") {
Ok(val) => format!("{datadir};{val}"),
Err(_) => datadir,
};
let sile_path: LuaString = lua.create_string(&sile_path).unwrap();
let sile_path: LuaString = lua.create_string(&sile_path)?;
lua.load(chunk! {
local status
for path in string.gmatch($sile_path, "[^;]+") do
Expand All @@ -50,9 +54,9 @@ pub fn inject_paths(lua: &Lua) {
end
})
.set_name("hard coded pathsetup loader")
.exec()
.unwrap();
.exec()?;
}
Ok(lua)
}

pub fn get_rusile_exports(lua: &Lua) -> LuaResult<LuaTable> {
Expand All @@ -62,28 +66,29 @@ pub fn get_rusile_exports(lua: &Lua) -> LuaResult<LuaTable> {
Ok(exports)
}

fn setenv(key: String, value: String) -> LuaResult<()> {
fn setenv(key: String, value: String) {
env::set_var(key, value);
Ok(())
}

pub fn inject_version(lua: &Lua) {
let sile: LuaTable = lua.globals().get("SILE").unwrap();
let mut full_version: String = sile.get("full_version").unwrap();
pub fn inject_version(lua: Lua) -> crate::Result<Lua> {
let sile: LuaTable = lua.globals().get("SILE")?;
let mut full_version: String = sile.get("full_version")?;
full_version.push_str(" [Rust]");
sile.set("full_version", full_version).unwrap();
sile.set("full_version", full_version)?;
Ok(lua)
}

pub fn load_sile(lua: &Lua) {
let entry: LuaString = lua.create_string("core.sile").unwrap();
let require: LuaFunction = lua.globals().get("require").unwrap();
require.call::<LuaTable>(entry).unwrap();
pub fn load_sile(lua: Lua) -> crate::Result<Lua> {
let entry: LuaString = lua.create_string("core.sile")?;
let require: LuaFunction = lua.globals().get("require")?;
require.call::<LuaTable>(entry)?;
Ok(lua)
}

pub fn version() -> crate::Result<String> {
let lua = start_luavm()?;
let sile: LuaTable = lua.globals().get("SILE").unwrap();
let full_version: String = sile.get("full_version").unwrap();
let sile: LuaTable = lua.globals().get("SILE")?;
let full_version: String = sile.get("full_version")?;
Ok(full_version)
}

Expand Down

0 comments on commit cdc3ba9

Please sign in to comment.