diff --git a/owners.py b/owners.py index 1dd467f6f..109273e5c 100644 --- a/owners.py +++ b/owners.py @@ -14,7 +14,7 @@ The syntax of the OWNERS file is, roughly: lines := (\s* line? \s* "\n")* line := directive - | "per-file" \s+ glob "=" directive + | "per-file" \s+ glob \s* "=" \s* directive | comment directive := "set noparent" @@ -221,8 +221,8 @@ class Database(object): m = re.match("per-file (.+)=(.+)", line) if m: - glob_string = m.group(1) - directive = m.group(2) + glob_string = m.group(1).strip() + directive = m.group(2).strip() full_glob_string = self.os_path.join(self.root, dirpath, glob_string) if '/' in glob_string or '\\' in glob_string: raise SyntaxErrorInOwnersFile(owners_path, lineno, diff --git a/tests/owners_unittest.py b/tests/owners_unittest.py index 7a544e13b..e031ab87b 100755 --- a/tests/owners_unittest.py +++ b/tests/owners_unittest.py @@ -154,6 +154,23 @@ class OwnersDatabaseTest(unittest.TestCase): [tom], ['content/baz']) + def test_per_file_with_spaces(self): + # This is the same as test_per_file(), except that we include spaces + # on the per-file line. brett isn't allowed to approve ugly.cc; + # tom is allowed to approve ugly.cc, but not froboz.h + self.files['/content/baz/OWNERS'] = owners_file(brett, + lines=['per-file ugly.* = tom@example.com']) + self.assert_dirs_not_covered_by(['content/baz/ugly.cc'], + [brett], + []) + + self.assert_dirs_not_covered_by(['content/baz/ugly.cc'], + [tom], + []) + self.assert_dirs_not_covered_by(['content/baz/froboz.h'], + [tom], + ['content/baz']) + def test_per_file__set_noparent(self): self.files['/content/baz/OWNERS'] = owners_file(brett, lines=['per-file ugly.*=tom@example.com',