diff --git a/Cargo.lock b/Cargo.lock index 9845d56..cf64e0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -148,6 +157,30 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "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 = "base64" version = "0.21.7" @@ -212,7 +245,6 @@ dependencies = [ name = "blue-build" version = "0.8.11" dependencies = [ - "anyhow", "blue-build-recipe", "blue-build-template", "blue-build-utils", @@ -227,6 +259,7 @@ dependencies = [ "indicatif", "lenient_semver", "log", + "miette", "once_cell", "open", "os_info", @@ -249,12 +282,12 @@ dependencies = [ name = "blue-build-recipe" version = "0.8.11" dependencies = [ - "anyhow", "blue-build-utils", "chrono", "colored", "indexmap 2.2.6", "log", + "miette", "serde", "serde_json", "serde_yaml 0.9.34+deprecated", @@ -293,6 +326,7 @@ dependencies = [ "indicatif-log-bridge", "log", "log4rs", + "miette", "nix", "nu-ansi-term", "once_cell", @@ -753,6 +787,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + [[package]] name = "git2" version = "0.18.3" @@ -924,6 +964,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + [[package]] name = "is_debug" version = "1.0.1" @@ -1118,6 +1164,37 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[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", + "textwrap 0.16.1", + "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.66", +] + [[package]] name = "mime" version = "0.3.17" @@ -1234,6 +1311,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +[[package]] +name = "object" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -1309,6 +1395,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "owo-colors" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" + [[package]] name = "parking_lot" version = "0.12.3" @@ -1594,10 +1686,16 @@ dependencies = [ "crossterm", "once_cell", "termion", - "textwrap", + "textwrap 0.15.2", "unicode-segmentation", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustix" version = "0.38.34" @@ -1799,6 +1897,27 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "supports-color" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" +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" @@ -1865,6 +1984,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "termion" version = "1.5.6" @@ -1888,6 +2017,17 @@ dependencies = [ "unicode-width", ] +[[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.61" diff --git a/Cargo.toml b/Cargo.toml index 285976e..16793e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ categories = ["command-line-utilities"] version = "0.8.11" [workspace.dependencies] -anyhow = "1" chrono = "0.4" clap = "4" colored = "2" @@ -19,6 +18,7 @@ indexmap = { version = "2", features = ["serde"] } indicatif = { version = "0.17", features = ["improved_unicode"] } indicatif-log-bridge = "0.2" log = "0.4" +miette = "7" once_cell = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -73,14 +73,13 @@ shadow-rs = "0.26" urlencoding = "2" users = "0.11" -# Workspace dependencies -anyhow.workspace = true chrono.workspace = true clap = { workspace = true, features = ["derive", "cargo", "unicode", "env"] } colored.workspace = true indexmap.workspace = true indicatif.workspace = true log.workspace = true +miette = { workspace = true, features = ["fancy"] } once_cell.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/recipe/Cargo.toml b/recipe/Cargo.toml index 6c084e8..d7b80f0 100644 --- a/recipe/Cargo.toml +++ b/recipe/Cargo.toml @@ -11,10 +11,10 @@ license.workspace = true [dependencies] blue-build-utils = { version = "=0.8.11", path = "../utils" } -anyhow.workspace = true chrono.workspace = true colored.workspace = true log.workspace = true +miette.workspace = true indexmap.workspace = true serde.workspace = true serde_yaml.workspace = true diff --git a/recipe/src/module.rs b/recipe/src/module.rs index 5da25f5..a3bcc90 100644 --- a/recipe/src/module.rs +++ b/recipe/src/module.rs @@ -1,10 +1,10 @@ use std::{borrow::Cow, path::PathBuf, process}; -use anyhow::{bail, Result}; use blue_build_utils::syntax_highlighting::highlight_ser; use colored::Colorize; use indexmap::IndexMap; use log::{error, trace, warn}; +use miette::{bail, Result}; use serde::{Deserialize, Serialize}; use serde_yaml::Value; use typed_builder::TypedBuilder; diff --git a/recipe/src/module_ext.rs b/recipe/src/module_ext.rs index f21abab..ab09655 100644 --- a/recipe/src/module_ext.rs +++ b/recipe/src/module_ext.rs @@ -1,8 +1,8 @@ use std::{borrow::Cow, collections::HashSet, fs, path::Path}; -use anyhow::{Context, Result}; use blue_build_utils::constants::{CONFIG_PATH, RECIPE_PATH}; use log::{trace, warn}; +use miette::{Context, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; use typed_builder::TypedBuilder; @@ -32,12 +32,14 @@ impl ModuleExt<'_> { }; let file = fs::read_to_string(&file_path) - .context(format!("Failed to open {}", file_path.display()))?; + .into_diagnostic() + .with_context(|| format!("Failed to open {}", file_path.display()))?; serde_yaml::from_str::(&file).map_or_else( |_| -> Result { let module = serde_yaml::from_str::(&file) - .map_err(blue_build_utils::serde_yaml_err(&file))?; + .map_err(blue_build_utils::serde_yaml_err(&file)) + .into_diagnostic()?; Ok(Self::builder().modules(vec![module]).build()) }, Ok, diff --git a/recipe/src/recipe.rs b/recipe/src/recipe.rs index ad14de4..8516897 100644 --- a/recipe/src/recipe.rs +++ b/recipe/src/recipe.rs @@ -1,6 +1,5 @@ use std::{borrow::Cow, env, fs, path::Path}; -use anyhow::{Context, Result}; use blue_build_utils::constants::{ CI_COMMIT_REF_NAME, CI_COMMIT_SHORT_SHA, CI_DEFAULT_BRANCH, CI_MERGE_REQUEST_IID, CI_PIPELINE_SOURCE, GITHUB_EVENT_NAME, GITHUB_REF_NAME, GITHUB_SHA, PR_EVENT_NUMBER, @@ -8,6 +7,7 @@ use blue_build_utils::constants::{ use chrono::Local; use indexmap::IndexMap; use log::{debug, trace, warn}; +use miette::{Context, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; use serde_yaml::Value; use typed_builder::TypedBuilder; @@ -204,16 +204,20 @@ impl<'a> Recipe<'a> { let file_path = if Path::new(path.as_ref()).is_absolute() { path.as_ref().to_path_buf() } else { - std::env::current_dir()?.join(path.as_ref()) + std::env::current_dir() + .into_diagnostic()? + .join(path.as_ref()) }; let file = fs::read_to_string(&file_path) - .context(format!("Failed to read {}", file_path.display()))?; + .into_diagnostic() + .with_context(|| format!("Failed to read {}", file_path.display()))?; debug!("Recipe contents: {file}"); let mut recipe = serde_yaml::from_str::(&file) - .map_err(blue_build_utils::serde_yaml_err(&file))?; + .map_err(blue_build_utils::serde_yaml_err(&file)) + .into_diagnostic()?; recipe.modules_ext.modules = Module::get_modules(&recipe.modules_ext.modules, None)?.into(); diff --git a/recipe/src/stage.rs b/recipe/src/stage.rs index f9af1dd..65f65c5 100644 --- a/recipe/src/stage.rs +++ b/recipe/src/stage.rs @@ -1,8 +1,8 @@ use std::{borrow::Cow, path::PathBuf}; -use anyhow::{bail, Result}; use blue_build_utils::syntax_highlighting::highlight_ser; use colored::Colorize; +use miette::{bail, Result}; use serde::{Deserialize, Serialize}; use typed_builder::TypedBuilder; diff --git a/recipe/src/stages_ext.rs b/recipe/src/stages_ext.rs index c02d4c9..be30ef8 100644 --- a/recipe/src/stages_ext.rs +++ b/recipe/src/stages_ext.rs @@ -1,8 +1,8 @@ use std::{borrow::Cow, fs, path::Path}; -use anyhow::{Context, Result}; use blue_build_utils::constants::{CONFIG_PATH, RECIPE_PATH}; use log::warn; +use miette::{Context, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; use typed_builder::TypedBuilder; @@ -32,12 +32,14 @@ impl<'a> StagesExt<'a> { }; let file = fs::read_to_string(&file_path) - .context(format!("Failed to open {}", file_path.display()))?; + .into_diagnostic() + .with_context(|| format!("Failed to open {}", file_path.display()))?; serde_yaml::from_str::(&file).map_or_else( |_| -> Result { let mut stage = serde_yaml::from_str::(&file) - .map_err(blue_build_utils::serde_yaml_err(&file))?; + .map_err(blue_build_utils::serde_yaml_err(&file)) + .into_diagnostic()?; if let Some(ref mut rf) = stage.required_fields { rf.modules_ext.modules = Module::get_modules(&rf.modules_ext.modules, None)?.into(); diff --git a/src/commands.rs b/src/commands.rs index 2e77035..19184ae 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -28,12 +28,12 @@ pub trait BlueBuildCommand { /// /// # Errors /// Can return an `anyhow` Error - fn try_run(&mut self) -> anyhow::Result<()>; + fn try_run(&mut self) -> miette::Result<()>; /// Runs the command and exits if there is an error. fn run(&mut self) { if let Err(e) = self.try_run() { - error!("{e}"); + error!("Failed:\n{e:?}"); std::process::exit(1); } std::process::exit(0); diff --git a/src/commands/bug_report.rs b/src/commands/bug_report.rs index ad25900..7c49d59 100644 --- a/src/commands/bug_report.rs +++ b/src/commands/bug_report.rs @@ -9,6 +9,7 @@ use clap_complete::Shell; use colored::Colorize; use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; use log::{debug, error, trace}; +use miette::{IntoDiagnostic, Result}; use requestty::question::{completions, Completions}; use std::time::Duration; use typed_builder::TypedBuilder; @@ -32,7 +33,7 @@ pub struct BugReportCommand { } impl BlueBuildCommand for BugReportCommand { - fn try_run(&mut self) -> anyhow::Result<()> { + fn try_run(&mut self) -> Result<()> { debug!("Generating bug report for hash: {}\n", shadow::COMMIT_HASH); debug!("Shadow Versioning:\n{}", shadow::VERSION.trim()); @@ -51,7 +52,7 @@ impl BugReportCommand { /// # Panics /// /// This function will panic if it fails to get the current shell or terminal version. - pub fn create_bugreport(&self) -> anyhow::Result<()> { + pub fn create_bugreport(&self) -> Result<()> { let os_info = os_info::get(); let recipe = self.get_recipe(); @@ -94,7 +95,7 @@ impl BugReportCommand { if let Err(e) = open::that(&link) { println!("Failed to open issue report in your browser: {e}"); println!("Please copy the above report and open an issue manually, or try opening the following link:\n{link}"); - return Err(e.into()); + return Err(e).into_diagnostic(); } } else { println!("{BUG_REPORT_WARNING_MESSAGE}"); @@ -125,7 +126,7 @@ impl BugReportCommand { } } -fn get_config_file(title: &str, message: &str) -> anyhow::Result { +fn get_config_file(title: &str, message: &str) -> Result { use std::path::Path; let question = requestty::Question::input(title) @@ -147,7 +148,7 @@ fn get_config_file(title: &str, message: &str) -> anyhow::Result { Ok(_) => unreachable!(), Err(e) => { trace!("Failed to get file: {}", e); - Err(e.into()) + Err(e).into_diagnostic() } } } @@ -276,11 +277,8 @@ fn get_pkg_branch_tag() -> String { format!("{} ({})", shadow::BRANCH, shadow::LAST_TAG) } -fn generate_github_issue( - environment: &Environment, - recipe: &Option, -) -> anyhow::Result { - let recipe = serde_yaml::to_string(recipe)?; +fn generate_github_issue(environment: &Environment, recipe: &Option) -> Result { + let recipe = serde_yaml::to_string(recipe).into_diagnostic()?; let github_template = GithubIssueTemplate::builder() .bb_version(shadow::PKG_VERSION) @@ -299,7 +297,7 @@ fn generate_github_issue( .terminal_version(environment.terminal_info.version.clone()) .build(); - Ok(github_template.render()?) + github_template.render().into_diagnostic() } fn make_github_issue_link(body: &str) -> String { diff --git a/src/commands/build.rs b/src/commands/build.rs index 5a26413..38ac4e6 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -4,7 +4,6 @@ use std::{ process::Command, }; -use anyhow::{bail, Context, Result}; use blue_build_recipe::Recipe; use blue_build_utils::{ constants::{ @@ -20,6 +19,7 @@ use blue_build_utils::{ use clap::Args; use colored::Colorize; use log::{debug, info, trace, warn}; +use miette::{bail, Context, IntoDiagnostic, Result}; use typed_builder::TypedBuilder; use crate::{ @@ -330,7 +330,8 @@ impl BuildCommand { .arg("-p") .arg(password) .arg(registry) - .output()?; + .output() + .into_diagnostic()?; if !login_output.status.success() { let err_output = String::from_utf8_lossy(&login_output.stderr); @@ -421,7 +422,8 @@ impl BuildCommand { if !self.force && container_file_path.exists() { let to_ignore_lines = [format!("/{CONTAINER_FILE}"), format!("/{CONTAINER_FILE}.*")]; let gitignore = fs::read_to_string(GITIGNORE_PATH) - .context(format!("Failed to read {GITIGNORE_PATH}"))?; + .into_diagnostic() + .with_context(|| format!("Failed to read {GITIGNORE_PATH}"))?; let mut edited_gitignore = gitignore.clone(); @@ -434,7 +436,10 @@ impl BuildCommand { }) .try_for_each(|to_ignore| -> Result<()> { let containerfile = fs::read_to_string(container_file_path) - .context(format!("Failed to read {}", container_file_path.display()))?; + .into_diagnostic() + .with_context(|| { + format!("Failed to read {}", container_file_path.display()) + })?; let has_label = containerfile .lines() @@ -467,7 +472,7 @@ impl BuildCommand { })?; if edited_gitignore != gitignore { - fs::write(GITIGNORE_PATH, edited_gitignore.as_str())?; + fs::write(GITIGNORE_PATH, edited_gitignore.as_str()).into_diagnostic()?; } } @@ -497,7 +502,8 @@ impl BuildCommand { let output = Command::new("cosign") .arg("public-key") .arg("--key=env://COSIGN_PRIVATE_KEY") - .output()?; + .output() + .into_diagnostic()?; if !output.status.success() { bail!( @@ -506,9 +512,10 @@ impl BuildCommand { ); } - let calculated_pub_key = String::from_utf8(output.stdout)?; + let calculated_pub_key = String::from_utf8(output.stdout).into_diagnostic()?; let found_pub_key = fs::read_to_string(COSIGN_PUB_PATH) - .context(format!("Failed to read {COSIGN_PUB_PATH}"))?; + .into_diagnostic() + .with_context(|| format!("Failed to read {COSIGN_PUB_PATH}"))?; trace!("calculated_pub_key={calculated_pub_key},found_pub_key={found_pub_key}"); if calculated_pub_key.trim() == found_pub_key.trim() { @@ -523,7 +530,8 @@ impl BuildCommand { let output = Command::new("cosign") .arg("public-key") .arg(format!("--key={COSIGN_PRIV_PATH}")) - .output()?; + .output() + .into_diagnostic()?; if !output.status.success() { bail!( @@ -532,9 +540,10 @@ impl BuildCommand { ); } - let calculated_pub_key = String::from_utf8(output.stdout)?; + let calculated_pub_key = String::from_utf8(output.stdout).into_diagnostic()?; let found_pub_key = fs::read_to_string(COSIGN_PUB_PATH) - .context(format!("Failed to read {COSIGN_PUB_PATH}"))?; + .into_diagnostic() + .with_context(|| format!("Failed to read {COSIGN_PUB_PATH}"))?; trace!("calculated_pub_key={calculated_pub_key},found_pub_key={found_pub_key}"); if calculated_pub_key.trim() == found_pub_key.trim() { @@ -622,7 +631,8 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> { .arg("sign") .arg("--recursive") .arg(&image_name_digest) - .status()? + .status() + .into_diagnostic()? .success() { info!("Successfully signed image!"); @@ -644,7 +654,8 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> { .arg("--certificate-oidc-issuer") .arg(&cert_oidc) .arg(&image_name_tag) - .status()? + .status() + .into_diagnostic()? .success() { bail!("Failed to verify image!"); @@ -661,7 +672,8 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> { .arg("sign") .arg("--recursive") .arg(&image_name_digest) - .status()? + .status() + .into_diagnostic()? .success() { info!("Successfully signed image!"); @@ -677,7 +689,8 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> { .arg("--certificate-oidc-issuer") .arg(GITHUB_TOKEN_ISSUER_URL) .arg(&image_name_tag) - .status()? + .status() + .into_diagnostic()? .success() { bail!("Failed to verify image!"); @@ -699,7 +712,8 @@ fn sign_priv_public_pair_env(image_digest: &str, image_name_tag: &str) -> Result .arg("--key=env://COSIGN_PRIVATE_KEY") .arg("--recursive") .arg(image_digest) - .status()? + .status() + .into_diagnostic()? .success() { info!("Successfully signed image!"); @@ -713,7 +727,8 @@ fn sign_priv_public_pair_env(image_digest: &str, image_name_tag: &str) -> Result .arg("verify") .arg(format!("--key={COSIGN_PUB_PATH}")) .arg(image_name_tag) - .status()? + .status() + .into_diagnostic()? .success() { bail!("Failed to verify image!"); @@ -732,7 +747,8 @@ fn sign_priv_public_pair_file(image_digest: &str, image_name_tag: &str) -> Resul .arg(format!("--key={COSIGN_PRIV_PATH}")) .arg("--recursive") .arg(image_digest) - .status()? + .status() + .into_diagnostic()? .success() { info!("Successfully signed image!"); @@ -746,7 +762,8 @@ fn sign_priv_public_pair_file(image_digest: &str, image_name_tag: &str) -> Resul .arg("verify") .arg(format!("--key={COSIGN_PUB_PATH}")) .arg(image_name_tag) - .status()? + .status() + .into_diagnostic()? .success() { bail!("Failed to verify image!"); diff --git a/src/commands/completions.rs b/src/commands/completions.rs index 4424fba..5f7ff11 100644 --- a/src/commands/completions.rs +++ b/src/commands/completions.rs @@ -1,5 +1,6 @@ use clap::{Args, CommandFactory}; use clap_complete::{generate, Shell as CompletionShell}; +use miette::Result; use crate::commands::BlueBuildArgs; @@ -12,7 +13,7 @@ pub struct CompletionsCommand { } impl BlueBuildCommand for CompletionsCommand { - fn try_run(&mut self) -> anyhow::Result<()> { + fn try_run(&mut self) -> Result<()> { log::debug!("Generating completions for {}", self.shell); generate( diff --git a/src/commands/generate.rs b/src/commands/generate.rs index 8fed287..1f3170c 100644 --- a/src/commands/generate.rs +++ b/src/commands/generate.rs @@ -3,7 +3,6 @@ use std::{ path::{Path, PathBuf}, }; -use anyhow::Result; use blue_build_recipe::Recipe; use blue_build_template::{ContainerFileTemplate, Template}; use blue_build_utils::{ @@ -15,6 +14,7 @@ use blue_build_utils::{ }; use clap::{crate_version, Args}; use log::{debug, info, trace, warn}; +use miette::{IntoDiagnostic, Result}; use typed_builder::TypedBuilder; use crate::{drivers::Driver, shadow}; @@ -104,7 +104,8 @@ impl GenerateCommand { if self.display_full_recipe { if let Some(output) = self.output.as_ref() { - std::fs::write(output, serde_yaml::to_string(&recipe_de)?)?; + std::fs::write(output, serde_yaml::to_string(&recipe_de).into_diagnostic()?) + .into_diagnostic()?; } else { syntax_highlighting::print_ser(&recipe_de, "yml", self.syntax_theme)?; } @@ -132,12 +133,12 @@ impl GenerateCommand { }) .build(); - let output_str = template.render()?; + let output_str = template.render().into_diagnostic()?; if let Some(output) = self.output.as_ref() { debug!("Templating to file {}", output.display()); trace!("Containerfile:\n{output_str}"); - std::fs::write(output, output_str)?; + std::fs::write(output, output_str).into_diagnostic()?; } else { debug!("Templating to stdout"); syntax_highlighting::print(&output_str, "Dockerfile", self.syntax_theme)?; diff --git a/src/commands/local.rs b/src/commands/local.rs index b2f927b..6f225e7 100644 --- a/src/commands/local.rs +++ b/src/commands/local.rs @@ -4,11 +4,11 @@ use std::{ process::Command, }; -use anyhow::{bail, Result}; use blue_build_recipe::Recipe; use blue_build_utils::constants::{ARCHIVE_SUFFIX, LOCAL_BUILD}; use clap::Args; use log::{debug, info, trace}; +use miette::{bail, IntoDiagnostic, Result}; use typed_builder::TypedBuilder; use users::{Users, UsersCache}; @@ -84,12 +84,16 @@ impl BlueBuildCommand for UpgradeCommand { Command::new("rpm-ostree") .arg("upgrade") .arg("--reboot") - .status()? + .status() + .into_diagnostic()? } else { info!("Upgrading image {image_name}"); trace!("rpm-ostree upgrade"); - Command::new("rpm-ostree").arg("upgrade").status()? + Command::new("rpm-ostree") + .arg("upgrade") + .status() + .into_diagnostic()? }; if status.success() { @@ -146,7 +150,8 @@ impl BlueBuildCommand for RebaseCommand { .arg("rebase") .arg("--reboot") .arg(rebase_url) - .status()? + .status() + .into_diagnostic()? } else { info!("Rebasing image {image_name}"); @@ -154,7 +159,8 @@ impl BlueBuildCommand for RebaseCommand { Command::new("rpm-ostree") .arg("rebase") .arg(rebase_url) - .status()? + .status() + .into_diagnostic()? }; if status.success() { @@ -198,10 +204,10 @@ fn clean_local_build_dir(image_name: &str, rebase: bool) -> Result<()> { if local_build_path.exists() { debug!("Cleaning out build dir {LOCAL_BUILD}"); - let entries = fs::read_dir(LOCAL_BUILD)?; + let entries = fs::read_dir(LOCAL_BUILD).into_diagnostic()?; for entry in entries { - let entry = entry?; + let entry = entry.into_diagnostic()?; let path = entry.path(); trace!("Found {}", path.display()); @@ -211,7 +217,7 @@ fn clean_local_build_dir(image_name: &str, rebase: bool) -> Result<()> { continue; } trace!("Removing {}", path.display()); - fs::remove_file(path)?; + fs::remove_file(path).into_diagnostic()?; } } } else { @@ -219,7 +225,7 @@ fn clean_local_build_dir(image_name: &str, rebase: bool) -> Result<()> { "Creating build output dir at {}", local_build_path.display() ); - fs::create_dir_all(local_build_path)?; + fs::create_dir_all(local_build_path).into_diagnostic()?; } Ok(()) diff --git a/src/commands/switch.rs b/src/commands/switch.rs index 79f4c76..c5a38c1 100644 --- a/src/commands/switch.rs +++ b/src/commands/switch.rs @@ -4,7 +4,6 @@ use std::{ time::Duration, }; -use anyhow::{bail, Result}; use blue_build_recipe::Recipe; use blue_build_utils::{ constants::{ARCHIVE_SUFFIX, LOCAL_BUILD, OCI_ARCHIVE, OSTREE_UNVERIFIED_IMAGE}, @@ -14,6 +13,7 @@ use clap::Args; use colored::Colorize; use indicatif::ProgressBar; use log::{debug, trace, warn}; +use miette::{bail, IntoDiagnostic, Result}; use tempdir::TempDir; use typed_builder::TypedBuilder; @@ -64,7 +64,7 @@ impl BlueBuildCommand for SwitchCommand { bail!("There is a transaction in progress. Please cancel it using `rpm-ostree cancel`"); } - let tempdir = TempDir::new("oci-archive")?; + let tempdir = TempDir::new("oci-archive").into_diagnostic()?; trace!("{tempdir:?}"); BuildCommand::builder() @@ -144,7 +144,8 @@ impl SwitchCommand { .status_image_ref_progress( format!("{}", archive_path.display()), "Switching to new image", - )?; + ) + .into_diagnostic()?; if !status.success() { bail!("Failed to switch to new image!"); @@ -164,7 +165,11 @@ impl SwitchCommand { progress.set_message(format!("Moving image archive to {}...", to.display())); trace!("sudo mv {} {}", from.display(), to.display()); - let status = Command::new("sudo").arg("mv").args([from, to]).status()?; + let status = Command::new("sudo") + .arg("mv") + .args([from, to]) + .status() + .into_diagnostic()?; progress.finish_and_clear(); @@ -191,9 +196,11 @@ impl SwitchCommand { let output = String::from_utf8( Command::new("sudo") .args(["ls", LOCAL_BUILD]) - .output()? + .output() + .into_diagnostic()? .stdout, - )?; + ) + .into_diagnostic()?; trace!("{output}"); @@ -214,7 +221,8 @@ impl SwitchCommand { let status = Command::new("sudo") .args(["rm", "-f"]) .arg(files) - .status()?; + .status() + .into_diagnostic()?; progress.finish_and_clear(); @@ -230,7 +238,8 @@ impl SwitchCommand { let status = Command::new("sudo") .args(["mkdir", "-p", LOCAL_BUILD]) - .status()?; + .status() + .into_diagnostic()?; if !status.success() { bail!("Failed to create directory {LOCAL_BUILD}"); diff --git a/src/drivers.rs b/src/drivers.rs index 724214f..cc0bfc2 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -10,10 +10,10 @@ use std::{ sync::{Arc, Mutex}, }; -use anyhow::{anyhow, bail, Result}; use blue_build_recipe::Recipe; use blue_build_utils::constants::IMAGE_VERSION_LABEL; use log::{debug, info, trace}; +use miette::{bail, miette, Result}; use once_cell::sync::Lazy; use semver::{Version, VersionReq}; use typed_builder::TypedBuilder; @@ -202,7 +202,7 @@ pub trait BuildDriver: Sync + Send { let image = opts .image .as_ref() - .ok_or_else(|| anyhow!("Image is required in order to tag"))?; + .ok_or_else(|| miette!("Image is required in order to tag"))?; debug!("Tagging all images"); for tag in opts.tags.as_ref() { @@ -369,13 +369,14 @@ impl Driver<'_> { /// # Errors /// Will error if the image doesn't have OS version info /// or we are unable to lock a mutex. + /// + /// # Panics + /// Panics if the mutex fails to lock. pub fn get_os_version(recipe: &Recipe) -> Result { trace!("Driver::get_os_version({recipe:#?})"); let image = format!("{}:{}", &recipe.base_image, &recipe.image_version); - let mut os_version_lock = OS_VERSION - .lock() - .map_err(|e| anyhow!("Unable set OS_VERSION {e}"))?; + let mut os_version_lock = OS_VERSION.lock().expect("Should lock"); let entry = os_version_lock.get(&image); @@ -389,8 +390,9 @@ impl Driver<'_> { let inspection = INSPECT_DRIVER.get_metadata(&inspect_opts)?; let os_version = inspection.get_version().ok_or_else(|| { - anyhow!( - "Unable to get the OS version from the labels. Please check with the image author about using '{IMAGE_VERSION_LABEL}' to report the os version." + miette!( + help = format!("Please check with the image author about using '{IMAGE_VERSION_LABEL}' to report the os version."), + "Unable to get the OS version from the labels" ) })?; trace!("os_version: {os_version}"); diff --git a/src/drivers/buildah_driver.rs b/src/drivers/buildah_driver.rs index d09f7eb..a500427 100644 --- a/src/drivers/buildah_driver.rs +++ b/src/drivers/buildah_driver.rs @@ -1,8 +1,8 @@ use std::process::Command; -use anyhow::{bail, Result}; use blue_build_utils::logging::CommandLogging; use log::{error, info, trace}; +use miette::{bail, IntoDiagnostic, Result}; use semver::Version; use serde::Deserialize; @@ -33,10 +33,12 @@ impl DriverVersion for BuildahDriver { let output = Command::new("buildah") .arg("version") .arg("--json") - .output()?; + .output() + .into_diagnostic()?; let version_json: BuildahVersionJson = serde_json::from_slice(&output.stdout) - .inspect_err(|e| error!("{e}: {}", String::from_utf8_lossy(&output.stdout)))?; + .inspect_err(|e| error!("{e}: {}", String::from_utf8_lossy(&output.stdout))) + .into_diagnostic()?; trace!("{version_json:#?}"); Ok(version_json.version) @@ -62,7 +64,9 @@ impl BuildDriver for BuildahDriver { .arg(opts.containerfile.as_ref()) .arg("-t") .arg(opts.image.as_ref()); - let status = command.status_image_ref_progress(&opts.image, "Building Image")?; + let status = command + .status_image_ref_progress(&opts.image, "Building Image") + .into_diagnostic()?; if status.success() { info!("Successfully built {}", opts.image); @@ -80,7 +84,8 @@ impl BuildDriver for BuildahDriver { .arg("tag") .arg(opts.src_image.as_ref()) .arg(opts.dest_image.as_ref()) - .status()?; + .status() + .into_diagnostic()?; if status.success() { info!("Successfully tagged {}!", opts.dest_image); @@ -102,7 +107,9 @@ impl BuildDriver for BuildahDriver { opts.compression_type.unwrap_or_default() )) .arg(opts.image.as_ref()); - let status = command.status_image_ref_progress(&opts.image, "Pushing Image")?; + let status = command + .status_image_ref_progress(&opts.image, "Pushing Image") + .into_diagnostic()?; if status.success() { info!("Successfully pushed {}!", opts.image); @@ -129,7 +136,8 @@ impl BuildDriver for BuildahDriver { .arg("-p") .arg(password) .arg(registry) - .output()?; + .output() + .into_diagnostic()?; if !output.status.success() { let err_out = String::from_utf8_lossy(&output.stderr); diff --git a/src/drivers/docker_driver.rs b/src/drivers/docker_driver.rs index 4f13030..e4c7e66 100644 --- a/src/drivers/docker_driver.rs +++ b/src/drivers/docker_driver.rs @@ -6,7 +6,6 @@ use std::{ time::Duration, }; -use anyhow::{anyhow, bail, Result}; use blue_build_utils::{ constants::{BB_BUILDKIT_CACHE_GHA, CONTAINER_FILE, DOCKER_HOST, SKOPEO_IMAGE}, logging::{CommandLogging, Logger}, @@ -14,6 +13,7 @@ use blue_build_utils::{ }; use indicatif::{ProgressBar, ProgressStyle}; use log::{info, trace, warn}; +use miette::{bail, IntoDiagnostic, Result}; use once_cell::sync::Lazy; use semver::Version; use serde::Deserialize; @@ -50,9 +50,7 @@ impl DockerDriver { fn setup() -> Result<()> { trace!("DockerDriver::setup()"); - let mut lock = DOCKER_SETUP - .lock() - .map_err(|e| anyhow!("Failed to lock DOCKER_SETUP: {e}"))?; + let mut lock = DOCKER_SETUP.lock().expect("Should lock"); if *lock { drop(lock); @@ -64,13 +62,14 @@ impl DockerDriver { .arg("buildx") .arg("ls") .arg("--format={{.Name}}") - .output()?; + .output() + .into_diagnostic()?; if !ls_out.status.success() { bail!("{}", String::from_utf8_lossy(&ls_out.stderr)); } - let ls_out = String::from_utf8(ls_out.stdout)?; + let ls_out = String::from_utf8(ls_out.stdout).into_diagnostic()?; trace!("{ls_out}"); @@ -82,7 +81,8 @@ impl DockerDriver { .arg("--bootstrap") .arg("--driver=docker-container") .arg("--name=bluebuild") - .output()?; + .output() + .into_diagnostic()?; if !create_out.status.success() { bail!("{}", String::from_utf8_lossy(&create_out.stderr)); @@ -105,9 +105,11 @@ impl DriverVersion for DockerDriver { .arg("version") .arg("-f") .arg("json") - .output()?; + .output() + .into_diagnostic()?; - let version_json: DockerVersionJson = serde_json::from_slice(&output.stdout)?; + let version_json: DockerVersionJson = + serde_json::from_slice(&output.stdout).into_diagnostic()?; Ok(version_json.client.version) } @@ -129,7 +131,8 @@ impl BuildDriver for DockerDriver { .arg("-f") .arg(opts.containerfile.as_ref()) .arg(".") - .status()?; + .status() + .into_diagnostic()?; if status.success() { info!("Successfully built {}", opts.image); @@ -147,7 +150,8 @@ impl BuildDriver for DockerDriver { .arg("tag") .arg(opts.src_image.as_ref()) .arg(opts.dest_image.as_ref()) - .status()?; + .status() + .into_diagnostic()?; if status.success() { info!("Successfully tagged {}!", opts.dest_image); @@ -164,7 +168,8 @@ impl BuildDriver for DockerDriver { let status = Command::new("docker") .arg("push") .arg(opts.image.as_ref()) - .status()?; + .status() + .into_diagnostic()?; if status.success() { info!("Successfully pushed {}!", opts.image); @@ -191,7 +196,8 @@ impl BuildDriver for DockerDriver { .arg("-p") .arg(password) .arg(registry) - .output()?; + .output() + .into_diagnostic()?; if !output.status.success() { let err_out = String::from_utf8_lossy(&output.stderr); @@ -287,7 +293,8 @@ impl BuildDriver for DockerDriver { command.arg("."); if command - .status_image_ref_progress(&final_image, "Building Image")? + .status_image_ref_progress(&final_image, "Building Image") + .into_diagnostic()? .success() { if opts.push { @@ -318,12 +325,14 @@ impl InspectDriver for DockerDriver { ); progress.enable_steady_tick(Duration::from_millis(100)); - let output = self.run_output( - &RunOpts::builder() - .image(SKOPEO_IMAGE) - .args(&["inspect".to_string(), url.clone()]) - .build(), - )?; + let output = self + .run_output( + &RunOpts::builder() + .image(SKOPEO_IMAGE) + .args(&["inspect".to_string(), url.clone()]) + .build(), + ) + .into_diagnostic()?; progress.finish(); Logger::multi_progress().remove(&progress); @@ -334,7 +343,7 @@ impl InspectDriver for DockerDriver { bail!("Failed to inspect image {url}") } - Ok(serde_json::from_slice(&output.stdout)?) + serde_json::from_slice(&output.stdout).into_diagnostic() } } diff --git a/src/drivers/podman_driver.rs b/src/drivers/podman_driver.rs index cdd6039..c0a0519 100644 --- a/src/drivers/podman_driver.rs +++ b/src/drivers/podman_driver.rs @@ -4,7 +4,6 @@ use std::{ time::Duration, }; -use anyhow::{bail, Result}; use blue_build_utils::{ constants::SKOPEO_IMAGE, logging::{CommandLogging, Logger}, @@ -13,6 +12,7 @@ use blue_build_utils::{ use colored::Colorize; use indicatif::{ProgressBar, ProgressStyle}; use log::{debug, error, info, trace, warn}; +use miette::{bail, IntoDiagnostic, Result}; use semver::Version; use serde::Deserialize; use tempdir::TempDir; @@ -55,10 +55,12 @@ impl DriverVersion for PodmanDriver { .arg("version") .arg("-f") .arg("json") - .output()?; + .output() + .into_diagnostic()?; let version_json: PodmanVersionJson = serde_json::from_slice(&output.stdout) - .inspect_err(|e| error!("{e}: {}", String::from_utf8_lossy(&output.stdout)))?; + .inspect_err(|e| error!("{e}: {}", String::from_utf8_lossy(&output.stdout))) + .into_diagnostic()?; trace!("{version_json:#?}"); Ok(version_json.client.version) @@ -85,7 +87,9 @@ impl BuildDriver for PodmanDriver { .arg("-t") .arg(opts.image.as_ref()) .arg("."); - let status = command.status_image_ref_progress(&opts.image, "Building Image")?; + let status = command + .status_image_ref_progress(&opts.image, "Building Image") + .into_diagnostic()?; if status.success() { info!("Successfully built {}", opts.image); @@ -103,7 +107,8 @@ impl BuildDriver for PodmanDriver { .arg("tag") .arg(opts.src_image.as_ref()) .arg(opts.dest_image.as_ref()) - .status()?; + .status() + .into_diagnostic()?; if status.success() { info!("Successfully tagged {}!", opts.dest_image); @@ -125,7 +130,9 @@ impl BuildDriver for PodmanDriver { opts.compression_type.unwrap_or_default() )) .arg(opts.image.as_ref()); - let status = command.status_image_ref_progress(&opts.image, "Pushing Image")?; + let status = command + .status_image_ref_progress(&opts.image, "Pushing Image") + .into_diagnostic()?; if status.success() { info!("Successfully pushed {}!", opts.image); @@ -152,7 +159,8 @@ impl BuildDriver for PodmanDriver { .arg("-p") .arg(password) .arg(registry) - .output()?; + .output() + .into_diagnostic()?; if !output.status.success() { let err_out = String::from_utf8_lossy(&output.stderr); @@ -179,12 +187,14 @@ impl InspectDriver for PodmanDriver { ); progress.enable_steady_tick(Duration::from_millis(100)); - let output = self.run_output( - &RunOpts::builder() - .image(SKOPEO_IMAGE) - .args(&["inspect".to_string(), url.clone()]) - .build(), - )?; + let output = self + .run_output( + &RunOpts::builder() + .image(SKOPEO_IMAGE) + .args(&["inspect".to_string(), url.clone()]) + .build(), + ) + .into_diagnostic()?; progress.finish(); Logger::multi_progress().remove(&progress); @@ -194,7 +204,7 @@ impl InspectDriver for PodmanDriver { } else { bail!("Failed to inspect image {url}"); } - Ok(serde_json::from_slice(&output.stdout)?) + serde_json::from_slice(&output.stdout).into_diagnostic() } } diff --git a/src/drivers/skopeo_driver.rs b/src/drivers/skopeo_driver.rs index 869cd95..9da563c 100644 --- a/src/drivers/skopeo_driver.rs +++ b/src/drivers/skopeo_driver.rs @@ -3,10 +3,10 @@ use std::{ time::Duration, }; -use anyhow::{bail, Result}; use blue_build_utils::logging::Logger; use indicatif::{ProgressBar, ProgressStyle}; use log::{debug, trace}; +use miette::{bail, IntoDiagnostic, Result}; use crate::image_metadata::ImageMetadata; @@ -36,7 +36,8 @@ impl InspectDriver for SkopeoDriver { .arg("inspect") .arg(&url) .stderr(Stdio::inherit()) - .output()?; + .output() + .into_diagnostic()?; progress.finish(); Logger::multi_progress().remove(&progress); @@ -46,6 +47,6 @@ impl InspectDriver for SkopeoDriver { } else { bail!("Failed to inspect image {url}") } - Ok(serde_json::from_slice(&output.stdout)?) + serde_json::from_slice(&output.stdout).into_diagnostic() } } diff --git a/src/rpm_ostree_status.rs b/src/rpm_ostree_status.rs index a07489d..c961a95 100644 --- a/src/rpm_ostree_status.rs +++ b/src/rpm_ostree_status.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, path::Path, process::Command}; -use anyhow::{bail, Result}; use log::trace; +use miette::{bail, IntoDiagnostic, Result}; use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] @@ -29,7 +29,8 @@ impl<'a> RpmOstreeStatus<'a> { trace!("rpm-ostree status --json"); let output = Command::new("rpm-ostree") .args(["status", "--json"]) - .output()?; + .output() + .into_diagnostic()?; if !output.status.success() { bail!("Failed to get `rpm-ostree` status!"); @@ -37,7 +38,7 @@ impl<'a> RpmOstreeStatus<'a> { trace!("{}", String::from_utf8_lossy(&output.stdout)); - Ok(serde_json::from_slice(&output.stdout)?) + serde_json::from_slice(&output.stdout).into_diagnostic() } /// Checks if there is a transaction in progress. diff --git a/utils/Cargo.toml b/utils/Cargo.toml index a86e0b9..d54cb09 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -9,6 +9,7 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1" atty = "0.2" base64 = "0.22.1" blake2 = "0.10.6" @@ -23,7 +24,6 @@ signal-hook = { version = "0.3.17", features = ["extended-siginfo"] } syntect = "5" which = "6" -anyhow.workspace = true chrono.workspace = true clap = { workspace = true, features = ["derive"] } colored.workspace = true @@ -31,6 +31,7 @@ format_serde_error.workspace = true indicatif.workspace = true indicatif-log-bridge.workspace = true log.workspace = true +miette.workspace = true once_cell.workspace = true tempdir.workspace = true serde.workspace = true diff --git a/utils/src/lib.rs b/utils/src/lib.rs index fcf2957..9adc2ef 100644 --- a/utils/src/lib.rs +++ b/utils/src/lib.rs @@ -12,7 +12,6 @@ use std::{ time::Duration, }; -use anyhow::{anyhow, Result}; use base64::prelude::*; use blake2::{ digest::{Update, VariableOutput}, @@ -20,6 +19,7 @@ use blake2::{ }; use format_serde_error::SerdeError; use log::trace; +use miette::{miette, IntoDiagnostic, Result}; use crate::constants::CONTAINER_FILE; @@ -35,14 +35,15 @@ pub fn check_command_exists(command: &str) -> Result<()> { trace!("which {command}"); if Command::new("which") .arg(command) - .output()? + .output() + .into_diagnostic()? .status .success() { trace!("Command {command} does exist"); Ok(()) } else { - Err(anyhow!( + Err(miette!( "Command {command} doesn't exist and is required to build the image" )) } @@ -69,9 +70,9 @@ pub fn serde_yaml_err(contents: &str) -> impl Fn(serde_yaml::Error) -> SerdeErro /// /// # Errors /// Will error when retries have been expended. -pub fn retry(attempts: u8, delay: u64, f: F) -> anyhow::Result +pub fn retry(attempts: u8, delay: u64, f: F) -> miette::Result where - F: Fn() -> anyhow::Result, + F: Fn() -> miette::Result, { let mut attempts = attempts; loop { @@ -100,9 +101,9 @@ pub fn generate_containerfile_path>(path: T) -> Result { const HASH_SIZE: usize = 8; let mut buf = [0u8; HASH_SIZE]; - let mut hasher = Blake2bVar::new(HASH_SIZE)?; + let mut hasher = Blake2bVar::new(HASH_SIZE).into_diagnostic()?; hasher.update(path.as_ref().as_os_str().as_bytes()); - hasher.finalize_variable(&mut buf)?; + hasher.finalize_variable(&mut buf).into_diagnostic()?; Ok(PathBuf::from(format!( "{CONTAINER_FILE}.{}", diff --git a/utils/src/syntax_highlighting.rs b/utils/src/syntax_highlighting.rs index 0bacc43..aff2344 100644 --- a/utils/src/syntax_highlighting.rs +++ b/utils/src/syntax_highlighting.rs @@ -1,6 +1,6 @@ -use anyhow::{anyhow, Result}; use clap::ValueEnum; use log::trace; +use miette::{miette, IntoDiagnostic, Result}; use serde::ser::Serialize; use syntect::{dumps, easy::HighlightLines, highlighting::ThemeSet, parsing::SyntaxSet}; @@ -42,7 +42,8 @@ pub fn highlight(file: &str, file_type: &str, theme: Option) -> R dumps::from_uncompressed_data(include_bytes!(concat!( env!("OUT_DIR"), "/docker_syntax.bin" - )))? + ))) + .into_diagnostic()? } else { SyntaxSet::load_defaults_newlines() }; @@ -50,18 +51,18 @@ pub fn highlight(file: &str, file_type: &str, theme: Option) -> R let syntax = ss .find_syntax_by_extension(file_type) - .ok_or_else(|| anyhow!("Failed to get syntax"))?; + .ok_or_else(|| miette!("Failed to get syntax"))?; let mut h = HighlightLines::new( syntax, ts.themes .get(theme.unwrap_or_default().to_string().as_str()) - .ok_or_else(|| anyhow!("Failed to get highlight theme"))?, + .ok_or_else(|| miette!("Failed to get highlight theme"))?, ); let mut highlighted_lines: Vec = vec![]; for line in file.lines() { highlighted_lines.push(syntect::util::as_24_bit_terminal_escaped( - &h.highlight_line(line, &ss)?, + &h.highlight_line(line, &ss).into_diagnostic()?, false, )); } @@ -83,7 +84,11 @@ pub fn highlight_ser( theme: Option, ) -> Result { trace!("syntax_highlighting::highlight_ser(file, {file_type}, {theme:?})"); - highlight(serde_yaml::to_string(file)?.as_str(), file_type, theme) + highlight( + serde_yaml::to_string(file).into_diagnostic()?.as_str(), + file_type, + theme, + ) } /// Prints the file with syntax highlighting. @@ -108,6 +113,10 @@ pub fn print_ser( theme: Option, ) -> Result<()> { trace!("syntax_highlighting::print_ser(file, {file_type}, {theme:?})"); - print(serde_yaml::to_string(file)?.as_str(), file_type, theme)?; + print( + serde_yaml::to_string(file).into_diagnostic()?.as_str(), + file_type, + theme, + )?; Ok(()) }