Skip to content

Commit

Permalink
Adding filter for packages by task
Browse files Browse the repository at this point in the history
  • Loading branch information
NicholasLYang committed Sep 26, 2024
1 parent 6d4e655 commit 57b9372
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
15 changes: 15 additions & 0 deletions crates/turborepo-lib/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl<T: OutputType> FromIterator<T> for Array<T> {
#[derive(Enum, Copy, Clone, Eq, PartialEq, Debug)]
enum PackageFields {
Name,
TaskName,
DirectDependencyCount,
DirectDependentCount,
IndirectDependentCount,
Expand Down Expand Up @@ -96,6 +97,7 @@ struct PackagePredicate {
greater_than: Option<FieldValuePair>,
less_than: Option<FieldValuePair>,
not: Option<Box<PackagePredicate>>,
has: Option<FieldValuePair>,
}

impl PackagePredicate {
Expand Down Expand Up @@ -226,6 +228,14 @@ 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::TaskName, Value::String(name)) => pkg.task_names().contains(name),
_ => false,
}
}

fn check(&self, pkg: &Package) -> bool {
let and = self
.and
Expand Down Expand Up @@ -254,6 +264,10 @@ impl PackagePredicate {
.as_ref()
.map(|pair| Self::check_greater_than(pkg, &pair.field, &pair.value));
let not = self.not.as_ref().map(|predicate| !predicate.check(pkg));
let has = self
.has
.as_ref()
.map(|pair| Self::check_has(pkg, &pair.field, &pair.value));

and.into_iter()
.chain(or)
Expand All @@ -262,6 +276,7 @@ impl PackagePredicate {
.chain(greater_than)
.chain(less_than)
.chain(not)
.chain(has)
.all(|p| p)
}
}
Expand Down
10 changes: 9 additions & 1 deletion crates/turborepo-lib/src/query/package.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::Arc;
use std::{collections::HashSet, sync::Arc};

use async_graphql::Object;
use itertools::Itertools;
Expand All @@ -15,6 +15,14 @@ pub struct Package {
}

impl Package {
pub fn task_names(&self) -> HashSet<String> {
self.run
.pkg_dep_graph()
.package_json(&self.name)
.map(|json| json.scripts.keys().cloned().collect())
.unwrap_or_default()
}

pub fn direct_dependents_count(&self) -> usize {
self.run
.pkg_dep_graph()
Expand Down
36 changes: 36 additions & 0 deletions turborepo-tests/integration/tests/command-query.t
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,42 @@ Query packages that have at least one dependent package
}
}
Query packages that have a task named `build`
$ ${TURBO} query "query { packages(filter: { has: { field: TASK_NAME, value: \"build\" } }) { items { name } } }" | jq
WARNING query command is experimental and may change in the future
{
"data": {
"packages": {
"items": [
{
"name": "my-app"
},
{
"name": "util"
}
]
}
}
}
Query packages that have a task named `build` or `dev`
$ ${TURBO} query "query { packages(filter: { or: [{ has: { field: TASK_NAME, value: \"build\" } }, { has: { field: TASK_NAME, value: \"dev\" } }] }) { items { name } } }" | jq
WARNING query command is experimental and may change in the future
{
"data": {
"packages": {
"items": [
{
"name": "my-app"
},
{
"name": "util"
}
]
}
}
}
Get dependents of `util`
$ ${TURBO} query "query { packages(filter: { equal: { field: NAME, value: \"util\" } }) { items { directDependents { items { name } } } } }" | jq
WARNING query command is experimental and may change in the future
Expand Down

0 comments on commit 57b9372

Please sign in to comment.