Skip to content

Commit

Permalink
Connected turbo trace to query
Browse files Browse the repository at this point in the history
  • Loading branch information
NicholasLYang committed Sep 17, 2024
1 parent e74ef21 commit a793850
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 175 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ async-recursion = "1.0.2"
miette = { version = "5.10.0", features = ["fancy"] }
markdown = "1.0.0-alpha.18"

turbo-trace = { path = "crates/turbo-trace" }
turbo-updater = { path = "crates/turborepo-updater" }
turbopath = { path = "crates/turborepo-paths" }
turborepo = { path = "crates/turborepo" }
Expand Down
4 changes: 4 additions & 0 deletions crates/turbo-trace/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod import_finder;
mod tracer;

pub use tracer::{TraceError, Tracer};
22 changes: 15 additions & 7 deletions crates/turbo-trace/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@ use camino::Utf8PathBuf;
use clap::Parser;
use thiserror::Error;
use tracer::Tracer;

#[derive(Debug, Error)]
enum Error {
#[error(transparent)]
Path(#[from] turbopath::PathError),
}
use turbo_trace::Error;
use turbopath::AbsoluteSystemPathBuf;

#[derive(Parser, Debug)]
struct Args {
Expand All @@ -24,7 +20,19 @@ struct Args {
fn main() -> Result<(), Error> {
let args = Args::parse();

let tracer = Tracer::new(args.files, args.cwd, args.ts_config)?;
let abs_cwd = if let Some(cwd) = args.cwd {
AbsoluteSystemPathBuf::from_cwd(cwd)?
} else {
AbsoluteSystemPathBuf::cwd()?
};

let files = args
.files
.into_iter()
.map(|f| AbsoluteSystemPathBuf::from_unknown(&abs_cwd, f))
.collect();

let tracer = Tracer::new(files, abs_cwd, args.ts_config)?;

let result = tracer.trace();

Expand Down
86 changes: 37 additions & 49 deletions crates/turbo-trace/src/tracer.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use std::{collections::HashSet, fs, sync::Arc};

use camino::Utf8PathBuf;
use miette::{miette, LabeledSpan, NamedSource};
use miette::{Diagnostic, NamedSource, SourceSpan};
use oxc_resolver::{
EnforceExtension, ResolveError, ResolveOptions, Resolver, TsconfigOptions, TsconfigReferences,
};
use swc_common::{comments::SingleThreadedComments, input::StringInput, FileName, SourceMap};
use swc_ecma_ast::EsVersion;
use swc_ecma_parser::{lexer::Lexer, Capturing, EsSyntax, Parser, Syntax, TsSyntax};
use swc_ecma_visit::VisitWith;
use turbopath::AbsoluteSystemPathBuf;
use thiserror::Error;
use turbopath::{AbsoluteSystemPathBuf, PathError};

use crate::{import_finder::ImportFinder, Error};
use crate::import_finder::ImportFinder;

pub struct Tracer {
cwd: AbsoluteSystemPathBuf,
Expand All @@ -21,35 +22,39 @@ pub struct Tracer {
source_map: Arc<SourceMap>,
}

#[derive(Debug, Error, Diagnostic)]
pub enum TraceError {
#[error("failed to read file: {0}")]
FileNotFound(AbsoluteSystemPathBuf),
#[error(transparent)]
PathEncoding(PathError),
#[error("failed to resolve import")]
Resolve {
#[label("import here")]
span: SourceSpan,
#[source_code]
text: NamedSource,
},
}

pub struct TraceResult {
pub errors: Vec<String>,
pub errors: Vec<TraceError>,
pub files: HashSet<AbsoluteSystemPathBuf>,
}

impl Tracer {
pub fn new(
files: Vec<Utf8PathBuf>,
cwd: Option<Utf8PathBuf>,
files: Vec<AbsoluteSystemPathBuf>,
cwd: AbsoluteSystemPathBuf,
ts_config: Option<Utf8PathBuf>,
) -> Result<Self, Error> {
let abs_cwd = if let Some(cwd) = cwd {
AbsoluteSystemPathBuf::from_cwd(cwd)?
} else {
AbsoluteSystemPathBuf::cwd()?
};

let files = files
.into_iter()
.map(|f| AbsoluteSystemPathBuf::from_unknown(&abs_cwd, f))
.collect();

) -> Result<Self, PathError> {
let ts_config =
ts_config.map(|ts_config| AbsoluteSystemPathBuf::from_unknown(&abs_cwd, ts_config));
ts_config.map(|ts_config| AbsoluteSystemPathBuf::from_unknown(&cwd, ts_config));

let seen = HashSet::new();

Ok(Self {
cwd: abs_cwd,
cwd,
files,
seen,
ts_config,
Expand Down Expand Up @@ -83,12 +88,9 @@ impl Tracer {
self.seen.insert(file_path.clone());

// Read the file content
let file_content = match fs::read_to_string(&file_path) {
Ok(content) => content,
Err(err) => {
errors.push(format!("failed to read file {}: {}", file_path, err));
continue;
}
let Ok(file_content) = fs::read_to_string(&file_path) else {
errors.push(TraceError::FileNotFound(file_path.clone()));
continue;
};

let comments = SingleThreadedComments::default();
Expand Down Expand Up @@ -122,12 +124,9 @@ impl Tracer {
let mut parser = Parser::new_from(Capturing::new(lexer));

// Parse the file as a module
let module = match parser.parse_module() {
Ok(module) => module,
Err(err) => {
errors.push(format!("failed to parse module {}: {:?}", file_path, err));
continue;
}
let Ok(module) = parser.parse_module() else {
errors.push(TraceError::FileNotFound(file_path.to_owned()));
continue;
};

// Visit the AST and find imports
Expand All @@ -142,28 +141,17 @@ impl Tracer {
Ok(resolved) => match resolved.into_path_buf().try_into() {
Ok(path) => self.files.push(path),
Err(err) => {
errors.push(err.to_string());
errors.push(TraceError::PathEncoding(err));
}
},
Err(ResolveError::Builtin(_)) => {}
Err(err) => {
Err(_) => {
let (start, end) = self.source_map.span_to_char_offset(&source_file, *span);

let report = miette!(
labels = [LabeledSpan::at(
(start as usize)..(end as usize),
"import here"
)],
"failed to resolve import",
)
.with_source_code(NamedSource::new(
file_path.to_string(),
file_content.clone(),
));

println!("{:?}", report);

errors.push(err.to_string());
errors.push(TraceError::Resolve {
span: (start as usize, end as usize).into(),
text: NamedSource::new(file_path.to_string(), file_content.clone()),
});
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/turborepo-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ tracing-appender = "0.2.2"
tracing-chrome = "0.7.1"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
tracing.workspace = true
turbo-trace = { workspace = true }
turbo-updater = { workspace = true }
turbopath = { workspace = true }
turborepo-analytics = { path = "../turborepo-analytics" }
Expand Down
56 changes: 56 additions & 0 deletions crates/turborepo-lib/src/query/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::sync::Arc;

use async_graphql::Object;
use turbo_trace::Tracer;
use turbopath::AbsoluteSystemPathBuf;

use crate::{query::Error, run::Run};

pub struct File {
run: Arc<Run>,
path: AbsoluteSystemPathBuf,
}

impl File {
pub fn new(run: Arc<Run>, path: AbsoluteSystemPathBuf) -> Self {
Self { run, path }
}
}

#[Object]
impl File {
async fn contents(&self) -> Result<String, Error> {
let contents = self.path.read_to_string()?;
Ok(contents)
}

async fn path(&self) -> Result<String, Error> {
Ok(self
.run
.repo_root()
.anchor(&self.path)
.map(|path| path.to_string())?)
}

async fn absolute_path(&self) -> Result<String, Error> {
Ok(self.path.to_string())
}

async fn dependencies(&self) -> Result<Vec<File>, Error> {
let tracer = Tracer::new(
vec![self.path.clone()],
self.run.repo_root().to_owned(),
None,
)?;
let result = tracer.trace();
if !result.errors.is_empty() {
return Err(Error::Trace(result.errors));
}

Ok(result
.files
.into_iter()
.map(|path| File::new(self.run.clone(), path))
.collect())
}
}
Loading

0 comments on commit a793850

Please sign in to comment.