From c9bc923c63ce11699e1abdee80f80b2a1c71ade1 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Fri, 1 Nov 2024 12:03:20 -0400 Subject: [PATCH 1/7] Starting refactor to explicit constructors with validation --- crates/turborepo-lib/src/query/mod.rs | 76 ++++++++++++++--------- crates/turborepo-lib/src/query/package.rs | 20 +++++- crates/turborepo-lib/src/query/task.rs | 32 +++++----- 3 files changed, 80 insertions(+), 48 deletions(-) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index b2dd00ce63f00..00b70f433b802 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -3,7 +3,11 @@ mod package; mod server; mod task; -use std::{io, sync::Arc}; +use std::{ + io, + ops::{Deref, DerefMut}, + sync::Arc, +}; use async_graphql::{http::GraphiQLSource, *}; use axum::{response, response::IntoResponse}; @@ -74,6 +78,19 @@ pub struct Array { length: usize, } +impl Deref for Array { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.items + } +} + +impl DerefMut for Array { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.items + } +} + impl FromIterator for Array { fn from_iter>(iter: I) -> Self { let items: Vec<_> = iter.into_iter().collect(); @@ -491,7 +508,7 @@ impl RepositoryQuery { let mut opts = self.run.opts().clone(); opts.scope_opts.affected_range = Some((base, head)); - Ok(RunBuilder::calculate_filtered_packages( + let mut packages = RunBuilder::calculate_filtered_packages( self.run.repo_root(), &opts, self.run.pkg_dep_graph(), @@ -499,24 +516,26 @@ impl RepositoryQuery { self.run.root_turbo_json(), )? .into_iter() - .map(|(package, reason)| ChangedPackage { - package: Package { - run: self.run.clone(), - name: package, - }, - reason: reason.into(), + .map(|(package, reason)| { + Ok(ChangedPackage { + package: Package::new(self.run.clone(), package)?, + reason: reason.into(), + }) }) - .filter(|package| filter.as_ref().map_or(true, |f| f.check(&package.package))) - .sorted_by(|a, b| a.package.name.cmp(&b.package.name)) - .collect()) + .filter(|package| { + let package = package.as_ref()?; + filter.as_ref().map_or(true, |f| f.check(&package.package)) + }) + .collect::, _>>()?; + + packages.sort_by(|a, b| a.package.get_name().cmp(&b.package.get_name())); + Ok(packages) } + /// Gets a single package by name async fn package(&self, name: String) -> Result { let name = PackageName::from(name); - Ok(Package { - run: self.run.clone(), - name, - }) + Package::new(self.run.clone(), name) } async fn version(&self) -> &'static str { @@ -536,29 +555,26 @@ impl RepositoryQuery { /// Gets a list of packages that match the given filter async fn packages(&self, filter: Option) -> Result, Error> { let Some(filter) = filter else { - return Ok(self + let mut packages = self .run .pkg_dep_graph() .packages() - .map(|(name, _)| Package { - run: self.run.clone(), - name: name.clone(), - }) - .sorted_by(|a, b| a.name.cmp(&b.name)) - .collect()); + .map(|(name, _)| Package::new(self.run.clone(), name.clone())) + .collect::, _>>()?; + packages.sort_by(|a, b| a.get_name().cmp(b.get_name())); + return Ok(packages); }; - Ok(self + let mut packages = self .run .pkg_dep_graph() .packages() - .map(|(name, _)| Package { - run: self.run.clone(), - name: name.clone(), - }) - .filter(|pkg| filter.check(pkg)) - .sorted_by(|a, b| a.name.cmp(&b.name)) - .collect()) + .map(|(name, _)| Package::new(self.run.clone(), name.clone())) + .filter(|pkg| pkg.as_ref().map_or(false, |pkg| filter.check(pkg))) + .collect::, _>>()?; + packages.sort_by(|a, b| a.get_name().cmp(b.get_name())); + + Ok(packages) } } diff --git a/crates/turborepo-lib/src/query/package.rs b/crates/turborepo-lib/src/query/package.rs index 621f6385dfbe2..4a642c820feb3 100644 --- a/crates/turborepo-lib/src/query/package.rs +++ b/crates/turborepo-lib/src/query/package.rs @@ -12,11 +12,27 @@ use crate::{ #[derive(Clone)] pub struct Package { - pub run: Arc, - pub name: PackageName, + run: Arc, + name: PackageName, } impl Package { + pub fn new(run: Arc, name: PackageName) -> Result { + run.pkg_dep_graph() + .package_info(&name) + .ok_or_else(|| Error::PackageNotFound(name.clone()))?; + + Ok(Self { run, name }) + } + + pub fn run(&self) -> &Arc { + &self.run + } + + pub fn get_name(&self) -> &PackageName { + &self.name + } + pub fn get_tasks(&self) -> HashMap> { self.run .pkg_dep_graph() diff --git a/crates/turborepo-lib/src/query/task.rs b/crates/turborepo-lib/src/query/task.rs index 5fbe69c7c5219..7313f97349518 100644 --- a/crates/turborepo-lib/src/query/task.rs +++ b/crates/turborepo-lib/src/query/task.rs @@ -43,7 +43,7 @@ impl RepositoryTask { } async fn full_name(&self) -> String { - format!("{}#{}", self.package.name, self.name) + format!("{}#{}", self.package.get_name(), self.name) } async fn script(&self) -> Option { @@ -51,9 +51,9 @@ impl RepositoryTask { } async fn direct_dependents(&self) -> Array { - let task_id = TaskId::from_static(self.package.name.to_string(), self.name.clone()); + let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); self.package - .run + .run() .engine() .dependents(&task_id) .into_iter() @@ -61,12 +61,12 @@ impl RepositoryTask { .filter_map(|task| match task { TaskNode::Root => None, TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run)), + TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run())), }) .sorted_by(|a, b| { a.package - .name - .cmp(&b.package.name) + .get_name() + .cmp(&b.package.get_name()) .then_with(|| a.name.cmp(&b.name)) }) .collect() @@ -116,23 +116,23 @@ impl RepositoryTask { }) .sorted_by(|a, b| { a.package - .name - .cmp(&b.package.name) + .get_name() + .cmp(&b.package.get_name()) .then_with(|| a.name.cmp(&b.name)) }) .collect() } async fn indirect_dependencies(&self) -> Array { - let task_id = TaskId::from_static(self.package.name.to_string(), self.name.clone()); + let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); let direct_dependencies = self .package - .run + .run() .engine() .dependencies(&task_id) .unwrap_or_default(); self.package - .run + .run() .engine() .transitive_dependencies(&task_id) .into_iter() @@ -173,21 +173,21 @@ impl RepositoryTask { } async fn all_dependencies(&self) -> Array { - let task_id = TaskId::from_static(self.package.name.to_string(), self.name.clone()); + let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); self.package - .run + .run() .engine() .transitive_dependencies(&task_id) .into_iter() .filter_map(|node| match node { TaskNode::Root => None, TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run)), + TaskNode::Task(task) => Some(RepositoryTask::new(task, self.package.run())), }) .sorted_by(|a, b| { a.package - .name - .cmp(&b.package.name) + .get_name() + .cmp(&b.package.get_name()) .then_with(|| a.name.cmp(&b.name)) }) .collect() From 35b171b07e00d4799ed3a9e368e0d24150b39bbf Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Fri, 1 Nov 2024 14:14:26 -0400 Subject: [PATCH 2/7] Finish refactoring to use constructor --- crates/turborepo-lib/src/query/mod.rs | 11 +- crates/turborepo-lib/src/query/task.rs | 208 +++++++++++-------------- crates/turborepo/tests/query.rs | 12 ++ 3 files changed, 109 insertions(+), 122 deletions(-) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index 00b70f433b802..940e3f152ee67 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -11,7 +11,6 @@ use std::{ use async_graphql::{http::GraphiQLSource, *}; use axum::{response, response::IntoResponse}; -use itertools::Itertools; use miette::Diagnostic; use package::Package; pub use server::run_server; @@ -137,7 +136,7 @@ struct PackagePredicate { impl PackagePredicate { fn check_equals(pkg: &Package, field: &PackageFields, value: &Any) -> bool { match (field, &value.0) { - (PackageFields::Name, Value::String(name)) => pkg.name.as_ref() == name, + (PackageFields::Name, Value::String(name)) => pkg.get_name().as_ref() == name, (PackageFields::DirectDependencyCount, Value::Number(n)) => { let Some(n) = n.as_u64() else { return false; @@ -264,7 +263,7 @@ impl PackagePredicate { fn check_has(pkg: &Package, field: &PackageFields, value: &Any) -> bool { match (field, &value.0) { - (PackageFields::Name, Value::String(name)) => pkg.name.as_ref() == name, + (PackageFields::Name, Value::String(name)) => pkg.get_name().as_str() == name, (PackageFields::TaskName, Value::String(name)) => pkg.get_tasks().contains_key(name), _ => false, } @@ -522,8 +521,10 @@ impl RepositoryQuery { reason: reason.into(), }) }) - .filter(|package| { - let package = package.as_ref()?; + .filter(|package: &Result| { + let Ok(package) = package.as_ref() else { + return true; + }; filter.as_ref().map_or(true, |f| f.check(&package.package)) }) .collect::, _>>()?; diff --git a/crates/turborepo-lib/src/query/task.rs b/crates/turborepo-lib/src/query/task.rs index 7313f97349518..9b8d8e079f5ae 100644 --- a/crates/turborepo-lib/src/query/task.rs +++ b/crates/turborepo-lib/src/query/task.rs @@ -1,12 +1,11 @@ use std::sync::Arc; use async_graphql::Object; -use itertools::Itertools; use turborepo_errors::Spanned; use crate::{ engine::TaskNode, - query::{package::Package, Array}, + query::{package::Package, Array, Error}, run::{task_id::TaskId, Run}, }; @@ -17,18 +16,37 @@ pub struct RepositoryTask { } impl RepositoryTask { - pub fn new(task_id: &TaskId, run: &Arc) -> Self { - let package = Package { - name: task_id.package().into(), - run: run.clone(), - }; + pub fn new(task_id: &TaskId, run: &Arc) -> Result { + let package = Package::new(run.clone(), task_id.package().into())?; let script = package.get_tasks().get(task_id.task()).cloned(); - RepositoryTask { + Ok(RepositoryTask { name: task_id.task().to_string(), package, script, - } + }) + } + + fn collect_and_sort<'a>( + &self, + task_id: &TaskId<'a>, + tasks: impl IntoIterator, + ) -> Result, Error> { + let mut tasks = tasks + .into_iter() + .filter_map(|task| match task { + TaskNode::Root => None, + TaskNode::Task(task) if task == task_id => None, + TaskNode::Task(task) => Some(RepositoryTask::new(&task, &self.package.run())), + }) + .collect::, _>>()?; + tasks.sort_by(|a, b| { + a.package + .get_name() + .cmp(&b.package.get_name()) + .then_with(|| a.name.cmp(&b.name)) + }); + Ok(tasks) } } @@ -50,80 +68,55 @@ impl RepositoryTask { self.script.as_ref().map(|script| script.value.to_string()) } - async fn direct_dependents(&self) -> Array { + async fn direct_dependents(&self) -> Result, Error> { let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); - self.package - .run() - .engine() - .dependents(&task_id) - .into_iter() - .flatten() - .filter_map(|task| match task { - TaskNode::Root => None, - TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run())), - }) - .sorted_by(|a, b| { - a.package - .get_name() - .cmp(&b.package.get_name()) - .then_with(|| a.name.cmp(&b.name)) - }) - .collect() - } - async fn direct_dependencies(&self) -> Array { - let task_id = TaskId::new(self.package.name.as_ref(), &self.name); + self.collect_and_sort( + &task_id, + self.package + .run() + .engine() + .dependents(&task_id) + .into_iter() + .flatten(), + ) + } - self.package - .run - .engine() - .dependencies(&task_id) - .into_iter() - .flatten() - .filter_map(|task| match task { - TaskNode::Root => None, - TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run)), - }) - .sorted_by(|a, b| { - a.package - .name - .cmp(&b.package.name) - .then_with(|| a.name.cmp(&b.name)) - }) - .collect() + async fn direct_dependencies(&self) -> Result, Error> { + let task_id = TaskId::new(self.package.get_name().as_ref(), &self.name); + + self.collect_and_sort( + &task_id, + self.package + .run() + .engine() + .dependencies(&task_id) + .into_iter() + .flatten(), + ) } - async fn indirect_dependents(&self) -> Array { - let task_id = TaskId::from_static(self.package.name.to_string(), self.name.clone()); + async fn indirect_dependents(&self) -> Result, Error> { + let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); let direct_dependents = self .package - .run + .run() .engine() .dependencies(&task_id) .unwrap_or_default(); - self.package - .run - .engine() - .transitive_dependents(&task_id) - .into_iter() - .filter(|node| !direct_dependents.contains(node)) - .filter_map(|node| match node { - TaskNode::Root => None, - TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run)), - }) - .sorted_by(|a, b| { - a.package - .get_name() - .cmp(&b.package.get_name()) - .then_with(|| a.name.cmp(&b.name)) - }) - .collect() + + self.collect_and_sort( + &task_id, + self.package + .run() + .engine() + .transitive_dependents(&task_id) + .into_iter() + .filter(|node| !direct_dependents.contains(node)), + ) } - async fn indirect_dependencies(&self) -> Array { + async fn indirect_dependencies(&self) -> Result, Error> { let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); let direct_dependencies = self .package @@ -131,7 +124,8 @@ impl RepositoryTask { .engine() .dependencies(&task_id) .unwrap_or_default(); - self.package + let mut dependencies = self + .package .run() .engine() .transitive_dependencies(&task_id) @@ -140,56 +134,36 @@ impl RepositoryTask { .filter_map(|node| match node { TaskNode::Root => None, TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run)), - }) - .sorted_by(|a, b| { - a.package - .name - .cmp(&b.package.name) - .then_with(|| a.name.cmp(&b.name)) + TaskNode::Task(task) => Some(RepositoryTask::new(task, self.package.run())), }) - .collect() + .collect::, _>>()?; + + dependencies.sort_by(|a, b| { + a.package + .get_name() + .cmp(b.package.get_name()) + .then_with(|| a.name.cmp(&b.name)) + }); + + Ok(dependencies) } - async fn all_dependents(&self) -> Array { - let task_id = TaskId::from_static(self.package.name.to_string(), self.name.clone()); - self.package - .run - .engine() - .transitive_dependents(&task_id) - .into_iter() - .filter_map(|node| match node { - TaskNode::Root => None, - TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, &self.package.run)), - }) - .sorted_by(|a, b| { - a.package - .name - .cmp(&b.package.name) - .then_with(|| a.name.cmp(&b.name)) - }) - .collect() + async fn all_dependents(&self) -> Result, Error> { + let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); + self.collect_and_sort( + &task_id, + self.package.run().engine().transitive_dependents(&task_id), + ) } - async fn all_dependencies(&self) -> Array { + async fn all_dependencies(&self) -> Result, Error> { let task_id = TaskId::from_static(self.package.get_name().to_string(), self.name.clone()); - self.package - .run() - .engine() - .transitive_dependencies(&task_id) - .into_iter() - .filter_map(|node| match node { - TaskNode::Root => None, - TaskNode::Task(task) if task == &task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(task, self.package.run())), - }) - .sorted_by(|a, b| { - a.package - .get_name() - .cmp(&b.package.get_name()) - .then_with(|| a.name.cmp(&b.name)) - }) - .collect() + self.collect_and_sort( + &task_id, + self.package + .run() + .engine() + .transitive_dependencies(&task_id), + ) } } diff --git a/crates/turborepo/tests/query.rs b/crates/turborepo/tests/query.rs index 08414593677b1..4ea85f7df220e 100644 --- a/crates/turborepo/tests/query.rs +++ b/crates/turborepo/tests/query.rs @@ -1,5 +1,17 @@ mod common; +#[test] +fn test_query() -> Result<(), anyhow::Error> { + check_json!( + "basic_monorepo", + "npm@10.5.0", + "query", + "get package that doesn't exist" => "query { package(name: \"doesnotexist\") { path } }", + ); + + Ok(()) +} + #[cfg(not(windows))] #[test] fn test_double_symlink() -> Result<(), anyhow::Error> { From 313d838ce4f1cdcdfd58b676be69ced46f9a7def Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Fri, 1 Nov 2024 14:14:39 -0400 Subject: [PATCH 3/7] Fix error printing --- crates/turborepo-lib/src/commands/query.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/turborepo-lib/src/commands/query.rs b/crates/turborepo-lib/src/commands/query.rs index 24fac3e27e66c..44c42057ab69b 100644 --- a/crates/turborepo-lib/src/commands/query.rs +++ b/crates/turborepo-lib/src/commands/query.rs @@ -33,10 +33,10 @@ struct QueryError { impl QueryError { fn get_index_from_row_column(query: &str, row: usize, column: usize) -> usize { let mut index = 0; - for line in query.lines().take(row + 1) { + for line in query.lines().take(row.saturating_sub(1)) { index += line.len() + 1; } - index + column + index + column - 1 } fn new(server_error: ServerError, query: String) -> Self { let span: Option = server_error.locations.first().map(|location| { @@ -109,6 +109,7 @@ pub async fn run( if result.errors.is_empty() { println!("{}", serde_json::to_string_pretty(&result)?); } else { + println!("{}", serde_json::to_string_pretty(&result)?); for error in result.errors { let error = QueryError::new(error, query.clone()); eprintln!("{:?}", Report::new(error)); From dcefb0d687a5cb3448ef2c0f6f03328b082926d4 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Fri, 1 Nov 2024 14:16:24 -0400 Subject: [PATCH 4/7] Update snapshot --- ...ckage_that_doesn't_exist_(npm@10.5.0).snap | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_that_doesn't_exist_(npm@10.5.0).snap diff --git a/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_that_doesn't_exist_(npm@10.5.0).snap b/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_that_doesn't_exist_(npm@10.5.0).snap new file mode 100644 index 0000000000000..b1c34e3924874 --- /dev/null +++ b/crates/turborepo/tests/snapshots/query__basic_monorepo_get_package_that_doesn't_exist_(npm@10.5.0).snap @@ -0,0 +1,21 @@ +--- +source: crates/turborepo/tests/query.rs +expression: query_output +--- +{ + "data": null, + "errors": [ + { + "message": "package not found: doesnotexist", + "locations": [ + { + "line": 1, + "column": 9 + } + ], + "path": [ + "package" + ] + } + ] +} From 08dc6b83a6ab1ce05f138e0975102c6b479a74ce Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Fri, 1 Nov 2024 15:19:36 -0400 Subject: [PATCH 5/7] Fix clippy --- crates/turborepo-lib/src/query/mod.rs | 2 +- crates/turborepo-lib/src/query/task.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index 940e3f152ee67..8e048c5bbca46 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -529,7 +529,7 @@ impl RepositoryQuery { }) .collect::, _>>()?; - packages.sort_by(|a, b| a.package.get_name().cmp(&b.package.get_name())); + packages.sort_by(|a, b| a.package.get_name().cmp(b.package.get_name())); Ok(packages) } diff --git a/crates/turborepo-lib/src/query/task.rs b/crates/turborepo-lib/src/query/task.rs index 9b8d8e079f5ae..72997203071ec 100644 --- a/crates/turborepo-lib/src/query/task.rs +++ b/crates/turborepo-lib/src/query/task.rs @@ -37,13 +37,13 @@ impl RepositoryTask { .filter_map(|task| match task { TaskNode::Root => None, TaskNode::Task(task) if task == task_id => None, - TaskNode::Task(task) => Some(RepositoryTask::new(&task, &self.package.run())), + TaskNode::Task(task) => Some(RepositoryTask::new(task, self.package.run())), }) .collect::, _>>()?; tasks.sort_by(|a, b| { a.package .get_name() - .cmp(&b.package.get_name()) + .cmp(b.package.get_name()) .then_with(|| a.name.cmp(&b.name)) }); Ok(tasks) From f86dce6f073c06512290bae4707d6425b15ad68b Mon Sep 17 00:00:00 2001 From: Nicholas Yang Date: Mon, 4 Nov 2024 10:39:52 -0500 Subject: [PATCH 6/7] Update crates/turborepo-lib/src/commands/query.rs Co-authored-by: Chris Olszewski --- crates/turborepo-lib/src/commands/query.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/turborepo-lib/src/commands/query.rs b/crates/turborepo-lib/src/commands/query.rs index 44c42057ab69b..c3d79df1f9fe0 100644 --- a/crates/turborepo-lib/src/commands/query.rs +++ b/crates/turborepo-lib/src/commands/query.rs @@ -106,10 +106,8 @@ pub async fn run( let request = Request::new(&query).variables(variables); let result = schema.execute(request).await; - if result.errors.is_empty() { - println!("{}", serde_json::to_string_pretty(&result)?); - } else { - println!("{}", serde_json::to_string_pretty(&result)?); + println!("{}", serde_json::to_string_pretty(&result)?); + if !result.errors.is_empty() { for error in result.errors { let error = QueryError::new(error, query.clone()); eprintln!("{:?}", Report::new(error)); From c94cad40e34844879a5ff7656a408d44cab47669 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Mon, 4 Nov 2024 10:46:30 -0500 Subject: [PATCH 7/7] PR feedback --- crates/turborepo-lib/src/query/mod.rs | 2 +- crates/turborepo-lib/src/query/package.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/turborepo-lib/src/query/mod.rs b/crates/turborepo-lib/src/query/mod.rs index 8e048c5bbca46..97e02e5208ee4 100644 --- a/crates/turborepo-lib/src/query/mod.rs +++ b/crates/turborepo-lib/src/query/mod.rs @@ -78,7 +78,7 @@ pub struct Array { } impl Deref for Array { - type Target = Vec; + type Target = [T]; fn deref(&self) -> &Self::Target { &self.items } diff --git a/crates/turborepo-lib/src/query/package.rs b/crates/turborepo-lib/src/query/package.rs index 4a642c820feb3..dc3a3b8d35e89 100644 --- a/crates/turborepo-lib/src/query/package.rs +++ b/crates/turborepo-lib/src/query/package.rs @@ -29,6 +29,8 @@ impl Package { &self.run } + /// This uses a different naming convention because we already have a + /// `name` resolver defined for GraphQL pub fn get_name(&self) -> &PackageName { &self.name }