Skip to content

Commit

Permalink
fix: Improve validation errors
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Dec 19, 2024
1 parent 000fc9a commit ab681f4
Show file tree
Hide file tree
Showing 73 changed files with 2,659 additions and 403 deletions.
336 changes: 165 additions & 171 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ tempfile.workspace = true
tokio = { workspace = true, optional = true }
bon.workspace = true
users.workspace = true
thiserror = "2.0.7"

[features]
# Top level features
Expand Down
37 changes: 22 additions & 15 deletions src/commands/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,21 @@ impl BlueBuildCommand for ValidateCommand {
impl ValidateCommand {
async fn setup_validators(&mut self) -> Result<(), Report> {
let (rv, sv, mv, mslv) = tokio::try_join!(
SchemaValidator::builder().url(RECIPE_V1_SCHEMA_URL).build(),
SchemaValidator::builder().url(STAGE_V1_SCHEMA_URL).build(),
SchemaValidator::builder().url(MODULE_V1_SCHEMA_URL).build(),
SchemaValidator::builder()
.url(RECIPE_V1_SCHEMA_URL)
.all_errors(self.all_errors)
.build(),
SchemaValidator::builder()
.url(STAGE_V1_SCHEMA_URL)
.all_errors(self.all_errors)
.build(),
SchemaValidator::builder()
.url(MODULE_V1_SCHEMA_URL)
.all_errors(self.all_errors)
.build(),
SchemaValidator::builder()
.url(MODULE_STAGE_LIST_V1_SCHEMA_URL)
.all_errors(self.all_errors)
.build(),
)?;
self.recipe_validator = Some(rv);
Expand Down Expand Up @@ -149,15 +159,12 @@ impl ValidateCommand {

if instance.get(DF::LIST_KEY).is_some() {
debug!("{path_display} is a list file");
let err = match self
let err = self
.module_stage_list_validator
.as_ref()
.unwrap()
.process_validation(path, file_str.clone(), self.all_errors)
{
Err(e) => return vec![e],
Ok(e) => e,
};
.process_validation(path, file_str.clone())
.err();

err.map_or_else(
|| {
Expand Down Expand Up @@ -195,13 +202,13 @@ impl ValidateCommand {
},
)
},
|err| vec![err],
|err| vec![err.into()],
)
} else {
debug!("{path_display} is a single file file");
single_validator
.process_validation(path, file_str, self.all_errors)
.map_or_else(|e| vec![e], |e| e.map_or_else(Vec::new, |e| vec![e]))
.process_validation(path, file_str)
.map_or_else(|e| vec![e.into()], |()| Vec::new())
}
}
Err(e) => vec![e],
Expand All @@ -221,11 +228,11 @@ impl ValidateCommand {

let schema_validator = self.recipe_validator.as_ref().unwrap();
let err = schema_validator
.process_validation(&self.recipe, recipe_str.clone(), self.all_errors)
.map_err(err_vec)?;
.process_validation(&self.recipe, recipe_str.clone())
.err();

if let Some(err) = err {
Err(vec![err])
Err(vec![err.into()])
} else {
let recipe: Recipe = serde_yaml::from_str(&recipe_str)
.into_diagnostic()
Expand Down
49 changes: 26 additions & 23 deletions src/commands/validate/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,34 +87,37 @@ impl TryFrom<String> for Location {
}
}

pub struct LocationSegmentIterator<'a> {
iter: std::vec::IntoIter<LocationSegment<'a>>,
}

impl<'a> Iterator for LocationSegmentIterator<'a> {
impl<'a> IntoIterator for &'a Location {
type Item = LocationSegment<'a>;
type IntoIter = std::vec::IntoIter<LocationSegment<'a>>;

fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
fn into_iter(self) -> Self::IntoIter {
self.as_str()
.split('/')
.filter(|p| !p.is_empty())
.map(|p| {
p.parse::<usize>()
.map_or_else(|_| LocationSegment::Property(p), LocationSegment::Index)
})
.collect::<Vec<_>>()
.into_iter()
}
}

impl<'a> IntoIterator for &'a Location {
type Item = LocationSegment<'a>;
type IntoIter = LocationSegmentIterator<'a>;

fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
iter: self
.as_str()
.split('/')
.filter(|p| !p.is_empty())
.map(|p| {
p.parse::<usize>()
.map_or_else(|_| LocationSegment::Property(p), LocationSegment::Index)
})
.collect::<Vec<_>>()
.into_iter(),
impl<'a> FromIterator<LocationSegment<'a>> for Location {
fn from_iter<T: IntoIterator<Item = LocationSegment<'a>>>(iter: T) -> Self {
fn inner<'a, 'b, 'c, I>(path_iter: &mut I, location: &'b LazyLocation<'b, 'a>) -> Location
where
I: Iterator<Item = LocationSegment<'c>>,
{
let Some(path) = path_iter.next() else {
return JsonLocation::from(location).into();
};
let location = location.push(path);
inner(path_iter, &location)
}

let loc = LazyLocation::default();
inner(&mut iter.into_iter(), &loc)
}
}
Loading

0 comments on commit ab681f4

Please sign in to comment.