Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(trace): filtering by import type #9357

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions crates/turbo-trace/src/import_finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ use swc_common::{Span, Spanned};
use swc_ecma_ast::{Decl, ModuleDecl, Stmt};
use swc_ecma_visit::{Visit, VisitWith};

#[derive(Default)]
use crate::tracer::ImportType;

pub struct ImportFinder {
import_type: ImportType,
imports: Vec<(String, Span)>,
}

impl ImportFinder {
pub fn new(import_type: ImportType) -> Self {
Self {
import_type,
imports: Vec::new(),
}
}

pub fn imports(&self) -> &[(String, Span)] {
&self.imports
}
Expand All @@ -16,8 +25,21 @@ impl ImportFinder {
impl Visit for ImportFinder {
fn visit_module_decl(&mut self, decl: &ModuleDecl) {
if let ModuleDecl::Import(import) = decl {
self.imports
.push((import.src.value.to_string(), import.span));
match self.import_type {
ImportType::All => {
self.imports
.push((import.src.value.to_string(), import.span));
}
ImportType::Types if import.type_only => {
self.imports
.push((import.src.value.to_string(), import.span));
}
ImportType::Values if !import.type_only => {
self.imports
.push((import.src.value.to_string(), import.span));
}
_ => {}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/turbo-trace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
mod import_finder;
mod tracer;

pub use tracer::{TraceError, TraceResult, Tracer};
pub use tracer::{ImportType, TraceError, TraceResult, Tracer};
22 changes: 21 additions & 1 deletion crates/turbo-trace/src/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#[derive(Debug, Default)]
pub struct SeenFile {
pub ast: Option<swc_ecma_ast::Module>,

Check warning on line 22 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo rust check

field `ast` is never read

Check warning on line 22 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Rust lints

field `ast` is never read

Check warning on line 22 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on ubuntu

field `ast` is never read

Check warning on line 22 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on macos

field `ast` is never read

Check warning on line 22 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on windows

field `ast` is never read
}

pub struct Tracer {
Expand All @@ -28,6 +28,7 @@
source_map: Arc<SourceMap>,
cwd: AbsoluteSystemPathBuf,
errors: Vec<TraceError>,
import_type: ImportType,
}

#[derive(Debug, Error, Diagnostic)]
Expand Down Expand Up @@ -57,6 +58,17 @@
pub files: HashMap<AbsoluteSystemPathBuf, SeenFile>,
}

/// The type of imports to trace.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ImportType {
/// Trace all imports.
All,
/// Trace only `import type` imports
Types,

Check warning on line 67 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo rust check

variants `Types` and `Values` are never constructed

Check warning on line 67 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Rust lints

variants `Types` and `Values` are never constructed

Check warning on line 67 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on ubuntu

variants `Types` and `Values` are never constructed

Check warning on line 67 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on macos

variants `Types` and `Values` are never constructed

Check warning on line 67 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on windows

variants `Types` and `Values` are never constructed
/// Trace only `import` imports and not `import type` imports
Values,
}

impl Tracer {
pub fn new(
cwd: AbsoluteSystemPathBuf,
Expand All @@ -72,17 +84,23 @@
files,
ts_config,
cwd,
import_type: ImportType::All,
errors: Vec::new(),
source_map: Arc::new(SourceMap::default()),
}
}

pub fn set_import_type(&mut self, import_type: ImportType) {

Check warning on line 93 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo rust check

method `set_import_type` is never used

Check warning on line 93 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Rust lints

method `set_import_type` is never used

Check warning on line 93 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on ubuntu

method `set_import_type` is never used

Check warning on line 93 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on macos

method `set_import_type` is never used

Check warning on line 93 in crates/turbo-trace/src/tracer.rs

View workflow job for this annotation

GitHub Actions / Turborepo Rust testing on windows

method `set_import_type` is never used
self.import_type = import_type;
}

#[tracing::instrument(skip(resolver, source_map))]
pub async fn get_imports_from_file(
source_map: &SourceMap,
errors: &mut Vec<TraceError>,
resolver: &Resolver,
file_path: &AbsoluteSystemPath,
import_type: ImportType,
) -> Option<(Vec<AbsoluteSystemPathBuf>, SeenFile)> {
// Read the file content
let Ok(file_content) = tokio::fs::read_to_string(&file_path).await else {
Expand Down Expand Up @@ -130,7 +148,7 @@
};

// Visit the AST and find imports
let mut finder = ImportFinder::default();
let mut finder = ImportFinder::new(import_type);
module.visit_with(&mut finder);
// Convert found imports/requires to absolute paths and add them to files to
// visit
Expand Down Expand Up @@ -196,6 +214,7 @@
&mut self.errors,
file_resolver.as_ref().unwrap_or(resolver),
&file_path,
self.import_type,
)
.await
else {
Expand Down Expand Up @@ -306,6 +325,7 @@
&mut errors,
file_resolver.as_ref().unwrap_or(&resolver),
&file,
shared_self.import_type,
)
.await
else {
Expand Down
42 changes: 38 additions & 4 deletions crates/turborepo-lib/src/query/file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use async_graphql::{Object, SimpleObject};
use async_graphql::{Enum, Object, SimpleObject};
use camino::Utf8PathBuf;
use itertools::Itertools;
use swc_ecma_ast::EsVersion;
Expand Down Expand Up @@ -146,6 +146,27 @@ impl TraceResult {
}
}

/// The type of imports to trace.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Enum)]
pub enum ImportType {
/// Trace all imports.
All,
/// Trace only `import type` imports
Types,
/// Trace only `import` imports and not `import type` imports
Values,
}

impl From<ImportType> for turbo_trace::ImportType {
fn from(import_type: ImportType) -> Self {
match import_type {
ImportType::All => turbo_trace::ImportType::All,
ImportType::Types => turbo_trace::ImportType::Types,
ImportType::Values => turbo_trace::ImportType::Values,
}
}
}

#[Object]
impl File {
async fn contents(&self) -> Result<String, Error> {
Expand All @@ -169,26 +190,39 @@ impl File {
&self,
depth: Option<usize>,
ts_config: Option<String>,
import_type: Option<ImportType>,
) -> Result<TraceResult, Error> {
let tracer = Tracer::new(
let mut tracer = Tracer::new(
self.run.repo_root().to_owned(),
vec![self.path.clone()],
ts_config.map(Utf8PathBuf::from),
);

if let Some(import_type) = import_type {
tracer.set_import_type(import_type.into());
}

let mut result = tracer.trace(depth).await;
// Remove the file itself from the result
result.files.remove(&self.path);
TraceResult::new(result, self.run.clone())
}

async fn dependents(&self, ts_config: Option<String>) -> Result<TraceResult, Error> {
let tracer = Tracer::new(
async fn dependents(
&self,
ts_config: Option<String>,
import_type: Option<ImportType>,
) -> Result<TraceResult, Error> {
let mut tracer = Tracer::new(
self.run.repo_root().to_owned(),
vec![self.path.clone()],
ts_config.map(Utf8PathBuf::from),
);

if let Some(import_type) = import_type {
tracer.set_import_type(import_type.into());
}

let mut result = tracer.reverse_trace().await;
// Remove the file itself from the result
result.files.remove(&self.path);
Expand Down
6 changes: 6 additions & 0 deletions crates/turborepo/tests/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ fn test_trace() -> Result<(), anyhow::Error> {
"get `invalid.ts` with dependencies" => "query { file(path: \"invalid.ts\") { path dependencies { files { items { path } } errors { items { message } } } } }",
"get `main.ts` with depth = 0" => "query { file(path: \"main.ts\") { path dependencies(depth: 1) { files { items { path } } } } }",
"get `with_prefix.ts` with dependencies" => "query { file(path: \"with_prefix.ts\") { path dependencies { files { items { path } } } } }",
"get `import_value_and_type.ts` with all dependencies" => "query { file(path: \"import_value_and_type.ts\") { path dependencies(importType: ALL) { files { items { path } } } } }",
"get `import_value_and_type.ts` with type dependencies" => "query { file(path: \"import_value_and_type.ts\") { path dependencies(importType: TYPES) { files { items { path } } } } }",
"get `import_value_and_type.ts` with value dependencies" => "query { file(path: \"import_value_and_type.ts\") { path dependencies(importType: VALUES) { files { items { path } } } } }",
"get `link.tsx` with all dependents" => "query { file(path: \"link.tsx\") { path dependents(importType: ALL) { files { items { path } } } } }",
"get `link.tsx` with type dependents" => "query { file(path: \"link.tsx\") { path dependents(importType: TYPES) { files { items { path } } } } }",
"get `link.tsx` with value dependents" => "query { file(path: \"link.tsx\") { path dependents(importType: VALUES) { files { items { path } } } } }",
);

Ok(())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: crates/turborepo/tests/query.rs
expression: query_output
---
{
"data": {
"file": {
"path": "import_value_and_type.ts",
"dependencies": {
"files": {
"items": [
{
"path": "link.tsx"
},
{
"path": "types.ts"
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/turborepo/tests/query.rs
expression: query_output
---
{
"data": {
"file": {
"path": "import_value_and_type.ts",
"dependencies": {
"files": {
"items": [
{
"path": "types.ts"
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/turborepo/tests/query.rs
expression: query_output
---
{
"data": {
"file": {
"path": "import_value_and_type.ts",
"dependencies": {
"files": {
"items": [
{
"path": "link.tsx"
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
source: crates/turborepo/tests/query.rs
expression: query_output
---
{
"data": {
"file": {
"path": "link.tsx",
"dependents": {
"files": {
"items": [
{
"path": "import_just_type.ts"
},
{
"path": "import_just_value.ts"
},
{
"path": "import_value_and_type.ts"
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/turborepo/tests/query.rs
expression: query_output
---
{
"data": {
"file": {
"path": "link.tsx",
"dependents": {
"files": {
"items": [
{
"path": "import_just_type.ts"
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: crates/turborepo/tests/query.rs
expression: query_output
---
{
"data": {
"file": {
"path": "link.tsx",
"dependents": {
"files": {
"items": [
{
"path": "import_just_value.ts"
},
{
"path": "import_value_and_type.ts"
}
]
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import type { LinkProps } from "./link";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { Link } from "./link";
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import type { LinkProps } from "./types";
import { Link } from "./link";
8 changes: 8 additions & 0 deletions turborepo-tests/integration/fixtures/turbo_trace/link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface LinkProps {
children: React.ReactNode;
href: string;
}

export const Link = ({ children, href }: LinkProps) => {
return <a href={href}>{children}</a>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type LinkProps = string;
Loading