From daa2144d879831ec12fbd83d46d65d9a7272ba10 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Sun, 22 Sep 2024 18:17:10 -0700 Subject: [PATCH] Improve error messages Notably, this will help debug which executable failed to launch, helping to debug issues like #76 --- Cargo.lock | 271 +++++++++++++++++++++++++++++++++++---------------- Cargo.toml | 2 +- src/main.rs | 62 ++++++------ src/shell.rs | 7 +- 4 files changed, 226 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96d6c70..28361b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -90,12 +90,27 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "calm_io" version = "0.1.1" @@ -123,9 +138,12 @@ checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" [[package]] name = "cc" -version = "1.0.79" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -152,10 +170,10 @@ checksum = "2e53afce1efce6ed1f633cf0e57612fe51db54a1ee4fd8f8503d078fe02d69ae" dependencies = [ "anstream", "anstyle", - "bitflags", + "bitflags 1.3.2", "clap_lex", "strsim", - "terminal_size", + "terminal_size 0.2.6", ] [[package]] @@ -167,7 +185,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.77", ] [[package]] @@ -176,33 +194,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" -[[package]] -name = "color-eyre" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" -dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] - -[[package]] -name = "color-spantrace" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" -dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -230,21 +221,11 @@ dependencies = [ "libc", ] -[[package]] -name = "eyre" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" -dependencies = [ - "indenter", - "once_cell", -] - [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "heck" @@ -258,12 +239,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -283,10 +258,16 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi", "io-lifetimes", - "rustix", + "rustix 0.37.20", "windows-sys", ] +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + [[package]] name = "itoa" version = "1.0.10" @@ -311,6 +292,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" version = "0.4.20" @@ -332,6 +319,37 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "miette" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +dependencies = [ + "backtrace", + "backtrace-ext", + "cfg-if", + "miette-derive", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size 0.3.0", + "textwrap", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "minijinja" version = "1.0.12" @@ -344,9 +362,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -358,7 +376,7 @@ dependencies = [ "calm_io", "camino", "clap", - "color-eyre", + "miette", "minijinja", "shell-words", "tracing", @@ -377,9 +395,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.4" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -398,9 +416,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "3.5.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "pin-project-lite" @@ -410,18 +428,18 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -482,11 +500,24 @@ version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys 0.4.14", "windows-sys", ] @@ -528,18 +559,51 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "smallvec" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "supports-color" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + [[package]] name = "syn" version = "1.0.109" @@ -553,9 +617,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -568,10 +632,51 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ - "rustix", + "rustix 0.37.20", + "windows-sys", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.3", "windows-sys", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -601,7 +706,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.77", ] [[package]] @@ -614,16 +719,6 @@ dependencies = [ "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-log" version = "0.1.3" @@ -659,6 +754,18 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "utf8parse" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 65656c7..1c5f92e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ categories = ["command-line-utilities"] calm_io = "0.1.1" camino = "1.1.4" clap = { version = "4.3.4", features = ["derive", "wrap_help", "env"] } -color-eyre = "0.6.2" +miette = { version = "7.2.0", features = ["fancy"] } minijinja = { version = "1.0.12", features = ["json"] } shell-words = "1.1.0" tracing = { version = "0.1.39", features = ["attributes"] } diff --git a/src/main.rs b/src/main.rs index 2d68683..4702fd9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,10 +6,9 @@ use calm_io::stdout as println; use camino::Utf8Path; use camino::Utf8PathBuf; use clap::Parser; -use color_eyre::eyre; -use color_eyre::eyre::eyre; -use color_eyre::eyre::Context; -use color_eyre::Help; +use miette::miette; +use miette::Context; +use miette::IntoDiagnostic; mod shell; use shell::Shell; @@ -83,9 +82,8 @@ impl Default for Command { } } -fn main() -> eyre::Result<()> { +fn main() -> miette::Result<()> { let opts = Opts::parse(); - color_eyre::install()?; install_tracing(&opts.log)?; let shell = Shell::from_path(&opts.shell)?; @@ -111,10 +109,10 @@ fn main() -> eyre::Result<()> { } ShellKind::Other(shell) => { - return Err(eyre!( - "I don't know how to generate a shell environment for `{shell}`" + return Err(miette!( + "I don't know how to generate a shell environment for `{shell}`\n\ + Note: Supported shells are: `zsh`, `fish`, `nushell`, `xonsh`, and `bash`" )) - .note("Supported shells are: `zsh`, `fish`, `nushell`, `xonsh`, and `bash`") } }; @@ -139,17 +137,18 @@ fn main() -> eyre::Result<()> { Command::NixShell { args } => { let new_args = nix::transform_nix_shell(args, shell.path.as_str()); let prog = if opts.nom { "nom-shell" } else { "nix-shell" }; + let command = + shell_words::join(std::iter::once(prog).chain(new_args.iter().map(|s| s.as_str()))); tracing::debug!( - command = shell_words::join( - std::iter::once(prog).chain(new_args.iter().map(|s| s.as_str())) - ), + %command, "Launching nix-shell" ); Err(process::Command::new(prog) .args(new_args) .env(NIX_SOURCED_VAR, "1") - .exec() - .into()) + .exec()) + .into_diagnostic() + .wrap_err_with(|| format!("Unable to launch {command}")) } Command::Nix { args } => { @@ -164,27 +163,26 @@ fn main() -> eyre::Result<()> { } else { "nix" }; - tracing::debug!( - command = shell_words::join( - std::iter::once(prog).chain(new_args.args.iter().map(|s| s.as_str())) - ), - "Launching nix" + let command = shell_words::join( + std::iter::once(prog).chain(new_args.args.iter().map(|s| s.as_str())), ); + tracing::debug!(%command, "Launching nix"); Err(process::Command::new(prog) .args(new_args.args) .env(NIX_SOURCED_VAR, "1") - .exec() - .into()) + .exec()) + .into_diagnostic() + .wrap_err_with(|| format!("Unable to launch {command}")) } } } -fn install_tracing(filter_directives: &str) -> eyre::Result<()> { +fn install_tracing(filter_directives: &str) -> miette::Result<()> { use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::Layer; - let env_filter = tracing_subscriber::EnvFilter::try_new(filter_directives)?; + let env_filter = tracing_subscriber::EnvFilter::try_new(filter_directives).into_diagnostic()?; let fmt_layer = tracing_subscriber::fmt::layer() .with_writer(std::io::stderr) @@ -199,16 +197,22 @@ fn install_tracing(filter_directives: &str) -> eyre::Result<()> { } /// Get the path to the current executable. -fn current_exe() -> eyre::Result { - Utf8PathBuf::from_path_buf(std::env::current_exe()?) - .map_err(|path_buf| eyre!("Path is not UTF-8: {path_buf:?}")) +fn current_exe() -> miette::Result { + Utf8PathBuf::from_path_buf( + std::env::current_exe() + .into_diagnostic() + .wrap_err("Unable to determine current executable")?, + ) + .map_err(|path_buf| miette!("Path is not UTF-8: {path_buf:?}")) } -fn executable_is_on_path(executable: &Utf8Path) -> eyre::Result { +fn executable_is_on_path(executable: &Utf8Path) -> miette::Result { let directory = executable .parent() - .ok_or_else(|| eyre!("Executable has no parent directory: {executable:?}"))?; - let path = std::env::var("PATH").wrap_err("Failed to get $PATH environment variable")?; + .ok_or_else(|| miette!("Executable has no parent directory: {executable:?}"))?; + let path = std::env::var("PATH") + .into_diagnostic() + .wrap_err("Failed to get $PATH environment variable")?; Ok(path .split(':') .map(Utf8Path::new) diff --git a/src/shell.rs b/src/shell.rs index 0dca8c0..2c0ea61 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -2,8 +2,7 @@ use std::fmt::Display; use camino::Utf8Path; use camino::Utf8PathBuf; -use color_eyre::eyre; -use color_eyre::eyre::eyre; +use miette::miette; /// A user's shell. #[derive(Clone, Debug)] @@ -52,12 +51,12 @@ pub struct Shell { } impl Shell { - pub fn from_path(path: impl AsRef) -> eyre::Result { + pub fn from_path(path: impl AsRef) -> miette::Result { let path = path.as_ref(); let file_name = match path.file_name() { Some(name) => name, None => { - return Err(eyre!("Path has no filename: {path:?}")); + return Err(miette!("Path has no filename: {path:?}")); } };