Skip to content

Commit 6bc0152

Browse files
authored
Fix: Devcontainer Index - Add Error Context (#16)
* Split parsing a collection to improve error context. * list: Avoid displaying empty collection table.
1 parent f443154 commit 6bc0152

File tree

2 files changed

+79
-43
lines changed

2 files changed

+79
-43
lines changed

src/list.rs

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,41 @@ fn collection_templates_and_features(oci_reference: &str, collection: &Collectio
2222
println!("Repository: {}", &source_information.repository);
2323
println!("OCI Reference: {}", &source_information.oci_reference);
2424

25-
let search_results = {
26-
let features = collection.features.iter().map(search::SearchResult::from);
27-
let templates = collection.templates.iter().map(search::SearchResult::from);
28-
features.chain(templates)
29-
};
30-
let data: Vec<[String; 5]> = search_results
31-
.enumerate()
32-
.map(|(i, r)| {
33-
let description = r
34-
.description
35-
.as_ref()
36-
.and_then(|d| d.lines().next())
37-
.unwrap_or_default();
38-
[
39-
(i + 1).to_string(),
40-
r.collection.to_string(),
41-
r.id.replace(oci_reference, "~"),
42-
r.name.to_string(),
43-
description.to_string(),
44-
]
45-
})
46-
.collect();
47-
let mut table = ascii_table::AsciiTable::default();
48-
49-
table.column(0).set_align(ascii_table::Align::Right);
50-
table.column(1).set_header("Type");
51-
table.column(2).set_header("OCI Reference");
52-
table.column(3).set_header("Name").set_max_width(40);
53-
table.column(4).set_header("Description").set_max_width(75);
54-
55-
table.print(data);
25+
let count = collection.features.len() + collection.templates.len();
26+
27+
if count > 0 {
28+
let search_results = {
29+
let features = collection.features.iter().map(search::SearchResult::from);
30+
let templates = collection.templates.iter().map(search::SearchResult::from);
31+
features.chain(templates)
32+
};
33+
let data: Vec<[String; 5]> = search_results
34+
.enumerate()
35+
.map(|(i, r)| {
36+
let description = r
37+
.description
38+
.as_ref()
39+
.and_then(|d| d.lines().next())
40+
.unwrap_or_default();
41+
[
42+
(i + 1).to_string(),
43+
r.collection.to_string(),
44+
r.id.replace(oci_reference, "~"),
45+
r.name.to_string(),
46+
description.to_string(),
47+
]
48+
})
49+
.collect();
50+
let mut table = ascii_table::AsciiTable::default();
51+
52+
table.column(0).set_align(ascii_table::Align::Right);
53+
table.column(1).set_header("Type");
54+
table.column(2).set_header("OCI Reference");
55+
table.column(3).set_header("Name").set_max_width(40);
56+
table.column(4).set_header("Description").set_max_width(75);
57+
58+
table.print(data);
59+
}
5660
}
5761

5862
fn overview_collections(index: &DevcontainerIndex) {

src/registry.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -473,18 +473,50 @@ pub fn read_devcontainer_index<P: AsRef<Path>>(filename: P) -> Result<Devcontain
473473
|arr| {
474474
let parsed = arr
475475
.iter()
476-
// TODO: Skip errors of a single feature or template, not the entire collection
477-
.filter_map(|value| match serde_json::from_value::<Collection>(value.to_owned()) {
478-
Ok(collection) => {
479-
features_count += collection.features.len();
480-
templates_count += collection.templates.len();
481-
Some(collection)
482-
},
483-
Err(_) => {
484-
// TODO: parse the collection fields so that source_information can be displayed here.
485-
log::warn!("Skipping collection due to parsing error");
486-
None
487-
},
476+
.filter_map(|value| {
477+
let source_information: SourceInformation = value
478+
.get("sourceInformation")
479+
.and_then(|value| serde_json::from_value(value.to_owned()).ok())?;
480+
let features = value.get("features").and_then(|value| value.as_array())?;
481+
let features = features
482+
.iter()
483+
.flat_map(|value| match serde_json::from_value::<Feature>(value.to_owned()) {
484+
Ok(feature) => {
485+
features_count += 1;
486+
Some(feature)
487+
},
488+
Err(_) => {
489+
log::warn!(
490+
"Skipping feature due to parsing error. Collection.oci_ref = {}",
491+
&source_information.oci_reference
492+
);
493+
None
494+
},
495+
})
496+
.collect();
497+
let templates = value.get("templates").and_then(|value| value.as_array())?;
498+
let templates = templates
499+
.iter()
500+
.flat_map(|value| match serde_json::from_value::<Template>(value.to_owned()) {
501+
Ok(template) => {
502+
templates_count += 1;
503+
Some(template)
504+
},
505+
Err(_) => {
506+
log::warn!(
507+
"Skipping template due to parsing error. Collection.oci_ref = {}",
508+
&source_information.oci_reference
509+
);
510+
None
511+
},
512+
})
513+
.collect();
514+
515+
Some(Collection {
516+
source_information,
517+
features,
518+
templates,
519+
})
488520
})
489521
.collect();
490522

0 commit comments

Comments
 (0)