fix: output better serde::yaml errors (#47)

Co-authored-by: Gerald Pinder <gmpinder@gmail.com>
This commit is contained in:
Hikari 2024-02-04 20:50:00 -06:00 committed by GitHub
parent 59c3cf55bd
commit 8f44bf4ea0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 107 additions and 64 deletions

87
Cargo.lock generated
View file

@ -147,7 +147,7 @@ dependencies = [
"percent-encoding",
"serde",
"serde_json",
"serde_yaml 0.9.30",
"serde_yaml",
]
[[package]]
@ -305,7 +305,7 @@ dependencies = [
"rusty-hook",
"serde",
"serde_json",
"serde_yaml 0.9.30",
"serde_yaml",
"shadow-rs",
"sigstore",
"tokio",
@ -1144,14 +1144,14 @@ dependencies = [
[[package]]
name = "format_serde_error"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5837b8e6a4001f99fe4746767fb7379e8510c508a843caa136cc12ed9c0bad0"
version = "0.4.0"
source = "git+https://github.com/blue-build/format_serde_error#ef37a22531a28a8c99fe5cfdd06604ad5ab0029e"
dependencies = [
"colored",
"serde",
"serde_json",
"serde_yaml 0.8.26",
"serde_yaml",
"toml 0.8.9",
"unicode-segmentation",
]
@ -2830,7 +2830,7 @@ dependencies = [
"ci_info",
"getopts",
"nias",
"toml",
"toml 0.5.11",
]
[[package]]
@ -2998,6 +2998,15 @@ dependencies = [
"syn 2.0.48",
]
[[package]]
name = "serde_spanned"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -3039,18 +3048,6 @@ dependencies = [
"syn 2.0.48",
]
[[package]]
name = "serde_yaml"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
"indexmap 1.9.3",
"ryu",
"serde",
"yaml-rust",
]
[[package]]
name = "serde_yaml"
version = "0.9.30"
@ -3534,6 +3531,40 @@ dependencies = [
"serde",
]
[[package]]
name = "toml"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
dependencies = [
"indexmap 2.2.1",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "tough"
version = "0.14.0"
@ -4176,6 +4207,15 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "winnow"
version = "0.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cad8365489051ae9f054164e459304af2e7e9bb407c958076c8bf4aef52da5"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.50.0"
@ -4215,15 +4255,6 @@ dependencies = [
"rustix",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zerocopy"
version = "0.7.32"

View file

@ -20,7 +20,7 @@ colorized = "1"
derive_builder = "0.13"
directories = "5"
env_logger = "0.11"
format_serde_error = "0.3.0"
format_serde_error = { git = "https://github.com/blue-build/format_serde_error" }
futures-util = { version = "0.3", optional = true }
fuzzy-matcher = "0.3"
indexmap = { version = "2", features = ["serde"] }
@ -44,10 +44,10 @@ which = "6"
[features]
default = []
nightly = ["builtin-podman"]
builtin-podman = ["podman-api", "tokio", "futures-util"]
tls = ["podman-api/tls", "builtin-podman"]
init = []
nightly = ["podman-api"]
tls = ["podman-api/tls", "podman-api"]
podman-api = ["dep:podman-api", "tokio", "futures-util"]
[dev-dependencies]
rusty-hook = "0.11.2"

View file

@ -5,6 +5,7 @@ use anyhow::Result;
use askama::Template;
use clap::Args;
use clap_complete::Shell;
use format_serde_error::SerdeError;
use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
use log::{debug, error, trace};
use requestty::question::{completions, Completions};
@ -390,10 +391,16 @@ fn get_module_from_file(file_name: &str) -> Result<ModuleExt> {
let file = fs::read_to_string(file_path.clone())?;
serde_yaml::from_str::<ModuleExt>(file.as_str()).map_or_else(
|_| -> Result<ModuleExt> {
let module = serde_yaml::from_str::<Module>(file.as_str())?;
serde_yaml::from_str::<ModuleExt>(&file).map_or_else(
|err| -> Result<ModuleExt> {
error!(
"Failed to parse module from {}: {}",
file_path.display(),
SerdeError::new(file.to_owned(), err).to_string()
);
let module =
serde_yaml::from_str::<Module>(&file).map_err(|err| SerdeError::new(file, err))?;
Ok(ModuleExt::builder().modules(vec![module]).build())
},
Ok,

View file

@ -9,6 +9,7 @@ use std::{
use anyhow::{anyhow, bail, Result};
use clap::Args;
use format_serde_error::SerdeError;
use log::{debug, info, trace, warn};
use typed_builder::TypedBuilder;
@ -21,9 +22,6 @@ use podman_api::{
#[cfg(feature = "podman-api")]
use build_strategy::BuildStrategy;
#[cfg(feature = "futures-util")]
use futures_util::StreamExt;
#[cfg(feature = "tokio")]
use tokio::runtime::Runtime;
@ -188,6 +186,8 @@ impl BlueBuildCommand for BuildCommand {
impl BuildCommand {
#[cfg(feature = "podman-api")]
async fn build_image_podman_api(&self, client: Podman, recipe_path: &Path) -> Result<()> {
use futures_util::StreamExt;
trace!("BuildCommand::build_image({client:#?})");
let credentials = self.get_login_creds();
@ -196,7 +196,9 @@ impl BuildCommand {
bail!("Failed to get credentials");
}
let recipe: Recipe = serde_yaml::from_str(fs::read_to_string(recipe_path)?.as_str())?;
let recipe_str = fs::read_to_string(recipe_path)?;
let recipe: Recipe = serde_yaml::from_str(&recipe_str)
.map_err(|err| SerdeError::new(recipe_str.to_owned(), err))?;
trace!("recipe: {recipe:#?}");
// Get values for image
@ -280,7 +282,9 @@ impl BuildCommand {
fn build_image(&self, recipe_path: &Path) -> Result<()> {
trace!("BuildCommand::build_image()");
let recipe: Recipe = serde_yaml::from_str(fs::read_to_string(recipe_path)?.as_str())?;
let recipe_str = fs::read_to_string(recipe_path)?;
let recipe: Recipe = serde_yaml::from_str(&recipe_str)
.map_err(|err| SerdeError::new(recipe_str.to_owned(), err))?;
let tags = recipe.generate_tags();

View file

@ -6,6 +6,7 @@ use std::{
use anyhow::{bail, Result};
use clap::Args;
use format_serde_error::SerdeError;
use log::{debug, info, trace};
use typed_builder::TypedBuilder;
use users::{Users, UsersCache};
@ -43,8 +44,10 @@ impl BlueBuildCommand for UpgradeCommand {
check_can_run()?;
let recipe: Recipe =
serde_yaml::from_str(fs::read_to_string(&self.common.recipe)?.as_str())?;
let recipe_str = fs::read_to_string(&self.common.recipe)?;
let recipe: Recipe = serde_yaml::from_str(&recipe_str)
.map_err(|err| SerdeError::new(recipe_str.to_owned(), err))?;
let mut build = BuildCommand::builder()
.recipe(self.common.recipe.clone())
.archive(LOCAL_BUILD)
@ -90,8 +93,10 @@ impl BlueBuildCommand for RebaseCommand {
check_can_run()?;
let recipe: Recipe =
serde_yaml::from_str(fs::read_to_string(&self.common.recipe)?.as_str())?;
let recipe_str = fs::read_to_string(&self.common.recipe)?;
let recipe: Recipe = serde_yaml::from_str(&recipe_str)
.map_err(|err| SerdeError::new(recipe_str.to_owned(), err))?;
let mut build = BuildCommand::builder()
.recipe(self.common.recipe.clone())
.archive(LOCAL_BUILD)

View file

@ -7,6 +7,7 @@ use std::{
use anyhow::Result;
use askama::Template;
use clap::Args;
use format_serde_error::SerdeError;
use log::{debug, error, info, trace};
use typed_builder::TypedBuilder;
@ -184,8 +185,11 @@ fn template_module_from_file(file_name: &str) -> String {
serde_yaml::from_str::<ModuleExt>(file.as_str()).map_or_else(
|_| {
let module = serde_yaml::from_str::<Module>(file.as_str()).unwrap_or_else(|e| {
error!("Failed to deserialize module {file_name}: {e}");
let module = serde_yaml::from_str::<Module>(file.as_str()).unwrap_or_else(|err| {
error!(
"Failed to deserialize module {file_name}: {}",
SerdeError::new(file_name.to_owned(), err)
);
process::exit(1);
});

View file

@ -1,15 +1,10 @@
use std::{
borrow::Cow,
collections::HashMap,
env, fs,
path::Path,
process::{self, Command},
};
use std::{borrow::Cow, collections::HashMap, env, fs, path::Path, process::Command};
use anyhow::Result;
use chrono::Local;
use format_serde_error::SerdeError;
use indexmap::IndexMap;
use log::{debug, error, info, trace, warn};
use log::{debug, info, trace, warn};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use serde_yaml::Value;
@ -137,17 +132,11 @@ impl<'a> Recipe<'a> {
let recipe_path_string = recipe_path.display().to_string();
debug!("Recipe::parse_recipe({recipe_path_string})");
let file = fs::read_to_string(recipe_path).unwrap_or_else(|e| {
error!("Failed to read file {recipe_path_string}: {e}");
process::exit(1);
});
let file = fs::read_to_string(recipe_path)?;
debug!("Recipe contents: {file}");
serde_yaml::from_str::<Recipe>(file.as_str()).map_err(|e| {
error!("Failed to parse recipe {recipe_path_string}: {e}");
process::exit(1);
})
Ok(serde_yaml::from_str::<Recipe>(&file).map_err(|err| SerdeError::new(file, err))?)
}
fn get_os_version(&self) -> String {
@ -185,8 +174,11 @@ impl<'a> Recipe<'a> {
let inspection: ImageInspection = match serde_json::from_str(
String::from_utf8_lossy(&output.stdout).as_ref(),
) {
Err(_) => {
warn!("Issue deserializing 'skopeo' output, falling back to version defined in recipe");
Err(err) => {
let err_msg =
SerdeError::new(String::from_utf8_lossy(&output.stdout).to_string(), err)
.to_string();
warn!("Issue deserializing 'skopeo' output, falling back to version defined in recipe. {err_msg}",);
return self.image_version.to_string();
}
Ok(inspection) => inspection,