Enhanced Windows support, see #70

* Use easier way to convert path components
* Fix failing tests on Windows
This commit is contained in:
David Peter 2017-10-07 09:40:44 +02:00 committed by GitHub
parent a84536a173
commit 4731dc670c
4 changed files with 24 additions and 19 deletions

View File

@ -1,4 +1,5 @@
use std::path::{Path, PathBuf};
use std::io;
/// Get a relative path with respect to a certain base path.
/// See: https://stackoverflow.com/a/39343127/704831
@ -41,3 +42,12 @@ pub fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
Some(comps.iter().map(|c| c.as_os_str()).collect())
}
}
pub fn absolute_path(path: &Path) -> io::Result<PathBuf> {
let path_buf = path.canonicalize()?;
#[cfg(windows)]
let path_buf = Path::new(path_buf.as_path().to_string_lossy().trim_left_matches(r"\\?\")).to_path_buf();
Ok(path_buf)
}

View File

@ -10,14 +10,13 @@ pub mod lscolors;
pub mod fshelper;
mod app;
use std::borrow::Cow;
use std::env;
use std::error::Error;
use std::io::Write;
use std::ops::Deref;
#[cfg(target_family = "unix")]
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::path::{Component, Path, PathBuf};
use std::path::{Path, PathBuf};
use std::process;
use std::sync::Arc;
use std::sync::mpsc::channel;
@ -111,10 +110,11 @@ enum ReceiverMode {
}
/// Root directory
#[cfg(unix)]
static ROOT_DIR: &'static str = "/";
/// Parent directory
static PARENT_DIR: &'static str = "..";
#[cfg(windows)]
static ROOT_DIR: &'static str = "";
/// Print a search result to the console.
fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
@ -122,13 +122,13 @@ fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
let path_str = entry.to_string_lossy();
#[cfg(target_family = "unix")]
#[cfg(unix)]
let is_executable = |p: Option<&std::fs::Metadata>| {
p.map(|f| f.permissions().mode() & 0o111 != 0)
.unwrap_or(false)
};
#[cfg(not(target_family = "unix"))]
#[cfg(windows)]
let is_executable = |_: Option<&std::fs::Metadata>| false;
let stdout = std::io::stdout();
@ -145,11 +145,7 @@ fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
// Traverse the path and colorize each component
for component in entry.components() {
let comp_str = match component {
Component::Normal(p) => p.to_string_lossy(),
Component::ParentDir => Cow::from(PARENT_DIR),
_ => error("Error: unexpected path component.")
};
let comp_str = component.as_os_str().to_string_lossy();
component_path.push(Path::new(comp_str.deref()));
@ -373,7 +369,7 @@ fn main() {
root_dir_is_absolute = path.is_absolute();
path.canonicalize().unwrap_or_else(
fshelper::absolute_path(path).unwrap_or_else(
|_| error(&format!("Error: could not find directory '{}'.", rd))
)
} else {

View File

@ -47,6 +47,8 @@ fn create_working_directory() -> Result<TempDir, io::Error> {
#[cfg(unix)]
unix::fs::symlink(root.join("one/two"), root.join("symlink"))?;
// Note: creating symlinks on Windows requires the `SeCreateSymbolicLinkPrivilege` which
// is by default only granted for administrators.
#[cfg(windows)]
windows::fs::symlink_dir(root.join("one/two"), root.join("symlink"))?;

View File

@ -1,7 +1,5 @@
//! Integration tests for the CLI interface of fd.
#![allow(dead_code, unused_imports)]
mod testenv;
use testenv::TestEnv;
@ -39,8 +37,6 @@ fn test_simple() {
}
/// Explicit root path
// TODO: Fails on windows
#[cfg_attr(windows, ignore)]
#[test]
fn test_explicit_root_path() {
let te = TestEnv::new();
@ -239,8 +235,6 @@ fn test_max_depth() {
}
/// Absolute paths (--absolute-path)
// TODO: fails on windows
#[cfg_attr(windows, ignore)]
#[test]
fn test_absolute_path() {
let te = TestEnv::new();
@ -250,6 +244,9 @@ fn test_absolute_path() {
.to_str().expect("string")
.to_string();
#[cfg(windows)]
let abs_path = abs_path.trim_left_matches(r"\\?\");
te.assert_output(
&["--absolute-path", "foo"],
&format!(