From 5b1a185ee82efb9085193186494684e24a882a62 Mon Sep 17 00:00:00 2001 From: Aaron Bull Schaefer Date: Sat, 13 May 2023 10:34:40 -0700 Subject: [PATCH] Use anyhow for idiomatic error handling Good for CLI applications, it provides some nicer ergonomics, features to inject context if needed, as well as non-trivial optimizations compared to using `Box`. For the xtasks use case, I'm going with the simpler `anyhow` over something like `color-eyre`, which supports more complicated output formatting (but has other trade-offs). See: - https://github.com/dtolnay/anyhow/issues/96 --- Cargo.lock | 7 +++++++ xtask/Cargo.toml | 1 + xtask/src/fixup.rs | 26 ++++++++++++-------------- xtask/src/main.rs | 28 ++++++++++++---------------- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b56fad..02320f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + [[package]] name = "cfg-if" version = "1.0.0" @@ -98,5 +104,6 @@ checksum = "1dbabb1cbd15a1d6d12d9ed6b35cc6777d4af87ab3ba155ea37215f20beab80c" name = "xtask" version = "0.1.0" dependencies = [ + "anyhow", "xshell", ] diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 0584f90..c0b0b68 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -9,4 +9,5 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.71" xshell = "0.2.2" diff --git a/xtask/src/fixup.rs b/xtask/src/fixup.rs index 6f23cbe..0b9fdd4 100644 --- a/xtask/src/fixup.rs +++ b/xtask/src/fixup.rs @@ -1,20 +1,18 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; - +use anyhow::Result; +use std::fs; +use std::path::{Path, PathBuf}; use xshell::{cmd, Shell}; -use crate::{project_root, verbose_cd, DynError}; +use crate::{project_root, verbose_cd}; -pub fn format_cue() -> Result<(), DynError> { +pub fn format_cue() -> Result<()> { let sh = Shell::new()?; verbose_cd(&sh, cue_dir()); cmd!(sh, "cue fmt --simplify").run()?; Ok(()) } -pub fn format_markdown() -> Result<(), DynError> { +pub fn format_markdown() -> Result<()> { let sh = Shell::new()?; let root = project_root(); verbose_cd(&sh, &root); @@ -32,21 +30,21 @@ pub fn format_markdown() -> Result<(), DynError> { Ok(()) } -pub fn format_rust() -> Result<(), DynError> { +pub fn format_rust() -> Result<()> { let sh = Shell::new()?; verbose_cd(&sh, project_root()); cmd!(sh, "cargo fmt").run()?; Ok(()) } -pub fn lint_cue() -> Result<(), DynError> { +pub fn lint_cue() -> Result<()> { let sh = Shell::new()?; verbose_cd(&sh, cue_dir()); cmd!(sh, "cue vet --concrete").run()?; Ok(()) } -pub fn lint_rust() -> Result<(), DynError> { +pub fn lint_rust() -> Result<()> { let sh = Shell::new()?; verbose_cd(&sh, project_root()); cmd!( @@ -67,14 +65,14 @@ pub fn lint_rust() -> Result<(), DynError> { Ok(()) } -pub fn regenerate_ci_yaml() -> Result<(), DynError> { +pub fn regenerate_ci_yaml() -> Result<()> { let sh = Shell::new()?; verbose_cd(&sh, cue_dir()); cmd!(sh, "cue cmd regen-ci-yaml").run()?; Ok(()) } -pub fn spellcheck() -> Result<(), DynError> { +pub fn spellcheck() -> Result<()> { let sh = Shell::new()?; verbose_cd(&sh, project_root()); cmd!(sh, "codespell --write-changes").run()?; @@ -85,7 +83,7 @@ fn cue_dir() -> PathBuf { project_root().join(".github/cue") } -fn find_markdown_files>(dir: P) -> Result, DynError> { +fn find_markdown_files>(dir: P) -> Result> { let mut result = Vec::new(); for entry in fs::read_dir(dir)? { let path = entry?.path(); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index de6399f..0772496 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,15 +1,11 @@ -use std::{ - env, - error::Error, - path::{Path, PathBuf}, -}; +use anyhow::Result; +use std::env; +use std::path::{Path, PathBuf}; use xshell::Shell; mod fixup; -type DynError = Box; - -fn main() -> Result<(), DynError> { +fn main() -> Result<()> { let task = env::args().nth(1); match task { None => tasks::print_help()?, @@ -20,7 +16,7 @@ fn main() -> Result<(), DynError> { "fixup.markdown" => tasks::fixup_markdown()?, "fixup.rust" => tasks::fixup_rust()?, "fixup.spelling" => tasks::fixup_spelling()?, - invalid => return Err(format!("Invalid task name: {}", invalid).into()), + invalid => return Err(anyhow::anyhow!("Invalid task name: {}", invalid)), }, }; Ok(()) @@ -30,7 +26,7 @@ pub mod tasks { use crate::fixup::{format_cue, format_markdown, format_rust}; use crate::fixup::{lint_cue, lint_rust}; use crate::fixup::{regenerate_ci_yaml, spellcheck}; - use crate::DynError; + use anyhow::Result; const HELP: &str = "\ NAME @@ -48,33 +44,33 @@ COMMANDS fixup.rust Fix lints and format Rust files in-place. "; - pub fn fixup() -> Result<(), DynError> { + pub fn fixup() -> Result<()> { fixup_spelling()?; // affects all file types; run this first fixup_github_actions()?; fixup_markdown()?; fixup_rust() } - pub fn fixup_github_actions() -> Result<(), DynError> { + pub fn fixup_github_actions() -> Result<()> { lint_cue()?; format_cue()?; regenerate_ci_yaml() } - pub fn fixup_markdown() -> Result<(), DynError> { + pub fn fixup_markdown() -> Result<()> { format_markdown() } - pub fn fixup_rust() -> Result<(), DynError> { + pub fn fixup_rust() -> Result<()> { lint_rust()?; format_rust() } - pub fn fixup_spelling() -> Result<(), DynError> { + pub fn fixup_spelling() -> Result<()> { spellcheck() } - pub fn print_help() -> Result<(), DynError> { + pub fn print_help() -> Result<()> { print!("{}", HELP); Ok(()) }