Skip to content
Closed
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
7 changes: 7 additions & 0 deletions defaults/default-prefs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@
# Set 'enabled' to true to have bacon always export locations
# This is equivalent to always adding -e to bacon commands
# but can still be cancelled on specific launches with -E
#
# 'add_context_to_message' is used to control whether to ad
# any normal line linked to the diagnostic title. When this
# is on, carriage returns are escaped to ensure we generate
# everything on a single line. They can be expande by replacing
# '\\n' with '\n' when read from the export locations file.
[export]
enabled = false
add_context_to_message = false
path = ".bacon-locations"
line_format = "{kind} {path}:{line}:{column} {message}"

Expand Down
1 change: 1 addition & 0 deletions src/export_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ pub struct ExportConfig {
pub enabled: Option<bool>,
pub path: Option<PathBuf>,
pub line_format: Option<String>,
pub add_context_to_message: Option<bool>
}
5 changes: 5 additions & 0 deletions src/export_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct ExportSettings {
pub enabled: bool,
pub path: PathBuf,
pub line_format: String,
pub add_context_to_message: bool
}

impl Default for ExportSettings {
Expand All @@ -17,6 +18,7 @@ impl Default for ExportSettings {
enabled: false,
path: default_path(),
line_format: default_line_format().to_string(),
add_context_to_message: false
}
}
}
Expand Down Expand Up @@ -45,5 +47,8 @@ impl ExportSettings {
if let Some(line_format) = &config.line_format {
self.line_format.clone_from(line_format);
}
if let Some(add_context_to_message) = config.add_context_to_message {
self.add_context_to_message = add_context_to_message;
}
}
}
16 changes: 16 additions & 0 deletions src/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ impl Line {
_ => None,
}
}

/// If the line is normal. get its messages
pub fn context(&self) -> Option<String> {
match self.line_type {
LineType::Normal => Some(
self.content
.strings
.iter()
.map(|ts| ts.raw.as_str())
.collect::<Vec<&str>>()
.join(""),
),
_ => None,
}
}

/// Return the location as given by cargo
/// It's usually relative and may contain the line and column
pub fn location(&self) -> Option<&str> {
Expand Down
69 changes: 63 additions & 6 deletions src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ use {
crate::*,
anyhow::Result,
lazy_regex::*,
std::{
collections::HashSet,
io,
path::PathBuf,
},
std::{collections::HashSet, io, path::PathBuf},
};

/// the usable content of cargo watch's output,
Expand Down Expand Up @@ -167,6 +163,51 @@ impl Report {
output: CommandOutput::default(),
})
}

/// Extract all the diagnostic context.
fn extract_diagnostic_context(
&self,
line: &Line,
) -> Option<String> {
let mut context = String::new();
for l in &self.lines {
if let LineType::Normal = l.line_type {
if l.item_idx == line.item_idx {
if let Some(ctx) = l.context() {
context = format!("{context}\n{ctx}");
}
}
}
}
if context.is_empty() {
None
} else {
Some(context.replace("\n", "\\n"))
}
}

/// Compose the message.
///
/// If `add_context_to_message` is true and there is context to this error,
/// it will be added to the exported line.
fn compose_message(
&self,
message: Option<&str>,
context: Option<String>,
add_context_to_message: bool,
) -> String {
if let Some(message) = message {
if add_context_to_message {
if let Some(context) = context {
return format!("{message}{context}");
}
}
message.to_string()
} else {
"".to_string()
}
}

/// export the report in a file
pub fn write_to<W: io::Write>(
&self,
Expand All @@ -175,19 +216,29 @@ impl Report {
) -> Result<(), io::Error> {
let mut last_kind = "???";
let mut message = None;
let mut context = None;
for line in &self.lines {
match line.line_type {
LineType::Title(Kind::Warning) => {
last_kind = "warning";
message = line.title_message();
if mission.settings.export.add_context_to_message {
context = self.extract_diagnostic_context(line);
}
}
LineType::Title(Kind::Error) => {
last_kind = "error";
message = line.title_message();
if mission.settings.export.add_context_to_message {
context = self.extract_diagnostic_context(line);
}
}
LineType::Title(Kind::TestFail) => {
last_kind = "test";
message = line.title_message();
if mission.settings.export.add_context_to_message {
context = self.extract_diagnostic_context(line);
}
}
_ => {}
}
Expand All @@ -208,6 +259,12 @@ impl Report {
.to_string();
path = &path_string;
}
let message = self.compose_message(
message,
context,
mission.settings.export.add_context_to_message,
);
context = None;
let exported = regex_replace_all!(
r#"\{([^\s}]+)\}"#,
&mission.settings.export.line_format,
Expand All @@ -217,7 +274,7 @@ impl Report {
"path" => path,
"line" => file_line,
"column" => file_column,
"message" => message.unwrap_or(""),
"message" => &message,
_ => {
debug!("unknown export key: {key:?}");
""
Expand Down