From 0a56c5efe35b49257dd11dc5306cca55696620c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Ochagav=C3=ADa?= Date: Fri, 2 Feb 2024 15:43:00 +0100 Subject: [PATCH] wip: proper unicode characters in error messages --- src/problem.rs | 261 +++++++++++++++--- tests/snapshots/solver__excluded.snap | 14 +- tests/snapshots/solver__merge_excluded.snap | 4 +- .../snapshots/solver__merge_installable.snap | 8 +- ...erge_installable_non_continuous_range.snap | 8 +- tests/snapshots/solver__root_excluded.snap | 4 +- .../solver__unsat_after_backtracking.snap | 16 +- ...lver__unsat_applies_graph_compression.snap | 16 +- .../solver__unsat_bluesky_conflict.snap | 13 +- tests/snapshots/solver__unsat_constrains.snap | 14 +- .../snapshots/solver__unsat_constrains_2.snap | 22 +- ..._unsat_incompatible_root_requirements.snap | 9 +- .../solver__unsat_locked_and_excluded.snap | 13 +- ...lver__unsat_no_candidates_for_child_1.snap | 5 +- ...lver__unsat_no_candidates_for_child_2.snap | 5 +- .../solver__unsat_pubgrub_article.snap | 21 +- 16 files changed, 300 insertions(+), 133 deletions(-) diff --git a/src/problem.rs b/src/problem.rs index f410cf3..78b562c 100644 --- a/src/problem.rs +++ b/src/problem.rs @@ -510,6 +510,114 @@ impl ProblemGraph { } } +#[derive(Copy, Clone, PartialEq, Eq)] +enum ChildOrder { + HasRemainingSiblings, + Last, +} + +struct Indenter { + levels: Vec, + top_level_indent: bool, +} + +impl Indenter { + fn new(top_level_indent: bool) -> Self { + Self { + levels: Vec::new(), + top_level_indent, + } + } + + fn is_at_top_level(&self) -> bool { + self.levels.len() == 1 + } + + fn push_level(&self) -> Self { + self.push_level_with_order(ChildOrder::HasRemainingSiblings) + } + + fn push_level_with_order(&self, order: ChildOrder) -> Self { + let mut levels = self.levels.clone(); + levels.push(order); + Self { + levels, + top_level_indent: self.top_level_indent, + } + } + + fn set_last(&mut self) { + *self.levels.last_mut().unwrap() = ChildOrder::Last; + } + + fn get_indent(&self) -> String { + assert!(!self.levels.is_empty()); + + let mut s = String::new(); + + let deepest_level = self.levels.len() - 1; + + for (level, &order) in self.levels.iter().enumerate() { + if level == 0 && !self.top_level_indent { + // Skip + continue; + } + + let is_at_deepest_level = level == deepest_level; + + let tree_prefix = match (is_at_deepest_level, order) { + (true, ChildOrder::HasRemainingSiblings) => "├─", + (true, ChildOrder::Last) => "└─", + (false, ChildOrder::HasRemainingSiblings) => "│ ", + (false, ChildOrder::Last) => " ", + }; + + // TODO: are these the right characters? Alternatives: https://en.wikipedia.org/wiki/Box-drawing_character or look at mamba + + s.push_str(tree_prefix); + s.push(' '); + } + + s + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_indenter_without_top_level_indent() { + let indenter = Indenter::new(false); + + let indenter = indenter.push_level_with_order(ChildOrder::Last); + assert_eq!(indenter.get_indent(), ""); + + let indenter = indenter.push_level_with_order(ChildOrder::Last); + assert_eq!(indenter.get_indent(), "└─ "); + } + + #[test] + fn test_indenter_with_multiple_siblings() { + let indenter = Indenter::new(true); + + let indenter = indenter.push_level_with_order(ChildOrder::Last); + assert_eq!(indenter.get_indent(), "└─ "); + + let indenter = indenter.push_level_with_order(ChildOrder::HasRemainingSiblings); + assert_eq!(indenter.get_indent(), " ├─ "); + + let indenter = indenter.push_level_with_order(ChildOrder::Last); + assert_eq!(indenter.get_indent(), " │ └─ "); + + let indenter = indenter.push_level_with_order(ChildOrder::Last); + assert_eq!(indenter.get_indent(), " │ └─ "); + + let indenter = indenter.push_level_with_order(ChildOrder::HasRemainingSiblings); + assert_eq!(indenter.get_indent(), " │ ├─ "); + } +} + /// A struct implementing [`fmt::Display`] that generates a user-friendly representation of a /// problem graph pub struct DisplayUnsat< @@ -554,19 +662,6 @@ impl< } } - fn get_indent(depth: usize, top_level_indent: bool) -> String { - let depth_correction = if depth > 0 && !top_level_indent { 1 } else { 0 }; - - let mut indent = " ".repeat((depth - depth_correction) * 4); - - let display_tree_char = depth != 0 || top_level_indent; - if display_tree_char { - indent.push_str("|-- "); - } - - indent - } - fn fmt_graph( &self, f: &mut Formatter<'_>, @@ -609,6 +704,7 @@ impl< let mut reported: HashSet = HashSet::new(); // Note: we are only interested in requires edges here + let indenter = Indenter::new(top_level_indent); let mut stack = top_level_edges .iter() .filter(|e| e.weight().try_requires().is_some()) @@ -623,10 +719,17 @@ impl< .iter() .any(|&edge| installable_nodes.contains(&graph.edge_endpoints(edge).unwrap().1)) }) - .map(|(version_set_id, edges)| (DisplayOp::Requirement(version_set_id, edges), 0)) + .map(|(version_set_id, edges)| (DisplayOp::Requirement(version_set_id, edges), indenter.push_level())) .collect::>(); - while let Some((node, depth)) = stack.pop() { - let indent = Self::get_indent(depth, top_level_indent); + + if !stack.is_empty() { + // Mark the first element of the stack as not having any remaining siblings + stack[0].1.set_last(); + } + + while let Some((node, indenter)) = stack.pop() { + let top_level = indenter.is_at_top_level(); + let indent = indenter.get_indent(); match node { DisplayOp::Requirement(version_set_id, edges) => { @@ -652,7 +755,7 @@ impl< edges.len() == 1 && graph[target_nx] == ProblemNode::UnresolvedDependency; if missing { // No candidates for requirement - if depth == 0 { + if top_level { writeln!(f, "{indent}No candidates were found for {name} {req}.")?; } else { writeln!( @@ -662,7 +765,7 @@ impl< } } else if installable { // Package can be installed (only mentioned for top-level requirements) - if depth == 0 { + if top_level { writeln!( f, "{indent}{name} {req} can be installed with any of the following options:" @@ -671,33 +774,85 @@ impl< writeln!(f, "{indent}{name} {req}, which can be installed with any of the following options:")?; } - stack.extend( - edges - .iter() - .filter(|&&e| { - installable_nodes.contains(&graph.edge_endpoints(e).unwrap().1) - }) - .map(|&e| { - ( - DisplayOp::Candidate(graph.edge_endpoints(e).unwrap().1), - depth + 1, - ) - }), - ); + let mut children: Vec<_> = edges + .iter() + .filter(|&&e| { + installable_nodes.contains(&graph.edge_endpoints(e).unwrap().1) + }) + .map(|&e| { + ( + DisplayOp::Candidate(graph.edge_endpoints(e).unwrap().1), + indenter.push_level(), + ) + }) + .collect(); + + // TODO: this is an utterly ugly hack that should be burnt to ashes + let mut deduplicated_children = Vec::new(); + let mut merged_and_seen = HashSet::new(); + for child in children { + let (DisplayOp::Candidate(child_node), _) = child else { unreachable!() }; + let solvable_id = graph[child_node].solvable_id(); + let merged = self.merged_candidates.get(&solvable_id); + + // Skip merged stuff that we have already seen + if merged_and_seen.contains(&solvable_id) { + continue; + } + + if let Some(merged) = merged { + merged_and_seen.extend(merged.ids.iter().copied()) + } + + deduplicated_children.push(child); + } + + if !deduplicated_children.is_empty() { + deduplicated_children[0].1.set_last(); + } + + stack.extend(deduplicated_children); } else { // Package cannot be installed (the conflicting requirement is further down the tree) - if depth == 0 { + if top_level { writeln!(f, "{indent}{name} {req} cannot be installed because there are no viable options:")?; } else { writeln!(f, "{indent}{name} {req}, which cannot be installed because there are no viable options:")?; } - stack.extend(edges.iter().map(|&e| { + let children: Vec<_> = edges.iter() + .map(|&e| { ( DisplayOp::Candidate(graph.edge_endpoints(e).unwrap().1), - depth + 1, + indenter.push_level(), ) - })); + }).collect(); + + // TODO: this is an utterly ugly hack that should be burnt to ashes + let mut deduplicated_children = Vec::new(); + let mut merged_and_seen = HashSet::new(); + for child in children { + let (DisplayOp::Candidate(child_node), _) = child else { unreachable!() }; + let solvable_id = graph[child_node].solvable_id(); + let merged = self.merged_candidates.get(&solvable_id); + + // Skip merged stuff that we have already seen + if merged_and_seen.contains(&solvable_id) { + continue; + } + + if let Some(merged) = merged { + merged_and_seen.extend(merged.ids.iter().copied()) + } + + deduplicated_children.push(child); + } + + if !deduplicated_children.is_empty() { + deduplicated_children[0].1.set_last(); + } + + stack.extend(deduplicated_children); } } DisplayOp::Candidate(candidate) => { @@ -798,7 +953,7 @@ impl< } else if already_installed { writeln!(f, "{indent}{name} {version}, which conflicts with the versions reported above.")?; } else if constrains_conflict { - let version_sets = graph + let mut version_sets = graph .edges(candidate) .flat_map(|e| match e.weight() { ProblemEdge::Conflict(ConflictCause::Constrains( @@ -806,12 +961,13 @@ impl< )) => Some(version_set_id), _ => None, }) - .dedup(); + .dedup() + .peekable(); writeln!(f, "{indent}{name} {version} would constrain",)?; - let indent = Self::get_indent(depth + 1, top_level_indent); - for &version_set_id in version_sets { + let mut indenter = indenter.push_level(); + while let Some(&version_set_id) = version_sets.next() { let version_set = self.solver_cache.pool().resolve_version_set(version_set_id); let name = self @@ -819,6 +975,11 @@ impl< .pool() .resolve_version_set_package_name(version_set_id); let name = self.solver_cache.pool().resolve_package_name(name); + + if version_sets.peek().is_none() { + indenter.set_last(); + } + let indent = indenter.get_indent(); writeln!( f, "{indent}{name} {version_set} , which conflicts with any installable versions previously reported", @@ -826,7 +987,7 @@ impl< } } else { writeln!(f, "{indent}{name} {version} would require",)?; - let requirements = graph + let mut requirements = graph .edges(candidate) .group_by(|e| e.weight().requires()) .into_iter() @@ -841,8 +1002,13 @@ impl< }) }) .map(|(version_set_id, edges)| { - (DisplayOp::Requirement(version_set_id, edges), depth + 1) - }); + (DisplayOp::Requirement(version_set_id, edges), indenter.push_level()) + }) + .collect::>(); + + if !requirements.is_empty() { + requirements[0].1.set_last(); + } stack.extend(requirements); } @@ -877,8 +1043,15 @@ impl< self.fmt_graph(f, &top_level_conflicts, true)?; // Conflicts caused by locked dependencies - let indent = Self::get_indent(0, true); - for e in self.graph.graph.edges(self.graph.root_node) { + let mut edges = self.graph.graph.edges(self.graph.root_node).peekable(); + let indenter = Indenter::new(true); + while let Some(e) = edges.next() { + let indenter = indenter.push_level_with_order(match edges.peek() { + Some(_) => ChildOrder::HasRemainingSiblings, + None => ChildOrder::Last, + }); + let indent = indenter.get_indent(); + let conflict = match e.weight() { ProblemEdge::Requires(_) => continue, ProblemEdge::Conflict(conflict) => conflict, diff --git a/tests/snapshots/solver__excluded.snap b/tests/snapshots/solver__excluded.snap index 9bae558..cb59d19 100644 --- a/tests/snapshots/solver__excluded.snap +++ b/tests/snapshots/solver__excluded.snap @@ -3,11 +3,11 @@ source: tests/solver.rs expression: "solve_snapshot(provider, &[\"a\"])" --- The following packages are incompatible -|-- a * cannot be installed because there are no viable options: - |-- a 2 would require - |-- b *, which cannot be installed because there are no viable options: - |-- b 1 is excluded because it is externally excluded - |-- a 1 would require - |-- c *, which cannot be installed because there are no viable options: - |-- c 1 is excluded because it is externally excluded +└─ a * cannot be installed because there are no viable options: + ├─ a 2 would require + │ └─ b *, which cannot be installed because there are no viable options: + │ └─ b 1 is excluded because it is externally excluded + └─ a 1 would require + └─ c *, which cannot be installed because there are no viable options: + └─ c 1 is excluded because it is externally excluded diff --git a/tests/snapshots/solver__merge_excluded.snap b/tests/snapshots/solver__merge_excluded.snap index 444b622..eaf1d26 100644 --- a/tests/snapshots/solver__merge_excluded.snap +++ b/tests/snapshots/solver__merge_excluded.snap @@ -3,6 +3,6 @@ source: tests/solver.rs expression: "solve_snapshot(provider, &[\"a\"])" --- The following packages are incompatible -|-- a * cannot be installed because there are no viable options: - |-- a >=1, <=2 is excluded because it is externally excluded +└─ a * cannot be installed because there are no viable options: + └─ a >=1, <=2 is excluded because it is externally excluded diff --git a/tests/snapshots/solver__merge_installable.snap b/tests/snapshots/solver__merge_installable.snap index e218ff8..e56cb6a 100644 --- a/tests/snapshots/solver__merge_installable.snap +++ b/tests/snapshots/solver__merge_installable.snap @@ -3,8 +3,8 @@ source: tests/solver.rs expression: "solve_snapshot(provider, &[\"a 0..3\", \"a 3..5\"])" --- The following packages are incompatible -|-- a >=3, <5 can be installed with any of the following options: - |-- a >=3, <=4 -|-- a >=0, <3 cannot be installed because there are no viable options: - |-- a >=1, <=2, which conflicts with the versions reported above. +├─ a >=3, <5 can be installed with any of the following options: +│ └─ a >=3, <=4 +└─ a >=0, <3 cannot be installed because there are no viable options: + └─ a >=1, <=2, which conflicts with the versions reported above. diff --git a/tests/snapshots/solver__merge_installable_non_continuous_range.snap b/tests/snapshots/solver__merge_installable_non_continuous_range.snap index 0f6fa3d..1fa63ce 100644 --- a/tests/snapshots/solver__merge_installable_non_continuous_range.snap +++ b/tests/snapshots/solver__merge_installable_non_continuous_range.snap @@ -3,8 +3,8 @@ source: tests/solver.rs expression: "solve_snapshot(provider, &[\"a 1\", \"a 2..20\"])" --- The following packages are incompatible -|-- a >=2, <20 can be installed with any of the following options: - |-- a 19 | >=16, <=17 | >=9, <=14 | >=2, <=7 -|-- a >=1, <2 cannot be installed because there are no viable options: - |-- a 1, which conflicts with the versions reported above. +├─ a >=2, <20 can be installed with any of the following options: +│ └─ a 19 | >=16, <=17 | >=9, <=14 | >=2, <=7 +└─ a >=1, <2 cannot be installed because there are no viable options: + └─ a 1, which conflicts with the versions reported above. diff --git a/tests/snapshots/solver__root_excluded.snap b/tests/snapshots/solver__root_excluded.snap index d9a1002..da4e821 100644 --- a/tests/snapshots/solver__root_excluded.snap +++ b/tests/snapshots/solver__root_excluded.snap @@ -3,6 +3,6 @@ source: tests/solver.rs expression: "solve_snapshot(provider, &[\"a\"])" --- The following packages are incompatible -|-- a * cannot be installed because there are no viable options: - |-- a 1 is excluded because it is externally excluded +└─ a * cannot be installed because there are no viable options: + └─ a 1 is excluded because it is externally excluded diff --git a/tests/snapshots/solver__unsat_after_backtracking.snap b/tests/snapshots/solver__unsat_after_backtracking.snap index 73ee8dc..ee6469c 100644 --- a/tests/snapshots/solver__unsat_after_backtracking.snap +++ b/tests/snapshots/solver__unsat_after_backtracking.snap @@ -3,12 +3,12 @@ source: tests/solver.rs expression: error --- The following packages are incompatible -|-- b * can be installed with any of the following options: - |-- b >=6, <=7 would require - |-- d >=1, <2, which can be installed with any of the following options: - |-- d 1 -|-- c * cannot be installed because there are no viable options: - |-- c >=1, <=2 would require - |-- d >=2, <3, which cannot be installed because there are no viable options: - |-- d 2, which conflicts with the versions reported above. +├─ b * can be installed with any of the following options: +│ └─ b >=6, <=7 would require +│ └─ d >=1, <2, which can be installed with any of the following options: +│ └─ d 1 +└─ c * cannot be installed because there are no viable options: + └─ c >=1, <=2 would require + └─ d >=2, <3, which cannot be installed because there are no viable options: + └─ d 2, which conflicts with the versions reported above. diff --git a/tests/snapshots/solver__unsat_applies_graph_compression.snap b/tests/snapshots/solver__unsat_applies_graph_compression.snap index e36ec24..b5f21cc 100644 --- a/tests/snapshots/solver__unsat_applies_graph_compression.snap +++ b/tests/snapshots/solver__unsat_applies_graph_compression.snap @@ -3,12 +3,12 @@ source: tests/solver.rs expression: error --- The following packages are incompatible -|-- a * can be installed with any of the following options: - |-- a >=9, <=10 would require - |-- b *, which can be installed with any of the following options: - |-- b >=42, <=100 would require - |-- c >=0, <100, which can be installed with any of the following options: - |-- c 99 -|-- c >=101, <104 cannot be installed because there are no viable options: - |-- c >=101, <=103, which conflicts with the versions reported above. +├─ a * can be installed with any of the following options: +│ └─ a >=9, <=10 would require +│ └─ b *, which can be installed with any of the following options: +│ └─ b >=42, <=100 would require +│ └─ c >=0, <100, which can be installed with any of the following options: +│ └─ c 99 +└─ c >=101, <104 cannot be installed because there are no viable options: + └─ c >=101, <=103, which conflicts with the versions reported above. diff --git a/tests/snapshots/solver__unsat_bluesky_conflict.snap b/tests/snapshots/solver__unsat_bluesky_conflict.snap index 6eb7781..b17d776 100644 --- a/tests/snapshots/solver__unsat_bluesky_conflict.snap +++ b/tests/snapshots/solver__unsat_bluesky_conflict.snap @@ -1,13 +1,12 @@ --- source: tests/solver.rs -assertion_line: 638 expression: error --- The following packages are incompatible -|-- bluesky-widgets >=0, <100 can be installed with any of the following options: - |-- bluesky-widgets 42 would require - |-- suitcase-utils >=0, <54, which can be installed with any of the following options: - |-- suitcase-utils 53 -|-- suitcase-utils >=54, <100 cannot be installed because there are no viable options: - |-- suitcase-utils 54, which conflicts with the versions reported above. +├─ bluesky-widgets >=0, <100 can be installed with any of the following options: +│ └─ bluesky-widgets 42 would require +│ └─ suitcase-utils >=0, <54, which can be installed with any of the following options: +│ └─ suitcase-utils 53 +└─ suitcase-utils >=54, <100 cannot be installed because there are no viable options: + └─ suitcase-utils 54, which conflicts with the versions reported above. diff --git a/tests/snapshots/solver__unsat_constrains.snap b/tests/snapshots/solver__unsat_constrains.snap index d785d80..4d42711 100644 --- a/tests/snapshots/solver__unsat_constrains.snap +++ b/tests/snapshots/solver__unsat_constrains.snap @@ -3,11 +3,11 @@ source: tests/solver.rs expression: error --- The following packages are incompatible -|-- a * can be installed with any of the following options: - |-- a >=9, <=10 would require - |-- b >=50, <100, which can be installed with any of the following options: - |-- b 50 -|-- c * cannot be installed because there are no viable options: - |-- c >=8, <=10 would constrain - |-- b >=0, <50 , which conflicts with any installable versions previously reported +├─ a * can be installed with any of the following options: +│ └─ a >=9, <=10 would require +│ └─ b >=50, <100, which can be installed with any of the following options: +│ └─ b 50 +└─ c * cannot be installed because there are no viable options: + └─ c >=8, <=10 would constrain + └─ b >=0, <50 , which conflicts with any installable versions previously reported diff --git a/tests/snapshots/solver__unsat_constrains_2.snap b/tests/snapshots/solver__unsat_constrains_2.snap index e22cd46..75946cf 100644 --- a/tests/snapshots/solver__unsat_constrains_2.snap +++ b/tests/snapshots/solver__unsat_constrains_2.snap @@ -3,15 +3,15 @@ source: tests/solver.rs expression: error --- The following packages are incompatible -|-- a * cannot be installed because there are no viable options: - |-- a >=1, <=2 would require - |-- b *, which cannot be installed because there are no viable options: - |-- b 2 would require - |-- c >=2, <3, which cannot be installed because there are no viable options: - |-- c 2 would constrain - |-- a >=3, <4 , which conflicts with any installable versions previously reported - |-- b 1 would require - |-- c >=1, <2, which cannot be installed because there are no viable options: - |-- c 1 would constrain - |-- a >=3, <4 , which conflicts with any installable versions previously reported +└─ a * cannot be installed because there are no viable options: + └─ a >=1, <=2 would require + └─ b *, which cannot be installed because there are no viable options: + ├─ b 2 would require + │ └─ c >=2, <3, which cannot be installed because there are no viable options: + │ └─ c 2 would constrain + │ └─ a >=3, <4 , which conflicts with any installable versions previously reported + └─ b 1 would require + └─ c >=1, <2, which cannot be installed because there are no viable options: + └─ c 1 would constrain + └─ a >=3, <4 , which conflicts with any installable versions previously reported diff --git a/tests/snapshots/solver__unsat_incompatible_root_requirements.snap b/tests/snapshots/solver__unsat_incompatible_root_requirements.snap index f8ba82a..f1605c1 100644 --- a/tests/snapshots/solver__unsat_incompatible_root_requirements.snap +++ b/tests/snapshots/solver__unsat_incompatible_root_requirements.snap @@ -1,11 +1,10 @@ --- source: tests/solver.rs -assertion_line: 612 expression: error --- The following packages are incompatible -|-- a >=5, <10 can be installed with any of the following options: - |-- a 5 -|-- a >=0, <4 cannot be installed because there are no viable options: - |-- a 2, which conflicts with the versions reported above. +├─ a >=5, <10 can be installed with any of the following options: +│ └─ a 5 +└─ a >=0, <4 cannot be installed because there are no viable options: + └─ a 2, which conflicts with the versions reported above. diff --git a/tests/snapshots/solver__unsat_locked_and_excluded.snap b/tests/snapshots/solver__unsat_locked_and_excluded.snap index c76d1fc..425e4ac 100644 --- a/tests/snapshots/solver__unsat_locked_and_excluded.snap +++ b/tests/snapshots/solver__unsat_locked_and_excluded.snap @@ -1,12 +1,11 @@ --- source: tests/solver.rs -assertion_line: 557 -expression: error +expression: "solve_snapshot(provider, &[\"asdf\"])" --- The following packages are incompatible -|-- asdf * can be installed with any of the following options: - |-- asdf 1 would require - |-- c >=2, <3, which can be installed with any of the following options: - |-- c 2 -|-- c 1 is locked, but another version is required as reported above +└─ asdf * can be installed with any of the following options: + └─ asdf 1 would require + └─ c >=2, <3, which can be installed with any of the following options: + └─ c 2 +└─ c 1 is locked, but another version is required as reported above diff --git a/tests/snapshots/solver__unsat_no_candidates_for_child_1.snap b/tests/snapshots/solver__unsat_no_candidates_for_child_1.snap index 8ee69ff..795627a 100644 --- a/tests/snapshots/solver__unsat_no_candidates_for_child_1.snap +++ b/tests/snapshots/solver__unsat_no_candidates_for_child_1.snap @@ -1,9 +1,8 @@ --- source: tests/solver.rs -assertion_line: 565 expression: error --- asdf * cannot be installed because there are no viable options: -|-- asdf 1 would require - |-- c >=2, <3, for which no candidates were found. +└─ asdf 1 would require + └─ c >=2, <3, for which no candidates were found. diff --git a/tests/snapshots/solver__unsat_no_candidates_for_child_2.snap b/tests/snapshots/solver__unsat_no_candidates_for_child_2.snap index ac34a46..60a1990 100644 --- a/tests/snapshots/solver__unsat_no_candidates_for_child_2.snap +++ b/tests/snapshots/solver__unsat_no_candidates_for_child_2.snap @@ -1,9 +1,8 @@ --- source: tests/solver.rs -assertion_line: 573 expression: error --- a >=0, <1000 cannot be installed because there are no viable options: -|-- a 41 would require - |-- B >=0, <20, for which no candidates were found. +└─ a 41 would require + └─ B >=0, <20, for which no candidates were found. diff --git a/tests/snapshots/solver__unsat_pubgrub_article.snap b/tests/snapshots/solver__unsat_pubgrub_article.snap index fe4ad65..f6da9f8 100644 --- a/tests/snapshots/solver__unsat_pubgrub_article.snap +++ b/tests/snapshots/solver__unsat_pubgrub_article.snap @@ -1,17 +1,16 @@ --- source: tests/solver.rs -assertion_line: 655 expression: error --- The following packages are incompatible -|-- menu * can be installed with any of the following options: - |-- menu 10 would require - |-- dropdown >=1, <2, which can be installed with any of the following options: - |-- dropdown 1 would require - |-- intl >=3, <4, which can be installed with any of the following options: - |-- intl 3 -|-- icons >=1, <2 can be installed with any of the following options: - |-- icons 1 -|-- intl >=5, <6 cannot be installed because there are no viable options: - |-- intl 5, which conflicts with the versions reported above. +├─ menu * can be installed with any of the following options: +│ └─ menu 10 would require +│ └─ dropdown >=1, <2, which can be installed with any of the following options: +│ └─ dropdown 1 would require +│ └─ intl >=3, <4, which can be installed with any of the following options: +│ └─ intl 3 +├─ icons >=1, <2 can be installed with any of the following options: +│ └─ icons 1 +└─ intl >=5, <6 cannot be installed because there are no viable options: + └─ intl 5, which conflicts with the versions reported above.