Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

extend --shorten-paths; highlight path segments #210

Merged
merged 7 commits into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
61 changes: 61 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ rustc-demangle = "0.1.19"
signal-hook = "0.3.8"
structopt = "0.3.21"
hidapi = "1.2.6"

[dev-dependencies]
pretty_assertions = "0.7.2"
rstest = "0.10.0"
17 changes: 7 additions & 10 deletions src/backtrace/pp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::borrow::Cow;

use colored::Colorize as _;

use crate::utils;
use crate::dep;

use super::{symbolicate::Frame, Settings};

Expand Down Expand Up @@ -40,24 +40,21 @@ pub(crate) fn backtrace(frames: &[Frame], settings: &Settings) {
println!("{}", colorized_line);

if let Some(location) = &subroutine.location {
let dep_path = dep::Path::from_std_path(&location.path);

let path = if settings.shorten_paths {
utils::shorten_paths(&location.path)
dep_path.format_short()
} else {
location.path.display().to_string()
dep_path.format_highlight()
};

let line = location.line;
let column = location
.column
.map(|column| Cow::Owned(format!(":{}", column)))
.unwrap_or(Cow::Borrowed(""));

let line = format!(" at {}:{}{}", path, line, column);
let colorized_line = if is_local_function {
line.normal()
} else {
line.dimmed()
};
println!("{}", colorized_line);
println!(" at {}:{}{}", path, line, column);
}

frame_index += 1;
Expand Down
98 changes: 98 additions & 0 deletions src/dep/cratesio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use std::path::{self, Component, Path as StdPath, PathBuf};

use colored::Colorize as _;

#[derive(Debug, PartialEq)]
pub(crate) struct Path<'p> {
Urhengulas marked this conversation as resolved.
Show resolved Hide resolved
registry_prefix: PathBuf,
crate_name_version: &'p str,
path: &'p StdPath,
}

impl<'p> Path<'p> {
pub(crate) fn from_std_path(path: &'p StdPath) -> Option<Self> {
if !path.is_absolute() {
return None;
}

let mut components = path.components();

let mut registry_prefix = PathBuf::new();
while let Some(component) = components.next() {
registry_prefix.push(component.as_os_str());

if let Component::Normal(component) = component {
if component == "registry" {
break;
}
}
}

let src = super::get_component_normal(components.next()?)?;
if src != "src" {
return None;
}
registry_prefix.push(src);

let github = super::get_component_normal(components.next()?)?.to_str()?;
if !github.starts_with("jackfan.us.kg-") {
return None;
}
registry_prefix.push(github);

let crate_name_version = super::get_component_normal(components.next()?)?.to_str()?;

Some(Path {
registry_prefix,
crate_name_version,
path: components.as_path(),
})
}

pub(crate) fn format_short(&self) -> String {
format!(
"[{}]{}{}",
self.crate_name_version,
path::MAIN_SEPARATOR,
self.path.display()
)
}

pub(crate) fn format_highlight(&self) -> String {
format!(
"{}{sep}{}{sep}{}",
self.registry_prefix.display().to_string().dimmed(),
self.crate_name_version.bold(),
self.path.display(),
sep = path::MAIN_SEPARATOR,
)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn end_to_end() {
let input = StdPath::new(
"/home/user/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/cortex-m-rt-0.6.13/src/lib.rs",
);

let path = Path::from_std_path(input).unwrap();
let expected = Path {
registry_prefix: PathBuf::from(
"/home/user/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/",
),
crate_name_version: "cortex-m-rt-0.6.13",
path: StdPath::new("src/lib.rs"),
};

assert_eq!(expected, path);

let expected_str = "[cortex-m-rt-0.6.13]/src/lib.rs";
let formatted_str = path.format_short();

assert_eq!(expected_str, formatted_str);
}
}
84 changes: 84 additions & 0 deletions src/dep/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! Dependency path parsing

use std::{
ffi::OsStr,
path::{Component, Path as StdPath},
};

mod cratesio;
mod rust_repo;
mod rust_std;
mod rustc;

#[derive(Debug, PartialEq)]
pub(crate) enum Path<'p> {
Cratesio(cratesio::Path<'p>),
/// Path into `rust-std` component
RustStd(rust_std::Path<'p>),
/// "Remapped" rust-lang/rust path AKA `/rustc` path
Rustc(rustc::Path<'p>),
Verbatim(&'p StdPath),
}

impl<'p> Path<'p> {
pub(crate) fn from_std_path(path: &'p StdPath) -> Self {
if let Some(rust_std) = rust_std::Path::from_std_path(path) {
Self::RustStd(rust_std)
} else if let Some(rustc) = rustc::Path::from_std_path(path) {
Self::Rustc(rustc)
} else if let Some(cratesio) = cratesio::Path::from_std_path(path) {
Self::Cratesio(cratesio)
} else {
Self::Verbatim(path)
}
}

pub(crate) fn format_short(&self) -> String {
match self {
Path::Cratesio(cratesio) => cratesio.format_short(),
Path::RustStd(rust_std) => rust_std.format_short(),
Path::Rustc(rustc) => rustc.format_short(),
Path::Verbatim(path) => path.display().to_string(),
}
}

pub(crate) fn format_highlight(&self) -> String {
match self {
Path::Cratesio(cratesio) => cratesio.format_highlight(),
Path::RustStd(rust_std) => rust_std.format_highlight(),
Path::Rustc(rustc) => rustc.format_highlight(),
Path::Verbatim(path) => path.display().to_string(),
}
}
}

fn get_component_normal<'c>(component: Component<'c>) -> Option<&'c OsStr> {
if let Component::Normal(string) = component {
Some(string)
} else {
None
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn from_std_path_returns_correct_variant() {
let cratesio = StdPath::new(
"/home/user/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/cortex-m-rt-0.6.13/src/lib.rs",
);
Urhengulas marked this conversation as resolved.
Show resolved Hide resolved

let rustc = StdPath::new(
"/rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs",
);
let rust_std = StdPath::new("/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs");
japaric marked this conversation as resolved.
Show resolved Hide resolved
let local = StdPath::new("src/lib.rs");

assert!(matches!(Path::from_std_path(cratesio), Path::Cratesio(_)));
assert!(matches!(Path::from_std_path(rustc), Path::Rustc(_)));
assert!(matches!(Path::from_std_path(rust_std), Path::RustStd(_)));
assert!(matches!(Path::from_std_path(local), Path::Verbatim(_)));
}
}
Loading