Skip to content

Commit 6ad0def

Browse files
authored
fix: handle Windows path correctly (#555)
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.
1 parent 5bdd1f2 commit 6ad0def

File tree

1 file changed

+69
-10
lines changed

1 file changed

+69
-10
lines changed

tokio-console/src/state/mod.rs

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -504,22 +504,42 @@ impl Attribute {
504504
}
505505
}
506506

507+
// A naive way to determine if a path is a Windows path.
508+
// If the path has a drive letter and more backslashes than forward slashes, it's a Windows path.
509+
fn is_windows_path(path: &str) -> bool {
510+
use once_cell::sync::OnceCell;
511+
use regex::Regex;
512+
513+
static REGEX: OnceCell<Regex> = OnceCell::new();
514+
let regex = REGEX.get_or_init(|| Regex::new(r"^[a-zA-Z]:\\").expect("failed to compile regex"));
515+
let has_drive_letter = regex.is_match(path);
516+
let slash_count = path.chars().filter(|&c| c == '/').count();
517+
let backslash_count = path.chars().filter(|&c| c == '\\').count();
518+
has_drive_letter && backslash_count > slash_count
519+
}
520+
507521
fn truncate_registry_path(s: String) -> String {
508522
use once_cell::sync::OnceCell;
509523
use regex::Regex;
510524
use std::borrow::Cow;
511525

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

518-
return match regex.replace(&s, "<cargo>/") {
532+
let rep = if is_windows_path(&s) {
533+
"<cargo>\\"
534+
} else {
535+
"<cargo>/"
536+
};
537+
538+
match regex.replace(&s, rep) {
519539
Cow::Owned(s) => s,
520540
// String was not modified, return the original.
521-
Cow::Borrowed(_) => s.to_string(),
522-
};
541+
Cow::Borrowed(_) => s,
542+
}
523543
}
524544

525545
fn format_location(loc: Option<proto::Location>) -> String {
@@ -586,30 +606,69 @@ mod tests {
586606
#[test]
587607
fn test_format_location_macos() {
588608
// macOS style paths.
589-
let location4 = proto::Location {
609+
let location1 = proto::Location {
590610
file: Some("/Users/user/.cargo/registry/src/gb.xjqchip.workers.dev-1ecc6299db9ec823/tokio-1.0.1/src/lib.rs".to_string()),
591611
..Default::default()
592612
};
593-
let location5 = proto::Location {
613+
let location2 = proto::Location {
594614
file: Some("/Users/user/.cargo/git/checkouts/tokio-1.0.1/src/lib.rs".to_string()),
595615
..Default::default()
596616
};
597-
let location6 = proto::Location {
617+
let location3 = proto::Location {
598618
file: Some("/Users/user/projects/tokio-1.0.1/src/lib.rs".to_string()),
599619
..Default::default()
600620
};
601621

602622
assert_eq!(
603-
format_location(Some(location4)),
623+
format_location(Some(location1)),
604624
"<cargo>/tokio-1.0.1/src/lib.rs"
605625
);
606626
assert_eq!(
607-
format_location(Some(location5)),
627+
format_location(Some(location2)),
608628
"<cargo>/tokio-1.0.1/src/lib.rs"
609629
);
610630
assert_eq!(
611-
format_location(Some(location6)),
631+
format_location(Some(location3)),
612632
"/Users/user/projects/tokio-1.0.1/src/lib.rs"
613633
);
614634
}
635+
636+
#[test]
637+
fn test_format_location_windows() {
638+
// Windows style paths.
639+
let location1 = proto::Location {
640+
file: Some(
641+
"C:\\Users\\user\\.cargo\\registry\\src\\gb.xjqchip.workers.dev-1ecc6299db9ec823\\tokio-1.0.1\\src\\lib.rs"
642+
.to_string(),
643+
),
644+
..Default::default()
645+
};
646+
647+
let location2 = proto::Location {
648+
file: Some(
649+
"C:\\Users\\user\\.cargo\\git\\checkouts\\tokio-1.0.1\\src\\lib.rs".to_string(),
650+
),
651+
..Default::default()
652+
};
653+
654+
let location3 = proto::Location {
655+
file: Some("C:\\Users\\user\\projects\\tokio-1.0.1\\src\\lib.rs".to_string()),
656+
..Default::default()
657+
};
658+
659+
assert_eq!(
660+
format_location(Some(location1)),
661+
"<cargo>\\tokio-1.0.1\\src\\lib.rs"
662+
);
663+
664+
assert_eq!(
665+
format_location(Some(location2)),
666+
"<cargo>\\tokio-1.0.1\\src\\lib.rs"
667+
);
668+
669+
assert_eq!(
670+
format_location(Some(location3)),
671+
"C:\\Users\\user\\projects\\tokio-1.0.1\\src\\lib.rs"
672+
);
673+
}
615674
}

0 commit comments

Comments
 (0)