Skip to content

Commit

Permalink
fix: handle Windows path correctly (#555)
Browse files Browse the repository at this point in the history
We need to make truncate_registry_path can
handle Windows path as well.
Because tokio-console can connect to any
server from different platforms,
so we use the same path separator to have the same experience.
  • Loading branch information
Rustin170506 authored Jul 3, 2024
1 parent 5bdd1f2 commit 6ad0def
Showing 1 changed file with 69 additions and 10 deletions.
79 changes: 69 additions & 10 deletions tokio-console/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,22 +504,42 @@ impl Attribute {
}
}

// A naive way to determine if a path is a Windows path.
// If the path has a drive letter and more backslashes than forward slashes, it's a Windows path.
fn is_windows_path(path: &str) -> bool {
use once_cell::sync::OnceCell;
use regex::Regex;

static REGEX: OnceCell<Regex> = OnceCell::new();
let regex = REGEX.get_or_init(|| Regex::new(r"^[a-zA-Z]:\\").expect("failed to compile regex"));
let has_drive_letter = regex.is_match(path);
let slash_count = path.chars().filter(|&c| c == '/').count();
let backslash_count = path.chars().filter(|&c| c == '\\').count();
has_drive_letter && backslash_count > slash_count
}

fn truncate_registry_path(s: String) -> String {
use once_cell::sync::OnceCell;
use regex::Regex;
use std::borrow::Cow;

static REGEX: OnceCell<Regex> = OnceCell::new();
let regex = REGEX.get_or_init(|| {
Regex::new(r".*/\.cargo(/registry/src/[^/]*/|/git/checkouts/)")
Regex::new(r".*[/\\]\.cargo[/\\](registry[/\\]src[/\\][^/\\]*[/\\]|git[/\\]checkouts[/\\])")
.expect("failed to compile regex")
});

return match regex.replace(&s, "<cargo>/") {
let rep = if is_windows_path(&s) {
"<cargo>\\"
} else {
"<cargo>/"
};

match regex.replace(&s, rep) {
Cow::Owned(s) => s,
// String was not modified, return the original.
Cow::Borrowed(_) => s.to_string(),
};
Cow::Borrowed(_) => s,
}
}

fn format_location(loc: Option<proto::Location>) -> String {
Expand Down Expand Up @@ -586,30 +606,69 @@ mod tests {
#[test]
fn test_format_location_macos() {
// macOS style paths.
let location4 = proto::Location {
let location1 = proto::Location {
file: Some("/Users/user/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.0.1/src/lib.rs".to_string()),
..Default::default()
};
let location5 = proto::Location {
let location2 = proto::Location {
file: Some("/Users/user/.cargo/git/checkouts/tokio-1.0.1/src/lib.rs".to_string()),
..Default::default()
};
let location6 = proto::Location {
let location3 = proto::Location {
file: Some("/Users/user/projects/tokio-1.0.1/src/lib.rs".to_string()),
..Default::default()
};

assert_eq!(
format_location(Some(location4)),
format_location(Some(location1)),
"<cargo>/tokio-1.0.1/src/lib.rs"
);
assert_eq!(
format_location(Some(location5)),
format_location(Some(location2)),
"<cargo>/tokio-1.0.1/src/lib.rs"
);
assert_eq!(
format_location(Some(location6)),
format_location(Some(location3)),
"/Users/user/projects/tokio-1.0.1/src/lib.rs"
);
}

#[test]
fn test_format_location_windows() {
// Windows style paths.
let location1 = proto::Location {
file: Some(
"C:\\Users\\user\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\tokio-1.0.1\\src\\lib.rs"
.to_string(),
),
..Default::default()
};

let location2 = proto::Location {
file: Some(
"C:\\Users\\user\\.cargo\\git\\checkouts\\tokio-1.0.1\\src\\lib.rs".to_string(),
),
..Default::default()
};

let location3 = proto::Location {
file: Some("C:\\Users\\user\\projects\\tokio-1.0.1\\src\\lib.rs".to_string()),
..Default::default()
};

assert_eq!(
format_location(Some(location1)),
"<cargo>\\tokio-1.0.1\\src\\lib.rs"
);

assert_eq!(
format_location(Some(location2)),
"<cargo>\\tokio-1.0.1\\src\\lib.rs"
);

assert_eq!(
format_location(Some(location3)),
"C:\\Users\\user\\projects\\tokio-1.0.1\\src\\lib.rs"
);
}
}

0 comments on commit 6ad0def

Please sign in to comment.