While `//?/C:/Users/Someone/config-files` is a valid path, it's not very human friendly. Such paths are returned from `BaseDirs`. This patch formats them in the traditional way.
This commit is contained in:
committed by
GitHub
parent
38552646f4
commit
022115e237
@@ -27,7 +27,8 @@ test_script:
|
|||||||
- if [%APPVEYOR_REPO_TAG%]==[false] (
|
- if [%APPVEYOR_REPO_TAG%]==[false] (
|
||||||
cargo fmt --all -- --check &&
|
cargo fmt --all -- --check &&
|
||||||
cargo clippy --all-targets --all-features -- -D warnings &&
|
cargo clippy --all-targets --all-features -- -D warnings &&
|
||||||
cargo clippy --all-targets -- -D warnings
|
cargo clippy --all-targets -- -D warnings &&
|
||||||
|
cargo test
|
||||||
)
|
)
|
||||||
|
|
||||||
before_deploy:
|
before_deploy:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ main() {
|
|||||||
cross clippy --all-targets --all-features -- -D warnings
|
cross clippy --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
if [ ! -z $DISABLE_TESTS ]; then
|
if [ ! -z $DISABLE_TESTS ]; then
|
||||||
|
cross test
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::executor::{CommandExt, RunType};
|
use crate::executor::{CommandExt, RunType};
|
||||||
use crate::terminal::print_separator;
|
use crate::terminal::print_separator;
|
||||||
use crate::utils::which;
|
use crate::utils::{which, HumanizedPath};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -58,7 +58,7 @@ impl Git {
|
|||||||
pub fn pull<P: AsRef<Path>>(&self, path: P, run_type: RunType) -> Option<(String, bool)> {
|
pub fn pull<P: AsRef<Path>>(&self, path: P, run_type: RunType) -> Option<(String, bool)> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|
||||||
print_separator(format!("Pulling {}", path.display()));
|
print_separator(format!("Pulling {}", HumanizedPath::from(path)));
|
||||||
|
|
||||||
let git = self.git.as_ref().unwrap();
|
let git = self.git.as_ref().unwrap();
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ impl Git {
|
|||||||
}()
|
}()
|
||||||
.is_ok();
|
.is_ok();
|
||||||
|
|
||||||
Some((format!("git: {}", path.display()), success))
|
Some((format!("git: {}", HumanizedPath::from(path)), success))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
87
src/utils.rs
87
src/utils.rs
@@ -1,8 +1,8 @@
|
|||||||
use super::error::{Error, ErrorKind};
|
use super::error::{Error, ErrorKind};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fmt::Debug;
|
use std::fmt::{self, Debug};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Component, Path, PathBuf};
|
||||||
use std::process::{ExitStatus, Output};
|
use std::process::{ExitStatus, Output};
|
||||||
use which_crate;
|
use which_crate;
|
||||||
|
|
||||||
@@ -68,3 +68,86 @@ pub fn which<T: AsRef<OsStr> + Debug>(binary_name: T) -> Option<PathBuf> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `std::fmt::Display` implementation for `std::path::Path`.
|
||||||
|
///
|
||||||
|
/// This struct differs from `std::path::Display` in that in Windows it takes care of printing backslashes
|
||||||
|
/// instead of slashes and don't print the `\\?` prefix in long paths.
|
||||||
|
pub struct HumanizedPath<'a> {
|
||||||
|
path: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a Path> for HumanizedPath<'a> {
|
||||||
|
fn from(path: &'a Path) -> Self {
|
||||||
|
Self { path }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> fmt::Display for HumanizedPath<'a> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
if cfg!(windows) {
|
||||||
|
let mut iterator = self.path.components().peekable();
|
||||||
|
|
||||||
|
while let Some(component) = iterator.next() {
|
||||||
|
let mut print_seperator = iterator.peek().is_some();
|
||||||
|
|
||||||
|
match &component {
|
||||||
|
Component::Normal(c) if *c == "?" => {
|
||||||
|
print_seperator = false;
|
||||||
|
}
|
||||||
|
Component::RootDir | Component::CurDir => {
|
||||||
|
print_seperator = false;
|
||||||
|
}
|
||||||
|
Component::ParentDir => {
|
||||||
|
write!(f, "..")?;
|
||||||
|
}
|
||||||
|
Component::Prefix(p) => {
|
||||||
|
write!(f, "{}", p.as_os_str().to_string_lossy())?;
|
||||||
|
print_seperator = true;
|
||||||
|
}
|
||||||
|
Component::Normal(c) => {
|
||||||
|
write!(f, "{}", c.to_string_lossy())?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if print_seperator {
|
||||||
|
write!(f, "{}", std::path::MAIN_SEPARATOR)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
write!(f, "{}", self.path.display())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[cfg(windows)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn humanize<P: AsRef<Path>>(path: P) -> String {
|
||||||
|
format!("{}", HumanizedPath::from(path.as_ref()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_just_drive() {
|
||||||
|
assert_eq!("C:\\", humanize("C:\\"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_path() {
|
||||||
|
assert_eq!("C:\\hi", humanize("C:\\hi"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unc() {
|
||||||
|
assert_eq!("\\\\server\\share\\", humanize("\\\\server\\share"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_long_path() {
|
||||||
|
assert_eq!("C:\\hi", humanize("//?/C:/hi"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user