
Bug: 1212040 Change-Id: Ia7600f8e3da825591d7c4a277e583d9dc6a89026 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2957342 Commit-Queue: Mark Cogan <marq@chromium.org> Auto-Submit: Josip Sokcevic <sokcevic@google.com> Reviewed-by: Mark Cogan <marq@chromium.org> Cr-Commit-Position: refs/heads/master@{#892008}
116 lines
3.7 KiB
Python
116 lines
3.7 KiB
Python
# Copyright 2017 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""Presubmit script for ios.
|
|
|
|
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
|
|
for more details about the presubmit API built into depot_tools.
|
|
"""
|
|
|
|
import os
|
|
|
|
USE_PYTHON3 = True
|
|
|
|
NULLABILITY_PATTERN = r'(nonnull|nullable|_Nullable|_Nonnull)'
|
|
TODO_PATTERN = r'TO[D]O\(([^\)]*)\)'
|
|
CRBUG_PATTERN = r'crbug\.com/\d+$'
|
|
ARC_COMPILE_GUARD = [
|
|
'#if !defined(__has_feature) || !__has_feature(objc_arc)',
|
|
'#error "This file requires ARC support."',
|
|
'#endif',
|
|
]
|
|
|
|
def IsSubListOf(needle, hay):
|
|
"""Returns whether there is a slice of |hay| equal to |needle|."""
|
|
for i, line in enumerate(hay):
|
|
if line == needle[0]:
|
|
if needle == hay[i:i+len(needle)]:
|
|
return True
|
|
return False
|
|
|
|
def _CheckARCCompilationGuard(input_api, output_api):
|
|
""" Checks whether new objc files have proper ARC compile guards."""
|
|
files_without_headers = []
|
|
for f in input_api.AffectedFiles():
|
|
if f.Action() != 'A':
|
|
continue
|
|
|
|
_, ext = os.path.splitext(f.LocalPath())
|
|
if ext not in ('.m', '.mm'):
|
|
continue
|
|
|
|
if not IsSubListOf(ARC_COMPILE_GUARD, f.NewContents()):
|
|
files_without_headers.append(f.LocalPath())
|
|
|
|
if not files_without_headers:
|
|
return []
|
|
|
|
plural_suffix = '' if len(files_without_headers) == 1 else 's'
|
|
error_message = '\n'.join([
|
|
'Found new Objective-C implementation file%(plural)s without compile'
|
|
' guard%(plural)s. Please use the following compile guard'
|
|
':' % {'plural': plural_suffix}
|
|
] + ARC_COMPILE_GUARD + files_without_headers) + '\n'
|
|
|
|
return [output_api.PresubmitError(error_message)]
|
|
|
|
|
|
def _CheckNullabilityAnnotations(input_api, output_api):
|
|
""" Checks whether there are nullability annotations in ios code."""
|
|
nullability_regex = input_api.re.compile(NULLABILITY_PATTERN)
|
|
|
|
errors = []
|
|
for f in input_api.AffectedFiles():
|
|
for line_num, line in f.ChangedContents():
|
|
if nullability_regex.search(line):
|
|
errors.append('%s:%s' % (f.LocalPath(), line_num))
|
|
if not errors:
|
|
return []
|
|
|
|
plural_suffix = '' if len(errors) == 1 else 's'
|
|
error_message = ('Found Nullability annotation%(plural)s. '
|
|
'Prefer DCHECKs in ios code to check for nullness:'
|
|
% {'plural': plural_suffix})
|
|
|
|
return [output_api.PresubmitPromptWarning(error_message, items=errors)]
|
|
|
|
|
|
def _CheckBugInToDo(input_api, output_api):
|
|
""" Checks whether TODOs in ios code are identified by a bug number."""
|
|
errors = []
|
|
for f in input_api.AffectedFiles():
|
|
for line_num, line in f.ChangedContents():
|
|
if _HasToDoWithNoBug(input_api, line):
|
|
errors.append('%s:%s' % (f.LocalPath(), line_num))
|
|
if not errors:
|
|
return []
|
|
|
|
plural_suffix = '' if len(errors) == 1 else 's'
|
|
error_message = '\n'.join([
|
|
'Found TO''DO%(plural)s without bug number%(plural)s (expected format is '
|
|
'\"TO''DO(crbug.com/######)\":' % {'plural': plural_suffix}
|
|
] + errors) + '\n'
|
|
|
|
return [output_api.PresubmitError(error_message)]
|
|
|
|
|
|
def _HasToDoWithNoBug(input_api, line):
|
|
""" Returns True if TODO is not identified by a bug number."""
|
|
todo_regex = input_api.re.compile(TODO_PATTERN)
|
|
crbug_regex = input_api.re.compile(CRBUG_PATTERN)
|
|
|
|
todo_match = todo_regex.search(line)
|
|
if not todo_match:
|
|
return False
|
|
crbug_match = crbug_regex.match(todo_match.group(1))
|
|
return not crbug_match
|
|
|
|
|
|
def CheckChangeOnUpload(input_api, output_api):
|
|
results = []
|
|
results.extend(_CheckBugInToDo(input_api, output_api))
|
|
results.extend(_CheckNullabilityAnnotations(input_api, output_api))
|
|
results.extend(_CheckARCCompilationGuard(input_api, output_api))
|
|
return results
|