diff --git a/Cargo.lock b/Cargo.lock index ce977c2..4e59b6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -544,24 +544,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" dependencies = [ "backtrace", - "color-spantrace", "eyre", "indenter", "once_cell", "owo-colors", - "tracing-error", -] - -[[package]] -name = "color-spantrace" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" -dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", + "url", ] [[package]] @@ -1003,6 +990,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fragile" version = "2.0.0" @@ -1437,6 +1433,16 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "image" version = "0.25.1" @@ -1956,6 +1962,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -2383,15 +2395,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shellexpand" version = "3.1.0" @@ -2593,6 +2596,21 @@ dependencies = [ "weezl", ] +[[package]] +name = "tinyvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "toml_datetime" version = "0.6.6" @@ -2650,28 +2668,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-error" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" -dependencies = [ - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "sharded-slab", - "thread_local", - "tracing-core", ] [[package]] @@ -2727,18 +2723,44 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "urlencoding" version = "2.1.3" @@ -2751,12 +2773,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index ec1a5dc..28fb87f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ arboard = "3.4.0" chrono = { version = "0.4.38", default-features = false } clap = "4.5.7" clap-verbosity-flag = "2.2.0" -color-eyre = "0.6.3" +color-eyre = { version = "0.6.3", default-features = false } enumflags2 = "0.7.10" exec = "0.3.1" fern = "0.6.2" @@ -48,11 +48,13 @@ nameof = "1.2.2" nix = "0.29.0" open = "5.1.4" procfs = "0.16.0" +quote = "1.0.36" rstest = "0.21.0" serde = { version = "1.0.203", features = ["derive"] } shellexpand = "3.1.0" single-instance = "0.3.3" stderrlog = { version = "0.6.0", default-features = false } +syn = "2.0.68" sysinfo = "0.30.12" system_shutdown = "4.0.1" thiserror = "1.0.61" @@ -100,3 +102,4 @@ unwrap_used = "warn" use_self = "warn" used_underscore_binding = "warn" wildcard_imports = "warn" +missing_panics_doc = "warn" diff --git a/gravel-ffi-macros/Cargo.toml b/gravel-ffi-macros/Cargo.toml index a0d8a93..072d3ae 100644 --- a/gravel-ffi-macros/Cargo.toml +++ b/gravel-ffi-macros/Cargo.toml @@ -7,8 +7,8 @@ edition.workspace = true proc-macro = true [dependencies] -quote = "1.0.36" -syn = { version = "2.0.68", features = ["full"] } +quote.workspace = true +syn.workspace = true [lints] workspace = true diff --git a/gravel-ffi/src/logging.rs b/gravel-ffi/src/logging.rs index 66f90ea..97163fe 100644 --- a/gravel-ffi/src/logging.rs +++ b/gravel-ffi/src/logging.rs @@ -65,6 +65,8 @@ pub struct ForwardLogger { } impl ForwardLogger { + /// # Panics + /// When called more than once. See `log::set_logger`. pub fn register(target: BoxDynLogTarget, crate_name: &'static str) { log::set_max_level(target.max_level().into()); log::set_logger(Box::leak(Box::new(Self { target }))).expect("logger must only be registered once per plugin"); diff --git a/gravel-ffi/src/paths.rs b/gravel-ffi/src/paths.rs index fc245e8..e189f79 100644 --- a/gravel-ffi/src/paths.rs +++ b/gravel-ffi/src/paths.rs @@ -3,6 +3,8 @@ use std::{env, iter::once, path::PathBuf}; const XDG_DATA_HOME: &str = "XDG_DATA_HOME"; const XDG_DATA_DIRS: &str = "XDG_DATA_DIRS"; +/// # Panics +/// When $HOME/$USERPROFILE are not set. pub fn home() -> PathBuf { #[cfg(unix)] let home = env::var("HOME").expect("$HOME must always be set"); diff --git a/gravel-ffi/tests/plugin_load_test.rs b/gravel-ffi/tests/plugin_load_test.rs index 053938c..afcd56b 100644 --- a/gravel-ffi/tests/plugin_load_test.rs +++ b/gravel-ffi/tests/plugin_load_test.rs @@ -1,4 +1,4 @@ -#![allow(unused_crate_dependencies)] +#![allow(unused_crate_dependencies, clippy::missing_panics_doc)] use abi_stable::std_types::{ROption, RSlice, RString}; use abi_stable::{library::RootModule, sabi_trait, traits::IntoReprC}; diff --git a/gravel/Cargo.toml b/gravel/Cargo.toml index 0d40faa..fc66e8e 100644 --- a/gravel/Cargo.toml +++ b/gravel/Cargo.toml @@ -37,7 +37,7 @@ anyhow.workspace = true chrono = { workspace = true } clap = { workspace = true, features = ["derive"] } clap-verbosity-flag.workspace = true -color-eyre.workspace = true +color-eyre = { workspace = true, features = ["issue-url"] } fern.workspace = true file-rotate.workspace = true glob.workspace = true diff --git a/gravel/src/init/mod.rs b/gravel/src/init/mod.rs index c4e3205..4811e31 100644 --- a/gravel/src/init/mod.rs +++ b/gravel/src/init/mod.rs @@ -4,6 +4,7 @@ mod engine; mod frontend; mod hotkeys; mod logging; +mod panic; mod plugins; mod single_instance; @@ -17,4 +18,5 @@ pub use engine::engine; pub use frontend::frontend; pub use hotkeys::hotkeys; pub use logging::logging; +pub use panic::panic; pub use plugins::plugins; diff --git a/gravel/src/init/panic.rs b/gravel/src/init/panic.rs new file mode 100644 index 0000000..9aabc24 --- /dev/null +++ b/gravel/src/init/panic.rs @@ -0,0 +1,44 @@ +use color_eyre::config::{HookBuilder, PanicHook}; +use std::panic::{set_hook, PanicInfo}; + +pub fn panic() { + #[allow(clippy::print_stderr)] + set_hook(Box::new(move |panic_info| { + log_panic(panic_info); + eprintln!("{}", get_eyre().panic_report(panic_info)); + })); +} + +fn get_eyre() -> PanicHook { + let (eyre_panic, _) = HookBuilder::default() + .issue_url(concat!(env!("CARGO_PKG_REPOSITORY"), "/issues/new")) + .into_hooks(); + + eyre_panic +} + +fn log_panic(panic_info: &PanicInfo<'_>) { + let payload = panic_info + .payload() + .downcast_ref::() + .map(String::as_str) + .or_else(|| panic_info.payload().downcast_ref::<&str>().cloned()) + .unwrap_or(""); + + let location = panic_info + .location() + .map_or_else(|| String::from("awd"), |l| format!("{}:{}", l.file(), l.line())); + + log::error!("panicked at {location}: {payload}"); + log::logger().flush(); +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn eyre_hook_init() { + get_eyre(); + } +} diff --git a/gravel/src/main.rs b/gravel/src/main.rs index c583ac9..6c57f75 100644 --- a/gravel/src/main.rs +++ b/gravel/src/main.rs @@ -15,7 +15,7 @@ mod init; // unwrap instead of returning a Result so we hit color_eyre's panic handler #[allow(clippy::unwrap_used)] fn main() { - color_eyre::install().unwrap(); + init::panic(); #[cfg(windows)] init::windows_console::attach();