diff --git a/.gitignore b/.gitignore index 4536c9f..1e87a9d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ target .project .cargo .settings +test_data/links/link-f +test_data/links/link-d diff --git a/src/find/matchers/type_matcher.rs b/src/find/matchers/type_matcher.rs index 5143844..3dc0334 100644 --- a/src/find/matchers/type_matcher.rs +++ b/src/find/matchers/type_matcher.rs @@ -8,6 +8,9 @@ use std::error::Error; use std::fs::FileType; use walkdir::DirEntry; +#[cfg(unix)] +use std::os::unix::fs::FileTypeExt; + use super::{Matcher, MatcherIO}; /// This matcher checks the type of the file. @@ -17,10 +20,17 @@ pub struct TypeMatcher { impl TypeMatcher { pub fn new(type_string: &str) -> Result> { + #[cfg(unix)] let function = match type_string { "f" => FileType::is_file, "d" => FileType::is_dir, - "b" | "c" | "p" | "l" | "s" | "D" => { + "l" => FileType::is_symlink, + "b" => FileType::is_block_device, + "c" => FileType::is_char_device, + "p" => FileType::is_fifo, // named pipe (FIFO) + "s" => FileType::is_socket, + // D: door (Solaris) + "D" => { return Err(From::from(format!( "Type argument {} not supported yet", type_string @@ -33,6 +43,18 @@ impl TypeMatcher { ))) } }; + #[cfg(not(unix))] + let function = match type_string { + "f" => FileType::is_file, + "d" => FileType::is_dir, + "l" => FileType::is_symlink, + _ => { + return Err(From::from(format!( + "Unrecognised type argument {}", + type_string + ))) + } + }; Ok(TypeMatcher { file_type_fn: function, }) @@ -55,6 +77,13 @@ mod tests { use crate::find::matchers::tests::get_dir_entry_for; use crate::find::matchers::Matcher; use crate::find::tests::FakeDependencies; + use std::io::ErrorKind; + + #[cfg(unix)] + use std::os::unix::fs::symlink; + + #[cfg(windows)] + use std::os::windows::fs::{symlink_dir, symlink_file}; #[test] fn file_type_matcher() { @@ -78,6 +107,64 @@ mod tests { assert!(!matcher.matches(&file, &mut deps.new_matcher_io())); } + // git does not translate links (in test_data) to Windows links + // so we have to create links in test + #[test] + fn link_type_matcher() { + #[cfg(unix)] + let _ = { + if let Err(e) = symlink("abbbc", "test_data/links/link-f") { + if e.kind() != ErrorKind::AlreadyExists { + panic!("Failed to create sym link: {:?}", e); + } + } + if let Err(e) = symlink("subdir", "test_data/links/link-d") { + if e.kind() != ErrorKind::AlreadyExists { + panic!("Failed to create sym link: {:?}", e); + } + } + }; + #[cfg(windows)] + let _ = { + if let Err(e) = symlink_file("abbbc", "test_data/links/link-f") { + if e.kind() != ErrorKind::AlreadyExists { + panic!("Failed to create sym link: {:?}", e); + } + } + if let Err(e) = symlink_dir("subdir", "test_data/links/link-d") { + if e.kind() != ErrorKind::AlreadyExists { + panic!("Failed to create sym link: {:?}", e); + } + } + }; + + let link_f = get_dir_entry_for("test_data/links", "link-f"); + let link_d = get_dir_entry_for("test_data/links", "link-d"); + let file = get_dir_entry_for("test_data/links", "abbbc"); + let dir = get_dir_entry_for("test_data", "links"); + let deps = FakeDependencies::new(); + + let matcher = TypeMatcher::new(&"l".to_string()).unwrap(); + assert!(!matcher.matches(&dir, &mut deps.new_matcher_io())); + assert!(!matcher.matches(&file, &mut deps.new_matcher_io())); + assert!(matcher.matches(&link_f, &mut deps.new_matcher_io())); + assert!(matcher.matches(&link_d, &mut deps.new_matcher_io())); + } + + #[cfg(unix)] + #[test] + fn unix_extra_type_matcher() { + let file = get_dir_entry_for("test_data/simple", "abbbc"); + let dir = get_dir_entry_for("test_data", "simple"); + let deps = FakeDependencies::new(); + + for typ in ["b", "c", "p", "s"].iter() { + let matcher = TypeMatcher::new(&typ.to_string()).unwrap(); + assert!(!matcher.matches(&dir, &mut deps.new_matcher_io())); + assert!(!matcher.matches(&file, &mut deps.new_matcher_io())); + } + } + #[test] fn cant_create_with_invalid_pattern() { let result = TypeMatcher::new(&"xxx".to_string()); diff --git a/test_data/links/abbbc b/test_data/links/abbbc new file mode 100644 index 0000000..e69de29 diff --git a/test_data/links/subdir/test b/test_data/links/subdir/test new file mode 100644 index 0000000..e69de29