diff --git a/doc/fd.1 b/doc/fd.1 index 613edc9..11efe85 100644 --- a/doc/fd.1 +++ b/doc/fd.1 @@ -33,7 +33,7 @@ Include hidden files and directories in the search results. Do not respect files like .I .gitignore and -.I .ignore +.I .fdignore and include ignored files in the search results. .TP .B \-\-no\-ignore\-vcs diff --git a/src/internal.rs b/src/internal.rs index fe9a43d..172e32b 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -30,11 +30,11 @@ pub struct FdOptions { /// Whether to ignore hidden files and directories (or not). pub ignore_hidden: bool, - /// Whether to respect ignore files (`.gitignore`, `.ignore`, ..) or not. - pub read_ignore: bool, + /// Whether to respect `.fdignore` files or not. + pub read_fdignore: bool, /// Whether to respect VCS ignore files (`.gitignore`, ..) or not. - pub read_gitignore: bool, + pub read_vcsignore: bool, /// Whether to follow symlinks or not. pub follow_links: bool, diff --git a/src/main.rs b/src/main.rs index fc03583..e40e730 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,9 +120,9 @@ fn main() { search_full_path: matches.is_present("full-path"), ignore_hidden: !(matches.is_present("hidden") || matches.occurrences_of("rg-alias-hidden-ignore") >= 2), - read_ignore: !(matches.is_present("no-ignore") + read_fdignore: !(matches.is_present("no-ignore") || matches.is_present("rg-alias-hidden-ignore")), - read_gitignore: !(matches.is_present("no-ignore") + read_vcsignore: !(matches.is_present("no-ignore") || matches.is_present("rg-alias-hidden-ignore") || matches.is_present("no-ignore-vcs")), follow_links: matches.is_present("follow"), diff --git a/src/walk.rs b/src/walk.rs index ac71fa9..a1d32e2 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -71,15 +71,19 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc, config: Arc) { let mut walker = WalkBuilder::new(first_path_buf.as_path()); walker .hidden(config.ignore_hidden) - .ignore(config.read_ignore) - .git_ignore(config.read_gitignore) - .parents(config.read_ignore || config.read_gitignore) - .git_global(config.read_gitignore) - .git_exclude(config.read_gitignore) + .ignore(false) + .parents(config.read_fdignore || config.read_vcsignore) + .git_ignore(config.read_vcsignore) + .git_global(config.read_vcsignore) + .git_exclude(config.read_vcsignore) .overrides(overrides) .follow_links(config.follow_links) .max_depth(config.max_depth); + if config.read_fdignore { + walker.add_custom_ignore_filename(".fdignore"); + } + for path_entry in path_iter { walker.add(path_entry.as_path()); } diff --git a/tests/testenv/mod.rs b/tests/testenv/mod.rs index 1446028..b3c9c72 100644 --- a/tests/testenv/mod.rs +++ b/tests/testenv/mod.rs @@ -60,7 +60,7 @@ fn create_working_directory( #[cfg(windows)] windows::fs::symlink_dir(root.join("one/two"), root.join("symlink"))?; - fs::File::create(root.join(".ignore"))?.write_all(b"ignored.foo")?; + fs::File::create(root.join(".fdignore"))?.write_all(b"fdignored.foo")?; fs::File::create(root.join(".gitignore"))?.write_all(b"gitignored.foo")?; } diff --git a/tests/tests.rs b/tests/tests.rs index 4259c1a..084683a 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -14,6 +14,8 @@ mod testenv; use testenv::TestEnv; use regex::escape; +use std::fs; +use std::io::Write; static DEFAULT_DIRS: &'static [&'static str] = &["one/two/three", "one/two/three/directory_foo"]; @@ -23,7 +25,7 @@ static DEFAULT_FILES: &'static [&'static str] = &[ "one/two/c.foo", "one/two/C.Foo2", "one/two/three/d.foo", - "ignored.foo", + "fdignored.foo", "gitignored.foo", ".hidden.foo", "e1 e2", @@ -272,7 +274,7 @@ fn test_no_ignore() { te.assert_output( &["--no-ignore", "foo"], "a.foo - ignored.foo + fdignored.foo gitignored.foo one/b.foo one/two/c.foo @@ -285,7 +287,7 @@ fn test_no_ignore() { &["--hidden", "--no-ignore", "foo"], ".hidden.foo a.foo - ignored.foo + fdignored.foo gitignored.foo one/b.foo one/two/c.foo @@ -295,6 +297,70 @@ fn test_no_ignore() { ); } +/// Custom ignore files +#[test] +fn test_custom_ignore() { + let files = &[ + "ignored-by-nothing", + "ignored-by-fdignore", + "ignored-by-gitignore", + "ignored-by-both", + ]; + let te = TestEnv::new(&[], files); + + fs::File::create(te.test_root().join(".fdignore")) + .unwrap() + .write_all(b"ignored-by-fdignore\nignored-by-both") + .unwrap(); + + fs::File::create(te.test_root().join(".gitignore")) + .unwrap() + .write_all(b"ignored-by-gitignore\nignored-by-both") + .unwrap(); + + te.assert_output(&["ignored"], "ignored-by-nothing"); + + te.assert_output( + &["--no-ignore-vcs", "ignored"], + "ignored-by-nothing + ignored-by-gitignore", + ); + + te.assert_output( + &["--no-ignore", "ignored"], + "ignored-by-nothing + ignored-by-fdignore + ignored-by-gitignore + ignored-by-both", + ); +} + +/// Precedence of custom ignore files +#[test] +fn test_custom_ignore_precedence() { + let dirs = &["inner"]; + let files = &["inner/foo"]; + let te = TestEnv::new(dirs, files); + + // Ignore 'foo' via .gitignore + fs::File::create(te.test_root().join("inner/.gitignore")) + .unwrap() + .write_all(b"foo") + .unwrap(); + + // Whitelist 'foo' via .fdignore + fs::File::create(te.test_root().join(".fdignore")) + .unwrap() + .write_all(b"!foo") + .unwrap(); + + te.assert_output(&["foo"], "inner/foo"); + + te.assert_output(&["--no-ignore-vcs", "foo"], "inner/foo"); + + te.assert_output(&["--no-ignore", "foo"], "inner/foo"); +} + /// VCS ignored files (--no-ignore-vcs) #[test] fn test_no_ignore_vcs() { @@ -320,7 +386,7 @@ fn test_no_ignore_aliases() { te.assert_output( &["-u", "foo"], "a.foo - ignored.foo + fdignored.foo gitignored.foo one/b.foo one/two/c.foo @@ -333,7 +399,7 @@ fn test_no_ignore_aliases() { &["-uu", "foo"], ".hidden.foo a.foo - ignored.foo + fdignored.foo gitignored.foo one/b.foo one/two/c.foo