Skip to content

Commit

Permalink
Add option to hide frames via regexes
Browse files Browse the repository at this point in the history
  • Loading branch information
nilehmann committed Jul 6, 2024
1 parent bcd7a17 commit ac68b7c
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 35 deletions.
96 changes: 96 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ version = "0.1.0"
[dependencies]
clap = { version = "4.5.8", features = ["derive", "wrap_help"] }
regex = "1.10.5"
serde = { version = "1.0.203", features = ["derive"] }
termcolor = "1.4.1"
termion = "4.0.2"
toml = "0.8.14"
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cargo install --git https://github.com/nilehmann/backtracetk

## Screenshot

![Screenshot](./screenshot.png)
![Screenshot](./screenshot1.png)

## Usage

Expand All @@ -28,11 +28,20 @@ Arguments:
[CMD]...

Options:
--style <STYLE> Set the backtrace style to short (RUST_BACKTRACE=1) or full (RUST_BACKTRACE=full)
[default: short] [possible values: short, full]
--no-lib-backtrace Set RUST_LIB_BACKTRACE=0
--hide-output By default, backtracetk prints every captured line as it reads it to get immediate
feedback. If this flag is set, this output is suppressed and nothing will be printed
until the program exits
-h, --help Print help
--style <STYLE> Set the backtrace style to short (RUST_BACKTRACE=1) or full
(RUST_BACKTRACE=full) [default: short] [possible values: short, full]
--enable-lib-backtrace By default, backtracetk sets RUST_LIB_BACKTRACE=0. Set this flag to revert this
behavior
--hide-output By default, backtracetk prints each captured line as it reads it, providing
immediate feedback. If this flag is set, this output is suppressed, and nothing
will be printed until the program exits
-h, --help Print help

```
### Configuration
Backtracetk will attempt to locate a configuration file named `backtrack.toml` or `.backtrack.toml` in the parent directories starting from where the command is executed. Currently, the only supported configuration is `hide`, which accepts a list of regex patterns.
Any frame matching on of these patterns will be hidden from the output. For example:
![Screenshot2](./screenshot2.png)
1 change: 1 addition & 0 deletions backtracetk.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hide = ["core::panicking", "rust_begin_unwind"]
File renamed without changes
Binary file added screenshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 55 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,8 @@ pub struct Backtrace {
panic_info: Option<PanicInfo>,
}

struct PanicInfo {
thread: String,
at: String,
message: Vec<String>,
}

pub struct Frame {
function: String,
frameno: u32,
source_info: Option<SourceInfo>,
}

pub struct SourceInfo {
file: String,
lineno: usize,
colno: usize,
}

impl Backtrace {
pub fn render(&self, out: &mut StandardStream) -> io::Result<()> {
pub fn render(&self, out: &mut StandardStream, filter: &mut impl Filter) -> io::Result<()> {
if self.frames.is_empty() {
return Ok(());
}
Expand All @@ -40,9 +22,17 @@ impl Backtrace {
let width = self.compute_width(framnow);
writeln!(out, "\n{:━^width$}", " BACKTRACE ")?;

let mut hidden = 0;
for frame in self.frames.iter().rev() {
frame.render(out, framnow, linenow)?;
if filter.exclude(frame) {
hidden += 1;
} else {
print_hidden_frames_message(out, hidden)?;
frame.render(out, framnow, linenow)?;
hidden = 0;
}
}
print_hidden_frames_message(out, hidden)?;

if let Some(panic_info) = &self.panic_info {
panic_info.render(out)?;
Expand Down Expand Up @@ -78,6 +68,18 @@ impl Backtrace {
}
}

struct PanicInfo {
thread: String,
at: String,
message: Vec<String>,
}

pub struct Frame {
pub function: String,
frameno: u32,
source_info: Option<SourceInfo>,
}

impl Frame {
fn render(&self, out: &mut StandardStream, framenow: usize, linenow: usize) -> io::Result<()> {
write!(out, "{:>framenow$}: ", self.frameno)?;
Expand All @@ -103,6 +105,26 @@ impl Frame {
}
}

pub struct SourceInfo {
file: String,
lineno: usize,
colno: usize,
}

fn print_hidden_frames_message(out: &mut StandardStream, hidden: u32) -> io::Result<()> {
out.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?;
match hidden {
0 => {}
1 => {
writeln!(out, " ({hidden} frame hidden)")?;
}
_ => {
writeln!(out, " ({hidden} frames hidden)")?;
}
}
out.set_color(&ColorSpec::new())
}

impl SourceInfo {
fn render(&self, out: &mut StandardStream, framenow: usize, linenow: usize) -> io::Result<()> {
write!(out, "{:framenow$} at ", "")?;
Expand Down Expand Up @@ -303,3 +325,16 @@ impl Parser {
backtraces
}
}

pub trait Filter {
fn exclude(&mut self, frame: &Frame) -> bool;
}

impl<F> Filter for F
where
F: FnMut(&Frame) -> bool,
{
fn exclude(&mut self, frame: &Frame) -> bool {
(self)(frame)
}
}
Loading

0 comments on commit ac68b7c

Please sign in to comment.