Skip to content

Commit

Permalink
Merge ffa9e26 into cc5ed35
Browse files Browse the repository at this point in the history
  • Loading branch information
wbinnssmith authored Nov 8, 2023
2 parents cc5ed35 + ffa9e26 commit 1a33186
Show file tree
Hide file tree
Showing 35 changed files with 283 additions and 162 deletions.
9 changes: 5 additions & 4 deletions crates/turbo-tasks-fetch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use anyhow::Result;
use turbo_tasks::Vc;
use turbo_tasks_fs::FileSystemPath;
use turbopack_core::issue::{Issue, IssueSeverity};
use turbopack_core::issue::{Issue, IssueSeverity, StyledString};

pub fn register() {
turbo_tasks::register();
Expand Down Expand Up @@ -154,11 +154,11 @@ impl Issue for FetchIssue {
}

#[turbo_tasks::function]
async fn description(&self) -> Result<Vc<String>> {
async fn description(&self) -> Result<Vc<StyledString>> {
let url = &*self.url.await?;
let kind = &*self.kind.await?;

Ok(Vc::cell(match kind {
Ok(StyledString::Text(match kind {
FetchErrorKind::Connect => format!(
"There was an issue establishing a connection while requesting {}.",
url
Expand All @@ -171,7 +171,8 @@ impl Issue for FetchIssue {
}
FetchErrorKind::Timeout => format!("Connection timed out when requesting {}", url),
FetchErrorKind::Other => format!("There was an issue requesting {}", url),
}))
})
.cell())
}

#[turbo_tasks::function]
Expand Down
6 changes: 3 additions & 3 deletions crates/turbo-tasks-fetch/tests/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use turbo_tasks::Vc;
use turbo_tasks_fetch::{fetch, register, FetchErrorKind};
use turbo_tasks_fs::{DiskFileSystem, FileSystem, FileSystemPath};
use turbo_tasks_testing::{register, run};
use turbopack_core::issue::{Issue, IssueSeverity};
use turbopack_core::issue::{Issue, IssueSeverity, StyledString};

register!();

Expand Down Expand Up @@ -115,7 +115,7 @@ async fn errors_on_failed_connection() {
let issue = err_vc.to_issue(IssueSeverity::Error.into(), get_issue_context());
assert_eq!(*issue.severity().await?, IssueSeverity::Error);
assert_eq!(*issue.category().await?, "fetch");
assert_eq!(*issue.description().await?, "There was an issue establishing a connection while requesting https://doesnotexist/foo.woff.");
assert_eq!(*issue.description().await?, StyledString::Text("There was an issue establishing a connection while requesting https://doesnotexist/foo.woff.".to_string()));
}
}

Expand All @@ -137,7 +137,7 @@ async fn errors_on_404() {
let issue = err_vc.to_issue(IssueSeverity::Error.into(), get_issue_context());
assert_eq!(*issue.severity().await?, IssueSeverity::Error);
assert_eq!(*issue.category().await?, "fetch");
assert_eq!(*issue.description().await?, format!("Received response with status 404 when requesting {}", &resource_url));
assert_eq!(*issue.description().await?, StyledString::Text(format!("Received response with status 404 when requesting {}", &resource_url)));
}
}

Expand Down
39 changes: 36 additions & 3 deletions crates/turbopack-cli-utils/src/issue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use turbo_tasks::{RawVc, ReadRef, TransientInstance, TransientValue, TryJoinIter
use turbo_tasks_fs::{source_context::get_source_context, FileLinesContent};
use turbopack_core::issue::{
CapturedIssues, Issue, IssueReporter, IssueSeverity, PlainIssue, PlainIssueProcessingPathItem,
PlainIssueSource,
PlainIssueSource, StyledString,
};

use crate::source_context::format_source_context_lines;
Expand Down Expand Up @@ -162,7 +162,12 @@ pub fn format_issue(

let description = &plain_issue.description;
if !description.is_empty() {
writeln!(styled_issue, "\n{description}").unwrap();
writeln!(
styled_issue,
"\n{}",
render_styled_string_to_ansi(description)
)
.unwrap();
}

if log_detail {
Expand Down Expand Up @@ -418,7 +423,11 @@ impl IssueReporter for ConsoleUi {

let description = &plain_issue.description;
if !description.is_empty() {
writeln!(&mut styled_issue, "\n{description}")?;
writeln!(
&mut styled_issue,
"\n{}",
render_styled_string_to_ansi(description)
)?;
}

if log_detail {
Expand Down Expand Up @@ -570,3 +579,27 @@ fn show_all_message_with_shown_count(
.bold()
}
}

fn render_styled_string_to_ansi(styled_string: &StyledString) -> String {
match styled_string {
StyledString::Line(parts) => {
let mut string = String::new();
for part in parts {
string.push_str(&render_styled_string_to_ansi(part));
}
string.push('\n');
string
}
StyledString::Stack(parts) => {
let mut string = String::new();
for part in parts {
string.push_str(&render_styled_string_to_ansi(part));
string.push('\n');
}
string
}
StyledString::Text(string) => string.to_string(),
StyledString::Code(string) => string.blue().to_string(),
StyledString::Strong(string) => string.bold().to_string(),
}
}
6 changes: 3 additions & 3 deletions crates/turbopack-core/src/issue/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ use anyhow::Result;
use turbo_tasks::Vc;
use turbo_tasks_fs::FileSystemPath;

use super::{Issue, IssueSeverity, LazyIssueSource, OptionIssueSource};
use super::{Issue, IssueSeverity, LazyIssueSource, OptionIssueSource, StyledString};
use crate::ident::AssetIdent;

#[turbo_tasks::value(shared)]
pub struct AnalyzeIssue {
pub severity: Vc<IssueSeverity>,
pub source_ident: Vc<AssetIdent>,
pub title: Vc<String>,
pub message: Vc<String>,
pub message: Vc<StyledString>,
pub category: Vc<String>,
pub code: Option<String>,
pub source: Option<Vc<LazyIssueSource>>,
Expand Down Expand Up @@ -43,7 +43,7 @@ impl Issue for AnalyzeIssue {
}

#[turbo_tasks::function]
fn description(&self) -> Vc<String> {
fn description(&self) -> Vc<StyledString> {
self.message
}

Expand Down
6 changes: 3 additions & 3 deletions crates/turbopack-core/src/issue/code_gen.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use turbo_tasks::Vc;
use turbo_tasks_fs::FileSystemPath;

use super::{Issue, IssueSeverity};
use super::{Issue, IssueSeverity, StyledString};

#[turbo_tasks::value(shared)]
pub struct CodeGenerationIssue {
pub severity: Vc<IssueSeverity>,
pub path: Vc<FileSystemPath>,
pub title: Vc<String>,
pub message: Vc<String>,
pub message: Vc<StyledString>,
}

#[turbo_tasks::value_impl]
Expand All @@ -34,7 +34,7 @@ impl Issue for CodeGenerationIssue {
}

#[turbo_tasks::function]
fn description(&self) -> Vc<String> {
fn description(&self) -> Vc<StyledString> {
self.message
}
}
80 changes: 74 additions & 6 deletions crates/turbopack-core/src/issue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,77 @@ impl Display for IssueSeverity {
}
}

/// Represents a section of structured styled text. This can be interpreted and
/// rendered by various UIs as appropriate, e.g. HTML for display on the web,
/// ANSI sequences in TTYs.
#[derive(Clone, Debug)]
#[turbo_tasks::value(shared)]
pub enum StyledString {
/// Multiple [StyledString]s concatenated into a single line. Each item is
/// considered as inline element. Items might contain line breaks, which
/// would be considered as soft line breaks.
Line(Vec<StyledString>),
/// Multiple [StyledString]s stacked vertically. They are considered as
/// block elements, just like the top level [StyledString].
Stack(Vec<StyledString>),
/// Some prose text.
Text(String),
/// Code snippet.
// TODO add language to support syntax hightlighting
Code(String),
/// Some important text.
Strong(String),
}

impl DeterministicHash for StyledString {
fn deterministic_hash<H: turbo_tasks_hash::DeterministicHasher>(&self, state: &mut H) {
match self {
StyledString::Line(parts) => {
"line_start".deterministic_hash(state);
for part in parts {
part.deterministic_hash(state);
}
"line_end".deterministic_hash(state);
}
StyledString::Stack(parts) => {
"stack_start".deterministic_hash(state);
for part in parts {
part.deterministic_hash(state);
}
"stack_end".deterministic_hash(state);
}
StyledString::Text(s) => {
"text_start".deterministic_hash(state);
s.deterministic_hash(state);
"text_end".deterministic_hash(state);
}
StyledString::Code(s) => {
"code_start".deterministic_hash(state);
s.deterministic_hash(state);
"code_end".deterministic_hash(state);
}
StyledString::Strong(s) => {
"strong_start".deterministic_hash(state);
s.deterministic_hash(state);
"strong_end".deterministic_hash(state);
}
}
}
}

impl StyledString {
pub fn is_empty(&self) -> bool {
match self {
StyledString::Line(parts) | StyledString::Stack(parts) => {
parts.iter().all(|part| part.is_empty())
}
StyledString::Text(string)
| StyledString::Code(string)
| StyledString::Strong(string) => string.is_empty(),
}
}
}

#[turbo_tasks::value_trait]
pub trait Issue {
/// Severity allows the user to filter out unimportant issues, with Bug
Expand Down Expand Up @@ -100,7 +171,7 @@ pub trait Issue {
/// A more verbose message of the issue, appropriate for providing multiline
/// information of the issue.
// TODO add Vc<StyledString>
fn description(self: Vc<Self>) -> Vc<String>;
fn description(self: Vc<Self>) -> Vc<StyledString>;

/// Full details of the issue, appropriate for providing debug level
/// information. Only displayed if the user explicitly asks for detailed
Expand Down Expand Up @@ -487,7 +558,7 @@ pub struct PlainIssue {
pub category: String,

pub title: String,
pub description: String,
pub description: StyledString,
pub detail: String,
pub documentation_link: String,

Expand All @@ -501,10 +572,7 @@ fn hash_plain_issue(issue: &PlainIssue, hasher: &mut Xxh3Hash64Hasher, full: boo
hasher.write_ref(&issue.file_path);
hasher.write_ref(&issue.category);
hasher.write_ref(&issue.title);
hasher.write_ref(
// Normalize syspaths from Windows. These appear in stack traces.
&issue.description.replace('\\', "/"),
);
hasher.write_ref(&issue.description);
hasher.write_ref(&issue.detail);
hasher.write_ref(&issue.documentation_link);

Expand Down
14 changes: 8 additions & 6 deletions crates/turbopack-core/src/issue/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::Result;
use turbo_tasks::{ValueToString, Vc};
use turbo_tasks_fs::FileSystemPath;

use super::{Issue, OptionIssueSource};
use super::{Issue, OptionIssueSource, StyledString};
use crate::{
error::PrettyPrintError,
issue::{IssueSeverity, LazyIssueSource},
Expand Down Expand Up @@ -48,11 +48,13 @@ impl Issue for ResolvingIssue {
}

#[turbo_tasks::function]
async fn description(&self) -> Result<Vc<String>> {
Ok(Vc::cell(format!(
"unable to resolve {module_name}",
module_name = self.request.to_string().await?
)))
async fn description(&self) -> Result<Vc<StyledString>> {
Ok(StyledString::Line(vec![
StyledString::Strong("Module not found".to_string()),
StyledString::Text(": Can't resolve".to_string()),
StyledString::Code(self.request.to_string().await?.to_string()),
])
.cell())
}

#[turbo_tasks::function]
Expand Down
9 changes: 5 additions & 4 deletions crates/turbopack-core/src/issue/unsupported_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::Result;
use turbo_tasks::Vc;
use turbo_tasks_fs::FileSystemPath;

use super::{Issue, IssueSeverity};
use super::{Issue, IssueSeverity, StyledString};

#[turbo_tasks::value(shared)]
pub struct UnsupportedModuleIssue {
Expand Down Expand Up @@ -34,10 +34,11 @@ impl Issue for UnsupportedModuleIssue {
}

#[turbo_tasks::function]
async fn description(&self) -> Result<Vc<String>> {
Ok(Vc::cell(match &self.package_path {
async fn description(&self) -> Result<Vc<StyledString>> {
Ok(StyledString::Text(match &self.package_path {
Some(path) => format!("The module {}{} is not yet supported", self.package, path),
None => format!("The package {} is not yet supported", self.package),
}))
})
.cell())
}
}
6 changes: 3 additions & 3 deletions crates/turbopack-core/src/package_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, ReadRef, Vc};
use turbo_tasks_fs::{FileContent, FileJsonContent, FileSystemPath};

use super::issue::Issue;
use crate::issue::IssueExt;
use crate::issue::{IssueExt, StyledString};

/// PackageJson wraps the parsed JSON content of a `package.json` file. The
/// wrapper is necessary so that we can reference the [FileJsonContent]'s inner
Expand Down Expand Up @@ -79,7 +79,7 @@ impl Issue for PackageJsonIssue {
}

#[turbo_tasks::function]
fn description(&self) -> Vc<String> {
Vc::cell(self.error_message.clone())
fn description(&self) -> Vc<StyledString> {
StyledString::Text(self.error_message.clone()).cell()
}
}
Loading

0 comments on commit 1a33186

Please sign in to comment.