diff --git a/nextgen/action-graph/src/action_graph.rs b/nextgen/action-graph/src/action_graph.rs index 9fc70e3a77c..7cb832ab873 100644 --- a/nextgen/action-graph/src/action_graph.rs +++ b/nextgen/action-graph/src/action_graph.rs @@ -30,7 +30,7 @@ impl ActionGraph { } pub fn reset_iterator(&mut self) -> miette::Result<()> { - // self.detect_cycle()?; + self.detect_cycle()?; self.queue.clear(); self.visited.clear(); @@ -104,27 +104,18 @@ impl ActionGraph { } fn detect_cycle(&self) -> miette::Result<()> { - if self.is_empty() || self.get_node_count() == 1 { - return Ok(()); + if self.get_node_count() > 1 { + if let Err(cycle) = petgraph::algo::toposort(&self.graph, None) { + return Err(ActionGraphError::CycleDetected( + self.get_node_from_index(&cycle.node_id()) + .map(|n| n.label()) + .unwrap_or_else(|| "(unknown)".into()), + ) + .into()); + } } - let scc = petgraph::algo::kosaraju_scc(&self.graph); - - // TODO - dbg!(&scc); - - // The cycle is always the last sequence in the list - let Some(cycle) = scc.last() else { - return Err(ActionGraphError::CycleDetected("(unknown)".into()).into()); - }; - - let path = cycle - .iter() - .filter_map(|i| self.get_node_from_index(i).map(|n| n.label())) - .collect::>() - .join(" → "); - - Err(ActionGraphError::CycleDetected(path).into()) + Ok(()) } } diff --git a/nextgen/action-graph/tests/action_graph_test.rs b/nextgen/action-graph/tests/action_graph_test.rs index 987bc415fd0..de9a843f356 100644 --- a/nextgen/action-graph/tests/action_graph_test.rs +++ b/nextgen/action-graph/tests/action_graph_test.rs @@ -174,6 +174,31 @@ fn topo(mut graph: ActionGraph) -> Vec { mod action_graph { use super::*; + // #[test] + // fn errors_on_cycle() { + // let mut graph = ProjectGraphType::new(); + // let a = graph.add_node(create_project("a")); + // let b = graph.add_node(create_project("b")); + // graph.add_edge(a, b, DependencyScope::Build); + // graph.add_edge(b, a, DependencyScope::Build); + + // let pg = ProjectGraph::new( + // graph, + // FxHashMap::from_iter([ + // ("a".into(), ProjectNode::new(0)), + // ("b".into(), ProjectNode::new(1)), + // ]), + // &PathBuf::from("."), + // ); + + // let mut builder = ActionGraphBuilder::new(&pg).unwrap(); + + // builder.sync_project(&pg.get("a").unwrap()).unwrap(); + // builder.sync_project(&pg.get("b").unwrap()).unwrap(); + + // builder.build().unwrap().reset_iterator().unwrap(); + // } + mod install_deps { use super::*; diff --git a/nextgen/project-graph/src/project_graph.rs b/nextgen/project-graph/src/project_graph.rs index 012de71483a..38b15e90294 100644 --- a/nextgen/project-graph/src/project_graph.rs +++ b/nextgen/project-graph/src/project_graph.rs @@ -34,6 +34,15 @@ pub struct ProjectNode { pub source: WorkspaceRelativePathBuf, } +impl ProjectNode { + pub fn new(index: usize) -> Self { + ProjectNode { + index: NodeIndex::new(index), + ..ProjectNode::default() + } + } +} + #[derive(Default)] pub struct ProjectGraph { pub check_boundaries: bool,