From b15e6c1a0e827e9421f77cba03ac689d95bbfcb2 Mon Sep 17 00:00:00 2001 From: Martins Sipenko Date: Tue, 28 Jun 2022 11:46:45 +0300 Subject: [PATCH 1/3] Added support for consecutive asterisks --- src/PatternMatcher.php | 2 ++ tests/Fixtures/CODEOWNERS.example | 16 ++++++++++++++++ tests/ParserTest.php | 6 ++++++ tests/PatternMatcherTest.php | 5 +++++ 4 files changed, 29 insertions(+) diff --git a/src/PatternMatcher.php b/src/PatternMatcher.php index 0f2b1bf..617d52a 100644 --- a/src/PatternMatcher.php +++ b/src/PatternMatcher.php @@ -62,6 +62,8 @@ private function isMatch(Pattern $pattern, string $filename): bool '*' => '[^\/]+', '?' => '[^\/]', '**' => '.*', + '/**' => '.*', + '**/' => '.*', '/**/' => '\/([^\/]+\/)*', ]; diff --git a/tests/Fixtures/CODEOWNERS.example b/tests/Fixtures/CODEOWNERS.example index 1ab69af..1bbb254 100644 --- a/tests/Fixtures/CODEOWNERS.example +++ b/tests/Fixtures/CODEOWNERS.example @@ -38,6 +38,22 @@ apps/ @octocat # directory in the root of your repository. /docs/ @doctocat +# A leading "**" followed by a slash means match in all directories. +# For example, "**/foo" matches file or directory "foo" anywhere, +# the same as pattern "foo". "**/foo/bar" matches file or directory +# "bar" anywhere that is directly under directory "foo". +**/foo @doctocat + +# A trailing "/**" matches everything inside. +# For example, "abc/**" matches all files inside directory "abc" +# with infinite depth. +abc/** @doctocat + +# A slash followed by two consecutive asterisks then a slash ma +# zero or more directories. For example, "a/**/b" matches "a/b", +# "a/x/b", "a/x/y/b" and so on. +a/**/b @doctocat + # In this example nobody owns the files # This line should be ignored by the parser. /src diff --git a/tests/ParserTest.php b/tests/ParserTest.php index 04cd26f..9aeca64 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -51,6 +51,9 @@ public function testParsingResultsInPatterns() new Pattern('docs/*', ['docs@example.com']), new Pattern('apps/', ['@octocat']), new Pattern('/docs/', ['@doctocat']), + new Pattern('**/foo', ['@doctocat']), + new Pattern('abc/**', ['@doctocat']), + new Pattern('a/**/b', ['@doctocat']), ], $patterns); } @@ -66,6 +69,9 @@ public function testParsingStringResultsInPatterns() new Pattern('docs/*', ['docs@example.com']), new Pattern('apps/', ['@octocat']), new Pattern('/docs/', ['@doctocat']), + new Pattern('**/foo', ['@doctocat']), + new Pattern('abc/**', ['@doctocat']), + new Pattern('a/**/b', ['@doctocat']), ], $patterns); } } diff --git a/tests/PatternMatcherTest.php b/tests/PatternMatcherTest.php index bf8b4a3..6a72b97 100644 --- a/tests/PatternMatcherTest.php +++ b/tests/PatternMatcherTest.php @@ -66,6 +66,11 @@ public function provideCorrectMatchIsReturnedForFilename(): array // does NOT match "foo/bar/file.ext" // ** + [new Pattern('**/c', ['@owner']), 'a/c'], + [new Pattern('**/c', ['@owner']), 'b/c'], + [new Pattern('**/c', ['@owner']), 'a/b/c'], + [new Pattern('a/**', ['@owner']), 'a/b'], + [new Pattern('a/**', ['@owner']), 'a/b/c'], [new Pattern('a/**/b', ['@owner']), 'a/b'], [new Pattern('a/**/b', ['@owner']), 'a/x/b'], [new Pattern('a/**/b', ['@owner']), 'a/x/y/b'], From 1042e3e18f1ee5b476faca9ced86bb72ce9909fe Mon Sep 17 00:00:00 2001 From: Martins Sipenko Date: Wed, 29 Jun 2022 10:43:37 +0300 Subject: [PATCH 2/3] Changes from PR feedback --- src/PatternMatcher.php | 2 +- tests/PatternMatcherTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PatternMatcher.php b/src/PatternMatcher.php index 617d52a..7e051ba 100644 --- a/src/PatternMatcher.php +++ b/src/PatternMatcher.php @@ -62,7 +62,7 @@ private function isMatch(Pattern $pattern, string $filename): bool '*' => '[^\/]+', '?' => '[^\/]', '**' => '.*', - '/**' => '.*', + '/**' => '\/.*', '**/' => '.*', '/**/' => '\/([^\/]+\/)*', ]; diff --git a/tests/PatternMatcherTest.php b/tests/PatternMatcherTest.php index 6a72b97..9212f27 100644 --- a/tests/PatternMatcherTest.php +++ b/tests/PatternMatcherTest.php @@ -131,6 +131,10 @@ public function provideNoMatchFoundExceptionIsThrownForFilename(): array [new Pattern('*.ext', ['@owner']), 'fooext'], [new Pattern('*.ext', ['@owner']), 'foo/ext'], [new Pattern('foo/*', ['@owner']), 'foo/bar/file.ext'], + + // ** + [new Pattern('**/foo', ['@owner']), 'foo.ext'], + [new Pattern('foo/**', ['@owner']), 'foo.ext'], ]; } } From 588eaba29523ad47666a25ce5a01f80f5794a2b3 Mon Sep 17 00:00:00 2001 From: Martins Sipenko Date: Wed, 29 Jun 2022 16:20:18 +0300 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Timo Schinkel <31616857+timoschinkel@users.noreply.github.com> --- src/PatternMatcher.php | 2 +- tests/PatternMatcherTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PatternMatcher.php b/src/PatternMatcher.php index 7e051ba..cd00f29 100644 --- a/src/PatternMatcher.php +++ b/src/PatternMatcher.php @@ -63,7 +63,7 @@ private function isMatch(Pattern $pattern, string $filename): bool '?' => '[^\/]', '**' => '.*', '/**' => '\/.*', - '**/' => '.*', + '**/' => '.*\/', '/**/' => '\/([^\/]+\/)*', ]; diff --git a/tests/PatternMatcherTest.php b/tests/PatternMatcherTest.php index 9212f27..5572bd6 100644 --- a/tests/PatternMatcherTest.php +++ b/tests/PatternMatcherTest.php @@ -134,6 +134,7 @@ public function provideNoMatchFoundExceptionIsThrownForFilename(): array // ** [new Pattern('**/foo', ['@owner']), 'foo.ext'], + [new Pattern('**/foo', ['@owner']), 'bar-foo/file.ext'], [new Pattern('foo/**', ['@owner']), 'foo.ext'], ]; }