From b2b75235b6e7f0e76552da23c31539cce3814330 Mon Sep 17 00:00:00 2001 From: Behnam Esfahbod Date: Wed, 12 Jul 2017 21:55:07 -0600 Subject: [PATCH] [ignore] Fix matched_path_or_any_parents() for patterns ending in slash In `matched_path_or_any_parents()` implementation, we missed the point that when we start walking up the tree, we have to set `is_dir` to `true`, so path `ROOT/a/b/c` matches pattern `/a/`, although the original path is not a dir. --- ignore/src/gitignore.rs | 14 +- ...gnore_matched_path_or_any_parents_tests.rs | 230 ++++++++++-------- 2 files changed, 140 insertions(+), 104 deletions(-) diff --git a/ignore/src/gitignore.rs b/ignore/src/gitignore.rs index b44428a37..85109559c 100644 --- a/ignore/src/gitignore.rs +++ b/ignore/src/gitignore.rs @@ -220,15 +220,17 @@ impl Gitignore { !path.has_root(), "path is expect to be under the root" ); - loop { - match self.matched_stripped(path, is_dir) { - Match::None => match path.parent() { - Some(parent) => path = parent, - None => return Match::None, - }, + match self.matched_stripped(path, is_dir) { + Match::None => (), // walk up + a_match => return a_match, + } + while let Some(parent) = path.parent() { + match self.matched_stripped(parent, /* is_dir */ true) { + Match::None => path = parent, // walk up a_match => return a_match, } } + Match::None } /// Like matched, but takes a path that has already been stripped. diff --git a/ignore/tests/gitignore_matched_path_or_any_parents_tests.rs b/ignore/tests/gitignore_matched_path_or_any_parents_tests.rs index 1b3f61842..c76ee2d1f 100644 --- a/ignore/tests/gitignore_matched_path_or_any_parents_tests.rs +++ b/ignore/tests/gitignore_matched_path_or_any_parents_tests.rs @@ -92,172 +92,206 @@ fn test_files_in_deep() { #[test] fn test_dirs_in_root() { let gitignore = get_gitignore(); - let m = |path: &str| gitignore.matched_path_or_any_parents(Path::new(path), true); + let m = + |path: &str, is_dir: bool| gitignore.matched_path_or_any_parents(Path::new(path), is_dir); // 00 - assert!(m("ROOT/dir_root_00").is_ignore()); - assert!(m("ROOT/dir_root_00/file").is_ignore()); - assert!(m("ROOT/dir_root_00/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_00", true).is_ignore()); + assert!(m("ROOT/dir_root_00/file", false).is_ignore()); + assert!(m("ROOT/dir_root_00/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_00/child_dir/file", false).is_ignore()); // 01 - assert!(m("ROOT/dir_root_01").is_ignore()); - assert!(m("ROOT/dir_root_01/file").is_ignore()); - assert!(m("ROOT/dir_root_01/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_01", true).is_ignore()); + assert!(m("ROOT/dir_root_01/file", false).is_ignore()); + assert!(m("ROOT/dir_root_01/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_01/child_dir/file", false).is_ignore()); // 02 - assert!(m("ROOT/dir_root_02").is_none()); // dir itself doesn't match - assert!(m("ROOT/dir_root_02/file").is_ignore()); - assert!(m("ROOT/dir_root_02/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_02", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/dir_root_02/file", false).is_ignore()); + assert!(m("ROOT/dir_root_02/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_02/child_dir/file", false).is_ignore()); // 03 - assert!(m("ROOT/dir_root_03").is_none()); // dir itself doesn't match - assert!(m("ROOT/dir_root_03/file").is_ignore()); - assert!(m("ROOT/dir_root_03/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_03", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/dir_root_03/file", false).is_ignore()); + assert!(m("ROOT/dir_root_03/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_03/child_dir/file", false).is_ignore()); // 10 - assert!(m("ROOT/dir_root_10").is_ignore()); - assert!(m("ROOT/dir_root_10/file").is_ignore()); - assert!(m("ROOT/dir_root_10/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_10", true).is_ignore()); + assert!(m("ROOT/dir_root_10/file", false).is_ignore()); + assert!(m("ROOT/dir_root_10/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_10/child_dir/file", false).is_ignore()); // 11 - assert!(m("ROOT/dir_root_11").is_ignore()); - assert!(m("ROOT/dir_root_11/file").is_ignore()); - assert!(m("ROOT/dir_root_11/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_11", true).is_ignore()); + assert!(m("ROOT/dir_root_11/file", false).is_ignore()); + assert!(m("ROOT/dir_root_11/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_11/child_dir/file", false).is_ignore()); // 12 - assert!(m("ROOT/dir_root_12").is_none()); // dir itself doesn't match - assert!(m("ROOT/dir_root_12/file").is_ignore()); - assert!(m("ROOT/dir_root_12/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_12", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/dir_root_12/file", false).is_ignore()); + assert!(m("ROOT/dir_root_12/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_12/child_dir/file", false).is_ignore()); // 13 - assert!(m("ROOT/dir_root_13").is_none()); - assert!(m("ROOT/dir_root_13/file").is_ignore()); - assert!(m("ROOT/dir_root_13/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_13", true).is_none()); + assert!(m("ROOT/dir_root_13/file", false).is_ignore()); + assert!(m("ROOT/dir_root_13/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_13/child_dir/file", false).is_ignore()); // 20 - assert!(m("ROOT/dir_root_20").is_none()); - assert!(m("ROOT/dir_root_20/file").is_none()); - assert!(m("ROOT/dir_root_20/child_dir/file").is_none()); + assert!(m("ROOT/dir_root_20", true).is_none()); + assert!(m("ROOT/dir_root_20/file", false).is_none()); + assert!(m("ROOT/dir_root_20/child_dir", true).is_none()); + assert!(m("ROOT/dir_root_20/child_dir/file", false).is_none()); // 21 - assert!(m("ROOT/dir_root_21").is_none()); - assert!(m("ROOT/dir_root_21/file").is_none()); - assert!(m("ROOT/dir_root_21/child_dir/file").is_none()); + assert!(m("ROOT/dir_root_21", true).is_none()); + assert!(m("ROOT/dir_root_21/file", false).is_none()); + assert!(m("ROOT/dir_root_21/child_dir", true).is_none()); + assert!(m("ROOT/dir_root_21/child_dir/file", false).is_none()); // 22 - assert!(m("ROOT/dir_root_22").is_none()); - assert!(m("ROOT/dir_root_22/file").is_none()); - assert!(m("ROOT/dir_root_22/child_dir/file").is_none()); + assert!(m("ROOT/dir_root_22", true).is_none()); + assert!(m("ROOT/dir_root_22/file", false).is_none()); + assert!(m("ROOT/dir_root_22/child_dir", true).is_none()); + assert!(m("ROOT/dir_root_22/child_dir/file", false).is_none()); // 23 - assert!(m("ROOT/dir_root_23").is_none()); - assert!(m("ROOT/dir_root_23/file").is_none()); - assert!(m("ROOT/dir_root_23/child_dir/file").is_none()); + assert!(m("ROOT/dir_root_23", true).is_none()); + assert!(m("ROOT/dir_root_23/file", false).is_none()); + assert!(m("ROOT/dir_root_23/child_dir", true).is_none()); + assert!(m("ROOT/dir_root_23/child_dir/file", false).is_none()); // 30 - assert!(m("ROOT/dir_root_30").is_ignore()); - assert!(m("ROOT/dir_root_30/file").is_ignore()); - assert!(m("ROOT/dir_root_30/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_30", true).is_ignore()); + assert!(m("ROOT/dir_root_30/file", false).is_ignore()); + assert!(m("ROOT/dir_root_30/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_30/child_dir/file", false).is_ignore()); // 31 - assert!(m("ROOT/dir_root_31").is_ignore()); - assert!(m("ROOT/dir_root_31/file").is_ignore()); - assert!(m("ROOT/dir_root_31/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_31", true).is_ignore()); + assert!(m("ROOT/dir_root_31/file", false).is_ignore()); + assert!(m("ROOT/dir_root_31/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_31/child_dir/file", false).is_ignore()); // 32 - assert!(m("ROOT/dir_root_32").is_none()); // dir itself doesn't match - assert!(m("ROOT/dir_root_32/file").is_ignore()); - assert!(m("ROOT/dir_root_32/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_32", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/dir_root_32/file", false).is_ignore()); + assert!(m("ROOT/dir_root_32/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_32/child_dir/file", false).is_ignore()); // 33 - assert!(m("ROOT/dir_root_33").is_none()); // dir itself doesn't match - assert!(m("ROOT/dir_root_33/file").is_ignore()); - assert!(m("ROOT/dir_root_33/child_dir/file").is_ignore()); + assert!(m("ROOT/dir_root_33", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/dir_root_33/file", false).is_ignore()); + assert!(m("ROOT/dir_root_33/child_dir", true).is_ignore()); + assert!(m("ROOT/dir_root_33/child_dir/file", false).is_ignore()); } #[test] fn test_dirs_in_deep() { let gitignore = get_gitignore(); - let m = |path: &str| gitignore.matched_path_or_any_parents(Path::new(path), true); + let m = + |path: &str, is_dir: bool| gitignore.matched_path_or_any_parents(Path::new(path), is_dir); // 00 - assert!(m("ROOT/parent_dir/dir_deep_00").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_00/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_00/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_00", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_00/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_00/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_00/child_dir/file", false).is_ignore()); // 01 - assert!(m("ROOT/parent_dir/dir_deep_01").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_01/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_01/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_01", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_01/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_01/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_01/child_dir/file", false).is_ignore()); // 02 - assert!(m("ROOT/parent_dir/dir_deep_02").is_none()); // dir itself doesn't match - assert!(m("ROOT/parent_dir/dir_deep_02/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_02/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_02", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/parent_dir/dir_deep_02/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_02/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_02/child_dir/file", false).is_ignore()); // 03 - assert!(m("ROOT/parent_dir/dir_deep_03").is_none()); // dir itself doesn't match - assert!(m("ROOT/parent_dir/dir_deep_03/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_03/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_03", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/parent_dir/dir_deep_03/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_03/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_03/child_dir/file", false).is_ignore()); // 10 - assert!(m("ROOT/parent_dir/dir_deep_10").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_10/file").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_10/child_dir/file").is_none()); + assert!(m("ROOT/parent_dir/dir_deep_10", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_10/file", false).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_10/child_dir", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_10/child_dir/file", false).is_none()); // 11 - assert!(m("ROOT/parent_dir/dir_deep_11").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_11/file").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_11/child_dir/file").is_none()); + assert!(m("ROOT/parent_dir/dir_deep_11", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_11/file", false).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_11/child_dir", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_11/child_dir/file", false).is_none()); // 12 - assert!(m("ROOT/parent_dir/dir_deep_12").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_12/file").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_12/child_dir/file").is_none()); + assert!(m("ROOT/parent_dir/dir_deep_12", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_12/file", false).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_12/child_dir", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_12/child_dir/file", false).is_none()); // 13 - assert!(m("ROOT/parent_dir/dir_deep_13").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_13/file").is_none()); - assert!(m("ROOT/parent_dir/dir_deep_13/child_dir/file").is_none()); + assert!(m("ROOT/parent_dir/dir_deep_13", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_13/file", false).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_13/child_dir", true).is_none()); + assert!(m("ROOT/parent_dir/dir_deep_13/child_dir/file", false).is_none()); // 20 - assert!(m("ROOT/parent_dir/dir_deep_20").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_20/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_20/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_20", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_20/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_20/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_20/child_dir/file", false).is_ignore()); // 21 - assert!(m("ROOT/parent_dir/dir_deep_21").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_21/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_21/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_21", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_21/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_21/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_21/child_dir/file", false).is_ignore()); // 22 - assert!(m("ROOT/parent_dir/dir_deep_22").is_none()); // dir itself doesn't match - assert!(m("ROOT/parent_dir/dir_deep_22/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_22/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_22", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/parent_dir/dir_deep_22/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_22/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_22/child_dir/file", false).is_ignore()); // 23 - assert!(m("ROOT/parent_dir/dir_deep_23").is_none()); // dir itself doesn't match - assert!(m("ROOT/parent_dir/dir_deep_23/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_23/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_23", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/parent_dir/dir_deep_23/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_23/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_23/child_dir/file", false).is_ignore()); // 30 - assert!(m("ROOT/parent_dir/dir_deep_30").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_30/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_30/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_30", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_30/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_30/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_30/child_dir/file", false).is_ignore()); // 31 - assert!(m("ROOT/parent_dir/dir_deep_31").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_31/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_31/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_31", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_31/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_31/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_31/child_dir/file", false).is_ignore()); // 32 - assert!(m("ROOT/parent_dir/dir_deep_32").is_none()); // dir itself doesn't match - assert!(m("ROOT/parent_dir/dir_deep_32/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_32/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_32", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/parent_dir/dir_deep_32/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_32/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_32/child_dir/file", false).is_ignore()); // 33 - assert!(m("ROOT/parent_dir/dir_deep_33").is_none()); // dir itself doesn't match - assert!(m("ROOT/parent_dir/dir_deep_33/file").is_ignore()); - assert!(m("ROOT/parent_dir/dir_deep_33/child_dir/file").is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_33", true).is_none()); // dir itself doesn't match + assert!(m("ROOT/parent_dir/dir_deep_33/file", false).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_33/child_dir", true).is_ignore()); + assert!(m("ROOT/parent_dir/dir_deep_33/child_dir/file", false).is_ignore()); }