0
Files
src/ppapi/PRESUBMIT.py
Tom Sepez d23993a158 Introduce new ppapi::PERMISSION_SOCKET.
Make pp:{TCP,UDP}Socket APIs require the new permission.
Grant it to all existing clients that need it for compatibility,
but do not grant it to the PDF plugin, which does not need this.

- Kill an else-after-return.
- Use make_unique<> in one place.
- Suppress include guard lint noise.
- Check CanCreateSocket() for TCP sockets, too.
- Prevent clang-format from moving indented includes to margin.

Bug: 948172
Change-Id: I9dbb9e06ec1f5e713250dfcc9414830a5aa8fc38
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1548593
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Mark Seaborn <mseaborn@chromium.org>
Reviewed-by: Nico Weber <thakis@chromium.org>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#647891}
2019-04-04 20:27:31 +00:00

347 lines
12 KiB
Python

# Copyright (c) 2012 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.
import os
import re
import sys
import subprocess
def RunCmdAndCheck(cmd, err_string, output_api, cwd=None, warning=False):
results = []
p = subprocess.Popen(cmd, cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(p_stdout, p_stderr) = p.communicate()
if p.returncode:
if warning:
results.append(output_api.PresubmitPromptWarning(
'%s\n\n%s' % (err_string, p_stderr)))
else:
results.append(
output_api.PresubmitError(err_string,
long_text=p_stderr))
return results
def RunUnittests(input_api, output_api):
# Run some Generator unittests if the generator source was changed.
results = []
files = input_api.LocalPaths()
generator_files = []
for filename in files:
name_parts = filename.split(os.sep)
if name_parts[0:2] == ['ppapi', 'generators']:
generator_files.append(filename)
if generator_files != []:
cmd = [ sys.executable, 'idl_tests.py']
ppapi_dir = input_api.PresubmitLocalPath()
results.extend(RunCmdAndCheck(cmd,
'PPAPI IDL unittests failed.',
output_api,
os.path.join(ppapi_dir, 'generators')))
return results
# Verify that the files do not contain a 'TODO' in them.
RE_TODO = re.compile(r'\WTODO\W', flags=re.I)
def CheckTODO(input_api, output_api):
live_files = input_api.AffectedFiles(include_deletes=False)
files = [f.LocalPath() for f in live_files]
todo = []
for filename in files:
name, ext = os.path.splitext(filename)
name_parts = name.split(os.sep)
# Only check normal build sources.
if ext not in ['.h', '.idl']:
continue
# Only examine the ppapi directory.
if name_parts[0] != 'ppapi':
continue
# Only examine public plugin facing directories.
if name_parts[1] not in ['api', 'c', 'cpp', 'utility']:
continue
# Only examine public stable interfaces.
if name_parts[2] in ['dev', 'private', 'trusted']:
continue
filepath = os.path.join('..', filename)
if RE_TODO.search(open(filepath, 'rb').read()):
todo.append(filename)
if todo:
return [output_api.PresubmitError(
'TODOs found in stable public PPAPI files:',
long_text='\n'.join(todo))]
return []
# Verify that no CPP wrappers use un-versioned PPB interface name macros.
RE_UNVERSIONED_PPB = re.compile(r'\bPPB_\w+_INTERFACE\b')
def CheckUnversionedPPB(input_api, output_api):
live_files = input_api.AffectedFiles(include_deletes=False)
files = [f.LocalPath() for f in live_files]
todo = []
for filename in files:
name, ext = os.path.splitext(filename)
name_parts = name.split(os.sep)
# Only check C++ sources.
if ext not in ['.cc']:
continue
# Only examine the public plugin facing ppapi/cpp directory.
if name_parts[0:2] != ['ppapi', 'cpp']:
continue
# Only examine public stable and trusted interfaces.
if name_parts[2] in ['dev', 'private']:
continue
filepath = os.path.join('..', filename)
if RE_UNVERSIONED_PPB.search(open(filepath, 'rb').read()):
todo.append(filename)
if todo:
return [output_api.PresubmitError(
'Unversioned PPB interface references found in PPAPI C++ wrappers:',
long_text='\n'.join(todo))]
return []
# Verify that changes to ppapi headers/sources are also made to NaCl SDK.
def CheckUpdatedNaClSDK(input_api, output_api):
files = input_api.LocalPaths()
# PPAPI files the Native Client SDK cares about.
nacl_sdk_files = []
for filename in files:
name, ext = os.path.splitext(filename)
name_parts = name.split(os.sep)
if len(name_parts) <= 2:
continue
if name_parts[0] != 'ppapi':
continue
if ((name_parts[1] == 'c' and ext == '.h') or
(name_parts[1] in ('cpp', 'utility') and ext in ('.h', '.cc'))):
if name_parts[2] in ('documentation', 'trusted'):
continue
nacl_sdk_files.append(filename)
if not nacl_sdk_files:
return []
verify_ppapi_py = os.path.join(input_api.change.RepositoryRoot(),
'native_client_sdk', 'src', 'build_tools',
'verify_ppapi.py')
cmd = [sys.executable, verify_ppapi_py] + nacl_sdk_files
return RunCmdAndCheck(cmd,
'PPAPI Interface modified without updating NaCl SDK.\n'
'(note that some dev interfaces should not be added '
'the NaCl SDK; when in doubt, ask a ppapi OWNER.\n'
'To ignore a file, add it to IGNORED_FILES in '
'native_client_sdk/src/build_tools/verify_ppapi.py)',
output_api,
warning=True)
# Verify that changes to ppapi/thunk/interfaces_* files have a corresponding
# change to tools/metrics/histograms/enums.xml for UMA tracking.
def CheckHistogramXml(input_api, output_api):
# We can't use input_api.LocalPaths() here because we need to know about
# changes outside of ppapi/. See tools/depot_tools/presubmit_support.py for
# details on input_api.
files = input_api.change.AffectedFiles()
INTERFACE_FILES = ('ppapi/thunk/interfaces_legacy.h',
'ppapi/thunk/interfaces_ppb_private_flash.h',
'ppapi/thunk/interfaces_ppb_private.h',
'ppapi/thunk/interfaces_ppb_private_no_permissions.h',
'ppapi/thunk/interfaces_ppb_public_dev_channel.h',
'ppapi/thunk/interfaces_ppb_public_dev.h',
'ppapi/thunk/interfaces_ppb_public_stable.h',
'ppapi/thunk/interfaces_ppb_public_socket.h')
HISTOGRAM_XML_FILE = 'tools/metrics/histograms/enums.xml'
interface_changes = []
has_histogram_xml_change = False
for filename in files:
path = filename.LocalPath()
if path in INTERFACE_FILES:
interface_changes.append(path)
if path == HISTOGRAM_XML_FILE:
has_histogram_xml_change = True
if interface_changes and not has_histogram_xml_change:
return [output_api.PresubmitNotifyResult(
'Missing change to tools/metrics/histograms/enums.xml.\n' +
'Run pepper_hash_for_uma to make get values for new interfaces.\n' +
'Interface changes:\n' + '\n'.join(interface_changes))]
return []
def CheckChange(input_api, output_api):
results = []
results.extend(RunUnittests(input_api, output_api))
results.extend(CheckTODO(input_api, output_api))
results.extend(CheckUnversionedPPB(input_api, output_api))
results.extend(CheckUpdatedNaClSDK(input_api, output_api))
results.extend(CheckHistogramXml(input_api, output_api))
# Verify all modified *.idl have a matching *.h
files = input_api.LocalPaths()
h_files = []
idl_files = []
generators_changed = False
# These are autogenerated by the command buffer generator, they don't go
# through idl.
whitelist = ['ppb_opengles2', 'ppb_opengles2ext_dev']
# The PDF interface is hand-written.
whitelist += ['ppb_pdf', 'ppp_pdf']
# Find all relevant .h and .idl files.
for filename in files:
name, ext = os.path.splitext(filename)
name_parts = name.split(os.sep)
if name_parts[-1] in whitelist:
continue
if name_parts[0:2] == ['ppapi', 'c'] and ext == '.h':
h_files.append('/'.join(name_parts[2:]))
elif name_parts[0:2] == ['ppapi', 'api'] and ext == '.idl':
idl_files.append('/'.join(name_parts[2:]))
elif name_parts[0:2] == ['ppapi', 'generators']:
generators_changed = True
# Generate a list of all appropriate *.h and *.idl changes in this CL.
both = h_files + idl_files
# If there aren't any, we are done checking.
if not both: return results
missing = []
for filename in idl_files:
if filename not in set(h_files):
missing.append('ppapi/api/%s.idl' % filename)
# An IDL change that includes [generate_thunk] doesn't need to have
# an update to the corresponding .h file.
new_thunk_files = []
for filename in missing:
lines = input_api.RightHandSideLines(lambda f: f.LocalPath() == filename)
for line in lines:
if line[2].strip() == '[generate_thunk]':
new_thunk_files.append(filename)
for filename in new_thunk_files:
missing.remove(filename)
if missing:
results.append(
output_api.PresubmitPromptWarning(
'Missing PPAPI header, no change or skipped generation?',
long_text='\n '.join(missing)))
missing_dev = []
missing_stable = []
missing_priv = []
for filename in h_files:
if filename not in set(idl_files):
name_parts = filename.split(os.sep)
if name_parts[-1] == 'pp_macros':
# The C header generator adds a PPAPI_RELEASE macro based on all the
# IDL files, so pp_macros.h may change while its IDL does not.
lines = input_api.RightHandSideLines(
lambda f: f.LocalPath() == 'ppapi/c/%s.h' % filename)
releaseChanged = False
for line in lines:
if line[2].split()[:2] == ['#define', 'PPAPI_RELEASE']:
results.append(
output_api.PresubmitPromptOrNotify(
'PPAPI_RELEASE has changed', long_text=line[2]))
releaseChanged = True
break
if releaseChanged:
continue
if 'trusted' in name_parts:
missing_priv.append(' ppapi/c/%s.h' % filename)
continue
if 'private' in name_parts:
missing_priv.append(' ppapi/c/%s.h' % filename)
continue
if 'dev' in name_parts:
missing_dev.append(' ppapi/c/%s.h' % filename)
continue
missing_stable.append(' ppapi/c/%s.h' % filename)
if missing_priv:
results.append(
output_api.PresubmitPromptWarning(
'Missing PPAPI IDL for private interface, please generate IDL:',
long_text='\n'.join(missing_priv)))
if missing_dev:
results.append(
output_api.PresubmitPromptWarning(
'Missing PPAPI IDL for DEV, required before moving to stable:',
long_text='\n'.join(missing_dev)))
if missing_stable:
# It might be okay that the header changed without a corresponding IDL
# change. E.g., comment indenting may have been changed. Treat this as a
# warning.
if generators_changed:
results.append(
output_api.PresubmitPromptWarning(
'Missing PPAPI IDL for stable interface (due to change in ' +
'generators?):',
long_text='\n'.join(missing_stable)))
else:
results.append(
output_api.PresubmitError(
'Missing PPAPI IDL for stable interface:',
long_text='\n'.join(missing_stable)))
# Verify all *.h files match *.idl definitions, use:
# --test to prevent output to disk
# --diff to generate a unified diff
# --out to pick which files to examine (only the ones in the CL)
ppapi_dir = input_api.PresubmitLocalPath()
cmd = [sys.executable, 'generator.py',
'--wnone', '--diff', '--test','--cgen', '--range=start,end']
# Only generate output for IDL files references (as *.h or *.idl) in this CL
cmd.append('--out=' + ','.join([name + '.idl' for name in both]))
cmd_results = RunCmdAndCheck(cmd,
'PPAPI IDL Diff detected: Run the generator.',
output_api,
os.path.join(ppapi_dir, 'generators'))
if cmd_results:
results.extend(cmd_results)
return results
def CheckChangeOnUpload(input_api, output_api):
return CheckChange(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return CheckChange(input_api, output_api)