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

Implement package.json's imports field #4895

Merged
merged 14 commits into from
May 18, 2023
2 changes: 1 addition & 1 deletion crates/turbo-tasks-memory/tests/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::sync::Mutex;

use anyhow::Result;
use turbo_tasks::{debug::ValueDebug, TaskInput};
use turbo_tasks::debug::ValueDebug;
use turbo_tasks_testing::{register, run};

register!();
Expand Down
1 change: 0 additions & 1 deletion crates/turbopack-core/src/issue/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub mod analyze;
pub mod code_gen;
pub mod package_json;
pub mod resolve;
pub mod unsupported_module;

Expand Down
34 changes: 0 additions & 34 deletions crates/turbopack-core/src/issue/package_json.rs

This file was deleted.

1 change: 1 addition & 0 deletions crates/turbopack-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod error;
pub mod ident;
pub mod introspect;
pub mod issue;
pub mod package_json;
pub mod plugin;
pub mod proxied_asset;
pub mod reference;
Expand Down
85 changes: 85 additions & 0 deletions crates/turbopack-core/src/package_json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use std::{fmt::Write, ops::Deref};

use anyhow::Result;
use serde_json::Value as JsonValue;
use turbo_tasks::{debug::ValueDebugFormat, primitives::StringVc, trace::TraceRawVcs};
use turbo_tasks_fs::{FileContent, FileJsonContent, FileJsonContentReadRef, FileSystemPathVc};

use super::issue::{Issue, IssueVc};

/// PackageJson wraps the parsed JSON content of a `package.json` file. The
/// wrapper is necessary so that we can reference the [FileJsonContent]'s inner
/// [serde_json::Value] without cloning it.
#[derive(PartialEq, Eq, ValueDebugFormat, TraceRawVcs)]
pub struct PackageJson(FileJsonContentReadRef);

impl Deref for PackageJson {
type Target = JsonValue;
fn deref(&self) -> &Self::Target {
match &*self.0 {
FileJsonContent::Content(json) => json,
_ => unreachable!("PackageJson is guaranteed to hold Content"),
jridgewell marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

#[turbo_tasks::value(transparent, serialization = "none")]
pub struct OptionPackageJson(Option<PackageJson>);

/// Reads a package.json file (if it exists). If the file is unparseable, it
/// emits a useful [Issue] pointing to the invalid location.
#[turbo_tasks::function]
pub async fn read_package_json(path: FileSystemPathVc) -> Result<OptionPackageJsonVc> {
let read = path.read_json().await?;
match &*read {
FileJsonContent::Content(_) => Ok(OptionPackageJson(Some(PackageJson(read))).cell()),
FileJsonContent::NotFound => Ok(OptionPackageJson(None).cell()),
FileJsonContent::Unparseable(e) => {
let mut message = "package.json is not parseable: invalid JSON: ".to_string();
if let FileContent::Content(content) = &*path.read().await? {
let text = content.content().to_str()?;
e.write_with_content(&mut message, &text)?;
} else {
write!(message, "{}", e)?;
}
PackageJsonIssue {
error_message: message,
path,
}
.cell()
.as_issue()
.emit();
Ok(OptionPackageJson(None).cell())
}
}
}

/// Reusable Issue struct representing any problem with a `package.json`
#[turbo_tasks::value(shared)]
pub struct PackageJsonIssue {
pub path: FileSystemPathVc,
pub error_message: String,
}

#[turbo_tasks::value_impl]
impl Issue for PackageJsonIssue {
#[turbo_tasks::function]
fn title(&self) -> StringVc {
StringVc::cell("Error parsing package.json file".to_string())
}

#[turbo_tasks::function]
fn category(&self) -> StringVc {
StringVc::cell("parse".to_string())
}

#[turbo_tasks::function]
fn context(&self) -> FileSystemPathVc {
self.path
}

#[turbo_tasks::function]
fn description(&self) -> StringVc {
StringVc::cell(self.error_message.clone())
}
}
Loading