Commit f9fbe7b6 authored by Jochen Eisinger's avatar Jochen Eisinger Committed by Commit Bot

Add presubmit check for set noparent rules

Bug: 1018108
Change-Id: I5d86962e4dcdd3a95058efef86735a11a75ac8c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1908531
Commit-Queue: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716096}
parent c975bcfd
......@@ -3073,6 +3073,71 @@ def _CheckIpcOwners(input_api, output_api):
return results
def _CheckSetNoParent(input_api, output_api):
"""Checks that set noparent is only used together with an OWNERS file in
//build/OWNERS.setnoparent (see also
//docs/code_reviews.md#owners-files-details)
"""
errors = []
allowed_owners_files_file = 'build/OWNERS.setnoparent'
allowed_owners_files = set()
with open(allowed_owners_files_file, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
allowed_owners_files.add(line)
per_file_pattern = input_api.re.compile('per-file (.+)=(.+)')
for f in input_api.AffectedFiles(include_deletes=False):
if not f.LocalPath().endswith('OWNERS'):
continue
found_owners_files = set()
found_set_noparent_lines = dict()
# Parse the OWNERS file.
for lineno, line in enumerate(f.NewContents(), 1):
line = line.strip()
if line.startswith('set noparent'):
found_set_noparent_lines[''] = lineno
if line.startswith('file://'):
if line in allowed_owners_files:
found_owners_files.add('')
if line.startswith('per-file'):
match = per_file_pattern.match(line)
if match:
glob = match.group(1).strip()
directive = match.group(2).strip()
if directive == 'set noparent':
found_set_noparent_lines[glob] = lineno
if directive.startswith('file://'):
if directive in allowed_owners_files:
found_owners_files.add(glob)
# Check that every set noparent line has a corresponding file:// line
# listed in build/OWNERS.setnoparent.
for set_noparent_line in found_set_noparent_lines:
if set_noparent_line in found_owners_files:
continue
errors.append(' %s:%d' % (f.LocalPath(),
found_set_noparent_lines[set_noparent_line]))
results = []
if errors:
if input_api.is_committing:
output = output_api.PresubmitError
else:
output = output_api.PresubmitPromptWarning
results.append(output(
'Found the following "set noparent" restrictions in OWNERS files that '
'do not include owners from build/OWNERS.setnoparent:',
long_text='\n\n'.join(errors)))
return results
def _CheckUselessForwardDeclarations(input_api, output_api):
"""Checks that added or removed lines in non third party affected
header files do not lead to new useless class or struct forward
......@@ -4192,6 +4257,7 @@ def _CommonChecks(input_api, output_api):
results.extend(_CheckPydepsNeedsUpdating(input_api, output_api))
results.extend(_CheckJavaStyle(input_api, output_api))
results.extend(_CheckIpcOwners(input_api, output_api))
results.extend(_CheckSetNoParent(input_api, output_api))
results.extend(_CheckUselessForwardDeclarations(input_api, output_api))
results.extend(_CheckForRelativeIncludes(input_api, output_api))
results.extend(_CheckForCcIncludes(input_api, output_api))
......
......@@ -2747,5 +2747,40 @@ class CheckFuzzTargetsTest(unittest.TestCase):
self.assertEqual(results[0].items, ['fuzzer.cc'])
class SetNoParentTest(unittest.TestCase):
def testSetNoParentMissing(self):
mock_input_api = MockInputApi()
mock_input_api.files = [
MockAffectedFile('goat/OWNERS',
[
'set noparent',
'jochen@chromium.org',
'per-file *.json=set noparent',
'per-file *.json=jochen@chromium.org',
])
]
mock_output_api = MockOutputApi()
errors = PRESUBMIT._CheckSetNoParent(mock_input_api, mock_output_api)
self.assertEqual(1, len(errors))
self.assertTrue('goat/OWNERS:1' in errors[0].long_text)
self.assertTrue('goat/OWNERS:3' in errors[0].long_text)
def testSetNoParentWithCorrectRule(self):
mock_input_api = MockInputApi()
mock_input_api.files = [
MockAffectedFile('goat/OWNERS',
[
'set noparent',
'file://ipc/SECURITY_OWNERS',
'per-file *.json=set noparent',
'per-file *.json=file://ipc/SECURITY_OWNERS',
])
]
mock_output_api = MockOutputApi()
errors = PRESUBMIT._CheckSetNoParent(mock_input_api, mock_output_api)
self.assertEqual([], errors)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment