From a5b0c1612815edcdb1112b178b296b6d11f39329 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Tue, 24 Sep 2024 16:08:44 -0400 Subject: [PATCH 1/8] creating packageGraph resolver --- crates/turborepo-lib/src/query/mod.rs | 8 ++++ .../turborepo-lib/src/query/package_graph.rs | 48 +++++++++++++++++++ .../src/package_graph/mod.rs | 13 +++++ 3 files changed, 69 insertions(+) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index 037470493388c..92866c3877792 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -2,6 +2,7 @@ mod boundaries; mod external_package; mod file; mod package; +mod package_graph; mod server; mod task; @@ -15,6 +16,7 @@ use async_graphql::{http::GraphiQLSource, *}; use axum::{response, response::IntoResponse}; use external_package::ExternalPackage; use package::Package; +use package_graph::{Edge, Node, PackageGraph}; pub use server::run_server; use thiserror::Error; use tokio::select; @@ -153,6 +155,8 @@ impl RepositoryQuery { #[graphql(concrete(name = "Files", params(File)))] #[graphql(concrete(name = "ExternalPackages", params(ExternalPackage)))] #[graphql(concrete(name = "Diagnostics", params(Diagnostic)))] +#[graphql(concrete(name = "Nodes", params(Node)))] +#[graphql(concrete(name = "Edges", params(Edge)))] pub struct Array { items: Vec, length: usize, @@ -571,6 +575,10 @@ impl RepositoryQuery { } } + async fn package_graph(&self) -> PackageGraph { + PackageGraph::new(self.run.clone()) + } + async fn file(&self, path: String) -> Result { let abs_path = AbsoluteSystemPathBuf::from_unknown(self.run.repo_root(), path); diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index 8b137891791fe..09c261076b9a2 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -1 +1,49 @@ +use std::sync::Arc; +use async_graphql::{Object, SimpleObject}; + +use crate::{query::Array, run::Run}; + +pub struct PackageGraph { + run: Arc, +} + +impl PackageGraph { + pub fn new(run: Arc) -> Self { + Self { run } + } +} + +#[derive(Debug, Clone, SimpleObject)] +pub(crate) struct Node { + idx: usize, +} + +#[derive(Debug, Clone, SimpleObject)] +pub(crate) struct Edge { + source: usize, + target: usize, +} + +#[Object] +impl PackageGraph { + async fn nodes(&self) -> Array { + self.run + .pkg_dep_graph() + .node_indices() + .map(|idx| Node { idx: idx.index() }) + .collect() + } + + async fn edges(&self) -> Array { + self.run + .pkg_dep_graph() + .edges() + .iter() + .map(|edge| Edge { + source: edge.source().index(), + target: edge.target().index(), + }) + .collect() + } +} diff --git a/crates/turborepo-repository/src/package_graph/mod.rs b/crates/turborepo-repository/src/package_graph/mod.rs index aae4acd04e514..79e6415de1dd4 100644 --- a/crates/turborepo-repository/src/package_graph/mod.rs +++ b/crates/turborepo-repository/src/package_graph/mod.rs @@ -4,6 +4,11 @@ use std::{ }; use itertools::Itertools; + +use petgraph::{ + graph::{Edge, NodeIndex}, + visit::{depth_first_search, Reversed}, +}; use serde::Serialize; use tracing::debug; use turbopath::{ @@ -219,6 +224,14 @@ impl PackageGraph { self.packages.get(package) } + pub fn node_indices(&self) -> impl Iterator { + self.graph.node_indices() + } + + pub fn edges(&self) -> &[Edge<()>] { + self.graph.raw_edges() + } + pub fn packages(&self) -> impl Iterator { self.packages.iter() } From 403d1ee1b6abd67b7cb884bc85ed0b09f0563bf4 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 30 Sep 2024 14:38:40 -0400 Subject: [PATCH 2/8] Adding filters for graph view --- Cargo.lock | 6 +- Cargo.toml | 2 +- crates/turborepo-lib/src/query/mod.rs | 4 +- .../turborepo-lib/src/query/package_graph.rs | 71 ++++++++++++++++--- .../src/package_graph/mod.rs | 8 +++ 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2369ff25141b8..8048a3b173f92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3819,12 +3819,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap 2.2.6", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c8dfd610286f6..b82a1ee342023 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,7 +127,7 @@ oxc_resolver = { version = "2.1.0" } parking_lot = "0.12.1" path-clean = "1.0.1" pathdiff = "0.2.1" -petgraph = "0.6.3" +petgraph = "0.6.5" pin-project-lite = "0.2.9" port_scanner = "0.1.5" predicates = "2.1.5" diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index 92866c3877792..a783ee8afd43e 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -575,8 +575,8 @@ impl RepositoryQuery { } } - async fn package_graph(&self) -> PackageGraph { - PackageGraph::new(self.run.clone()) + async fn package_graph(&self, center: String) -> PackageGraph { + PackageGraph::new(self.run.clone(), center) } async fn file(&self, path: String) -> Result { diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index 09c261076b9a2..3370be127a6fe 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -1,22 +1,42 @@ use std::sync::Arc; use async_graphql::{Object, SimpleObject}; +use petgraph::graph::NodeIndex; +use turborepo_repository::package_graph::{PackageName, PackageNode}; use crate::{query::Array, run::Run}; pub struct PackageGraph { run: Arc, + center: PackageNode, } impl PackageGraph { - pub fn new(run: Arc) -> Self { - Self { run } + pub fn new(run: Arc, center: String) -> Self { + let center = PackageNode::Workspace(PackageName::from(center)); + + Self { run, center } } } -#[derive(Debug, Clone, SimpleObject)] +#[derive(Clone)] pub(crate) struct Node { - idx: usize, + idx: NodeIndex, + run: Arc, +} + +#[Object] +impl Node { + async fn name(&self) -> Option { + self.run + .pkg_dep_graph() + .get_package_by_index(self.idx) + .map(|pkg| pkg.to_string()) + } + + async fn idx(&self) -> usize { + self.idx.index() + } } #[derive(Debug, Clone, SimpleObject)] @@ -28,21 +48,56 @@ pub(crate) struct Edge { #[Object] impl PackageGraph { async fn nodes(&self) -> Array { + let transitive_closure = self + .run + .pkg_dep_graph() + .transitive_closure(Some(&self.center)); self.run .pkg_dep_graph() .node_indices() - .map(|idx| Node { idx: idx.index() }) + .filter_map(|idx| { + let package_node = self.run.pkg_dep_graph().get_package_by_index(idx)?; + if !transitive_closure.contains(package_node) { + return None; + } + + Some(Node { + idx: idx, + run: self.run.clone(), + }) + }) .collect() } async fn edges(&self) -> Array { + let transitive_closure = self + .run + .pkg_dep_graph() + .transitive_closure(Some(&self.center)); self.run .pkg_dep_graph() .edges() .iter() - .map(|edge| Edge { - source: edge.source().index(), - target: edge.target().index(), + .filter_map(|edge| { + let source_node = self + .run + .pkg_dep_graph() + .get_package_by_index(edge.source())?; + let target_node = self + .run + .pkg_dep_graph() + .get_package_by_index(edge.target())?; + + if !transitive_closure.contains(source_node) + || !transitive_closure.contains(target_node) + { + return None; + } + + Some(Edge { + source: edge.source().index(), + target: edge.target().index(), + }) }) .collect() } diff --git a/crates/turborepo-repository/src/package_graph/mod.rs b/crates/turborepo-repository/src/package_graph/mod.rs index 79e6415de1dd4..d7125b6f00eea 100644 --- a/crates/turborepo-repository/src/package_graph/mod.rs +++ b/crates/turborepo-repository/src/package_graph/mod.rs @@ -224,6 +224,10 @@ impl PackageGraph { self.packages.get(package) } + pub fn get_package_by_index(&self, index: NodeIndex) -> Option<&PackageNode> { + self.graph.node_weight(index) + } + pub fn node_indices(&self) -> impl Iterator { self.graph.node_indices() } @@ -236,6 +240,10 @@ impl PackageGraph { self.packages.iter() } + pub fn get_page_rank(&self) -> Vec { + petgraph::algo::page_rank::page_rank(&self.graph, 0.85, 1) + } + pub fn root_package_json(&self) -> &PackageJson { self.package_json(&PackageName::Root) .expect("package graph was built without root package.json") From 1714d290d36e75b79637d88b3c3978e408c5ab95 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 30 Sep 2024 15:13:45 -0400 Subject: [PATCH 3/8] Remove Node type, add filters --- crates/turborepo-lib/src/query/mod.rs | 8 +- .../turborepo-lib/src/query/package_graph.rs | 89 ++++++++++--------- 2 files changed, 55 insertions(+), 42 deletions(-) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index a783ee8afd43e..4f41709984a3a 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -575,8 +575,12 @@ impl RepositoryQuery { } } - async fn package_graph(&self, center: String) -> PackageGraph { - PackageGraph::new(self.run.clone(), center) + async fn package_graph( + &self, + center: Option, + filter: Option, + ) -> PackageGraph { + PackageGraph::new(self.run.clone(), center, filter) } async fn file(&self, path: String) -> Result { diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index 3370be127a6fe..c11d4be184436 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -1,21 +1,30 @@ use std::sync::Arc; use async_graphql::{Object, SimpleObject}; +use itertools::Itertools; use petgraph::graph::NodeIndex; use turborepo_repository::package_graph::{PackageName, PackageNode}; -use crate::{query::Array, run::Run}; +use crate::{ + query::{package::Package, Array, PackagePredicate}, + run::Run, +}; pub struct PackageGraph { run: Arc, - center: PackageNode, + center: Option, + filter: Option, } impl PackageGraph { - pub fn new(run: Arc, center: String) -> Self { - let center = PackageNode::Workspace(PackageName::from(center)); + pub fn new(run: Arc, center: Option, filter: Option) -> Self { + let center = center.map(|center| PackageNode::Workspace(PackageName::from(center))); - Self { run, center } + Self { + run, + center, + filter, + } } } @@ -25,60 +34,59 @@ pub(crate) struct Node { run: Arc, } -#[Object] -impl Node { - async fn name(&self) -> Option { - self.run - .pkg_dep_graph() - .get_package_by_index(self.idx) - .map(|pkg| pkg.to_string()) - } - - async fn idx(&self) -> usize { - self.idx.index() - } -} - -#[derive(Debug, Clone, SimpleObject)] +#[derive(Debug, Clone, SimpleObject, Hash, PartialEq, Eq)] pub(crate) struct Edge { - source: usize, - target: usize, + source: String, + target: String, } #[Object] impl PackageGraph { - async fn nodes(&self) -> Array { + async fn nodes(&self) -> Array { let transitive_closure = self - .run - .pkg_dep_graph() - .transitive_closure(Some(&self.center)); + .center + .as_ref() + .map(|center| self.run.pkg_dep_graph().transitive_closure(Some(center))); self.run .pkg_dep_graph() .node_indices() .filter_map(|idx| { let package_node = self.run.pkg_dep_graph().get_package_by_index(idx)?; - if !transitive_closure.contains(package_node) { - return None; + if let Some(closure) = transitive_closure.as_ref() { + if !closure.contains(package_node) { + return None; + } } - Some(Node { - idx: idx, + let package = Package { run: self.run.clone(), - }) + name: package_node.as_package_name().clone(), + }; + + if let Some(filter) = &self.filter { + if !filter.check(&package) { + return None; + } + } + + Some(package) }) .collect() } async fn edges(&self) -> Array { let transitive_closure = self - .run - .pkg_dep_graph() - .transitive_closure(Some(&self.center)); + .center + .as_ref() + .map(|center| self.run.pkg_dep_graph().transitive_closure(Some(center))); self.run .pkg_dep_graph() .edges() .iter() .filter_map(|edge| { + if edge.source() == edge.target() { + return None; + } let source_node = self .run .pkg_dep_graph() @@ -88,17 +96,18 @@ impl PackageGraph { .pkg_dep_graph() .get_package_by_index(edge.target())?; - if !transitive_closure.contains(source_node) - || !transitive_closure.contains(target_node) - { - return None; + if let Some(closure) = transitive_closure.as_ref() { + if !closure.contains(source_node) || !closure.contains(target_node) { + return None; + } } Some(Edge { - source: edge.source().index(), - target: edge.target().index(), + source: source_node.as_package_name().to_string(), + target: target_node.as_package_name().to_string(), }) }) + .dedup() .collect() } } From ebc1b6c4bb33ca53ac95083850b9ac82edd73134 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 30 Sep 2024 15:55:26 -0400 Subject: [PATCH 4/8] Remove Root packages from graph --- crates/turborepo-lib/src/query/package_graph.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index c11d4be184436..be6e646d63647 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -52,6 +52,11 @@ impl PackageGraph { .node_indices() .filter_map(|idx| { let package_node = self.run.pkg_dep_graph().get_package_by_index(idx)?; + if matches!(package_node, PackageNode::Root) + || matches!(package_node, PackageNode::Workspace(PackageName::Root)) + { + return None; + } if let Some(closure) = transitive_closure.as_ref() { if !closure.contains(package_node) { return None; @@ -96,6 +101,16 @@ impl PackageGraph { .pkg_dep_graph() .get_package_by_index(edge.target())?; + if matches!( + source_node, + PackageNode::Root | PackageNode::Workspace(PackageName::Root) + ) || matches!( + target_node, + PackageNode::Root | PackageNode::Workspace(PackageName::Root) + ) { + return None; + } + if let Some(closure) = transitive_closure.as_ref() { if !closure.contains(source_node) || !closure.contains(target_node) { return None; From 2b951417146616998d6e974eb354c5851ed4669f Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 30 Sep 2024 16:29:40 -0400 Subject: [PATCH 5/8] Trying some filters and cleaning --- .../turborepo-lib/src/query/package_graph.rs | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index be6e646d63647..27f81d9180b4d 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -43,22 +43,31 @@ pub(crate) struct Edge { #[Object] impl PackageGraph { async fn nodes(&self) -> Array { - let transitive_closure = self + let direct_dependencies = self .center .as_ref() - .map(|center| self.run.pkg_dep_graph().transitive_closure(Some(center))); + .and_then(|center| self.run.pkg_dep_graph().immediate_dependencies(center)); self.run .pkg_dep_graph() .node_indices() .filter_map(|idx| { let package_node = self.run.pkg_dep_graph().get_package_by_index(idx)?; + if let Some(center) = &self.center { + if center == package_node { + return Some(Package { + run: self.run.clone(), + name: package_node.as_package_name().clone(), + }); + } + } + if matches!(package_node, PackageNode::Root) || matches!(package_node, PackageNode::Workspace(PackageName::Root)) { return None; } - if let Some(closure) = transitive_closure.as_ref() { - if !closure.contains(package_node) { + if let Some(dependencies) = direct_dependencies.as_ref() { + if !dependencies.contains(package_node) { return None; } } @@ -80,10 +89,10 @@ impl PackageGraph { } async fn edges(&self) -> Array { - let transitive_closure = self + let direct_dependencies = self .center .as_ref() - .map(|center| self.run.pkg_dep_graph().transitive_closure(Some(center))); + .and_then(|center| self.run.pkg_dep_graph().immediate_dependencies(center)); self.run .pkg_dep_graph() .edges() @@ -111,8 +120,16 @@ impl PackageGraph { return None; } - if let Some(closure) = transitive_closure.as_ref() { - if !closure.contains(source_node) || !closure.contains(target_node) { + if let Some(center) = &self.center { + if center == source_node || center == target_node { + return Some(Edge { + source: source_node.as_package_name().to_string(), + target: target_node.as_package_name().to_string(), + }); + } + } + if let Some(dependencies) = direct_dependencies.as_ref() { + if !dependencies.contains(source_node) || !dependencies.contains(target_node) { return None; } } From b0ce051d579408e7972c8542013a6a2237de3f01 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 3 Feb 2025 17:00:32 -0500 Subject: [PATCH 6/8] Fixing up PR --- crates/turborepo-lib/src/query/mod.rs | 3 +- .../turborepo-lib/src/query/package_graph.rs | 28 +++++++++++-------- .../src/package_graph/mod.rs | 6 +--- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index 4f41709984a3a..34bdf06103037 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -16,7 +16,7 @@ use async_graphql::{http::GraphiQLSource, *}; use axum::{response, response::IntoResponse}; use external_package::ExternalPackage; use package::Package; -use package_graph::{Edge, Node, PackageGraph}; +use package_graph::{Edge, PackageGraph}; pub use server::run_server; use thiserror::Error; use tokio::select; @@ -155,7 +155,6 @@ impl RepositoryQuery { #[graphql(concrete(name = "Files", params(File)))] #[graphql(concrete(name = "ExternalPackages", params(ExternalPackage)))] #[graphql(concrete(name = "Diagnostics", params(Diagnostic)))] -#[graphql(concrete(name = "Nodes", params(Node)))] #[graphql(concrete(name = "Edges", params(Edge)))] pub struct Array { items: Vec, diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index 27f81d9180b4d..f783e84f03f96 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -6,7 +6,7 @@ use petgraph::graph::NodeIndex; use turborepo_repository::package_graph::{PackageName, PackageNode}; use crate::{ - query::{package::Package, Array, PackagePredicate}, + query::{package::Package, Array, Error, PackagePredicate}, run::Run, }; @@ -42,11 +42,12 @@ pub(crate) struct Edge { #[Object] impl PackageGraph { - async fn nodes(&self) -> Array { + async fn nodes(&self) -> Result, Error> { let direct_dependencies = self .center .as_ref() .and_then(|center| self.run.pkg_dep_graph().immediate_dependencies(center)); + self.run .pkg_dep_graph() .node_indices() @@ -54,10 +55,10 @@ impl PackageGraph { let package_node = self.run.pkg_dep_graph().get_package_by_index(idx)?; if let Some(center) = &self.center { if center == package_node { - return Some(Package { - run: self.run.clone(), - name: package_node.as_package_name().clone(), - }); + return Some(Package::new( + self.run.clone(), + package_node.as_package_name().clone(), + )); } } @@ -72,10 +73,13 @@ impl PackageGraph { } } - let package = Package { - run: self.run.clone(), - name: package_node.as_package_name().clone(), - }; + let package = + match Package::new(self.run.clone(), package_node.as_package_name().clone()) { + Ok(package) => package, + Err(err) => { + return Some(Err(err.into())); + } + }; if let Some(filter) = &self.filter { if !filter.check(&package) { @@ -83,9 +87,9 @@ impl PackageGraph { } } - Some(package) + Some(Ok(package)) }) - .collect() + .collect::, _>>() } async fn edges(&self) -> Array { diff --git a/crates/turborepo-repository/src/package_graph/mod.rs b/crates/turborepo-repository/src/package_graph/mod.rs index d7125b6f00eea..446332aef78dc 100644 --- a/crates/turborepo-repository/src/package_graph/mod.rs +++ b/crates/turborepo-repository/src/package_graph/mod.rs @@ -4,11 +4,7 @@ use std::{ }; use itertools::Itertools; - -use petgraph::{ - graph::{Edge, NodeIndex}, - visit::{depth_first_search, Reversed}, -}; +use petgraph::graph::{Edge, NodeIndex}; use serde::Serialize; use tracing::debug; use turbopath::{ From b02f271ebdd213366df77a649ce80456b7a4114e Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 3 Feb 2025 17:03:19 -0500 Subject: [PATCH 7/8] Add test for package graph --- crates/turborepo/tests/query.rs | 1 + ...norepo_get_package_graph_(npm@10.5.0).snap | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap diff --git a/crates/turborepo/tests/query.rs b/crates/turborepo/tests/query.rs index 4bc695744e6df..baa96f068170b 100644 --- a/crates/turborepo/tests/query.rs +++ b/crates/turborepo/tests/query.rs @@ -9,6 +9,7 @@ fn test_query() -> Result<(), anyhow::Error> { "get package that doesn't exist" => "query { package(name: \"doesnotexist\") { path } }", "get packages with less than 1 dependents" => "query { packages(filter: {lessThan: {field: DIRECT_DEPENDENT_COUNT, value: 1}}) { items { name directDependents { length } } } }", "get packages with more than 0 dependents" => "query { packages(filter: {greaterThan: {field: DIRECT_DEPENDENT_COUNT, value: 0}}) { items { name directDependents { length } } } }", + "get package graph" => "query { packageGraph { nodes { items { name } } edges { items { source target } } } }", ); Ok(()) diff --git a/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap b/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap new file mode 100644 index 0000000000000..1be9dc271f251 --- /dev/null +++ b/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap @@ -0,0 +1,31 @@ +--- +source: crates/turborepo/tests/query.rs +expression: query_output +--- +{ + "data": { + "packageGraph": { + "nodes": { + "items": [ + { + "name": "my-app" + }, + { + "name": "another" + }, + { + "name": "util" + } + ] + }, + "edges": { + "items": [ + { + "source": "my-app", + "target": "util" + } + ] + } + } + } +} From 6b291a3247ceb6e6a858cec05e49524d86799b18 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Wed, 5 Feb 2025 11:17:48 -0500 Subject: [PATCH 8/8] Fix CI --- crates/turborepo-lib/src/query/package_graph.rs | 11 ++++++++--- ...basic_monorepo_get_package_graph_(npm@10.5.0).snap | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/turborepo-lib/src/query/package_graph.rs b/crates/turborepo-lib/src/query/package_graph.rs index f783e84f03f96..b1526a945f1b2 100644 --- a/crates/turborepo-lib/src/query/package_graph.rs +++ b/crates/turborepo-lib/src/query/package_graph.rs @@ -48,7 +48,8 @@ impl PackageGraph { .as_ref() .and_then(|center| self.run.pkg_dep_graph().immediate_dependencies(center)); - self.run + let mut nodes = self + .run .pkg_dep_graph() .node_indices() .filter_map(|idx| { @@ -77,7 +78,7 @@ impl PackageGraph { match Package::new(self.run.clone(), package_node.as_package_name().clone()) { Ok(package) => package, Err(err) => { - return Some(Err(err.into())); + return Some(Err(err)); } }; @@ -89,7 +90,11 @@ impl PackageGraph { Some(Ok(package)) }) - .collect::, _>>() + .collect::, _>>()?; + + nodes.sort_by(|a, b| a.get_name().cmp(b.get_name())); + + Ok(nodes) } async fn edges(&self) -> Array { diff --git a/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap b/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap index 1be9dc271f251..f8b234e7247e8 100644 --- a/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap +++ b/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_graph_(npm@10.5.0).snap @@ -8,10 +8,10 @@ expression: query_output "nodes": { "items": [ { - "name": "my-app" + "name": "another" }, { - "name": "another" + "name": "my-app" }, { "name": "util"