15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def RunCmdAndCheck(cmd, err_string, output_api, cwd=None):
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results = []
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  p = subprocess.Popen(cmd, cwd=cwd,
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       stdout=subprocess.PIPE,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       stderr=subprocess.PIPE)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (p_stdout, p_stderr) = p.communicate()
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if p.returncode:
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.append(
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output_api.PresubmitError(err_string,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  long_text=p_stderr))
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return results
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def RunUnittests(input_api, output_api):
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Run some Generator unittests if the generator source was changed.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results = []
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  files = input_api.LocalPaths()
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator_files = []
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for filename in files:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_parts = filename.split(os.sep)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[0:2] == ['ppapi', 'generators']:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      generator_files.append(filename)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if generator_files != []:
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cmd = [ sys.executable, 'idl_tests.py']
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ppapi_dir = input_api.PresubmitLocalPath()
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.extend(RunCmdAndCheck(cmd,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  'PPAPI IDL unittests failed.',
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  output_api,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  os.path.join(ppapi_dir, 'generators')))
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return results
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Verify that the files do not contain a 'TODO' in them.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RE_TODO = re.compile(r'\WTODO\W', flags=re.I)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CheckTODO(input_api, output_api):
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  live_files = input_api.AffectedFiles(include_deletes=False)
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  files = [f.LocalPath() for f in live_files]
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  todo = []
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for filename in files:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name, ext = os.path.splitext(filename)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_parts = name.split(os.sep)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only check normal build sources.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ext not in ['.h', '.idl']:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only examine the ppapi directory.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[0] != 'ppapi':
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only examine public plugin facing directories.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[1] not in ['api', 'c', 'cpp', 'utility']:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only examine public stable interfaces.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[2] in ['dev', 'private', 'trusted']:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if name_parts[2] == 'extensions' and name_parts[3] == 'dev':
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filepath = os.path.join('..', filename)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if RE_TODO.search(open(filepath, 'rb').read()):
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      todo.append(filename)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if todo:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return [output_api.PresubmitError(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'TODOs found in stable public PPAPI files:',
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        long_text='\n'.join(todo))]
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return []
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Verify that no CPP wrappers use un-versioned PPB interface name macros.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RE_UNVERSIONED_PPB = re.compile(r'\bPPB_\w+_INTERFACE\b')
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CheckUnversionedPPB(input_api, output_api):
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  live_files = input_api.AffectedFiles(include_deletes=False)
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  files = [f.LocalPath() for f in live_files]
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  todo = []
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for filename in files:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name, ext = os.path.splitext(filename)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_parts = name.split(os.sep)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only check C++ sources.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ext not in ['.cc']:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only examine the public plugin facing ppapi/cpp directory.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[0:2] != ['ppapi', 'cpp']:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Only examine public stable and trusted interfaces.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[2] in ['dev', 'private']:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filepath = os.path.join('..', filename)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if RE_UNVERSIONED_PPB.search(open(filepath, 'rb').read()):
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      todo.append(filename)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if todo:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return [output_api.PresubmitError(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'Unversioned PPB interface references found in PPAPI C++ wrappers:',
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        long_text='\n'.join(todo))]
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return []
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch# Verify that changes to ppapi headers/sources are also made to NaCl SDK.
1169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochdef CheckUpdatedNaClSDK(input_api, output_api):
1179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  files = input_api.LocalPaths()
1189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  # PPAPI files the Native Client SDK cares about.
1209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  nacl_sdk_files = []
1219ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1229ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  for filename in files:
1239ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    name, ext = os.path.splitext(filename)
1249ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    name_parts = name.split(os.sep)
1259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1269ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    if len(name_parts) <= 2:
1279ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      continue
1289ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1299ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    if name_parts[0] != 'ppapi':
1309ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      continue
1319ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1329ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    if ((name_parts[1] == 'c' and ext == '.h') or
1339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch        (name_parts[1] in ('cpp', 'utility') and ext in ('.h', '.cc'))):
1349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      if name_parts[2] in ('documentation', 'trusted'):
1359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch        continue
1369ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      nacl_sdk_files.append(filename)
1379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  if not nacl_sdk_files:
1399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    return []
1409ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  verify_ppapi_py = os.path.join(input_api.change.RepositoryRoot(),
1429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                 'native_client_sdk', 'src', 'build_tools',
1439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                 'verify_ppapi.py')
1449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  cmd = [sys.executable, verify_ppapi_py] + nacl_sdk_files
1459ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  return RunCmdAndCheck(cmd,
1469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                        'PPAPI Interface modified without updating NaCl SDK.',
1479ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                        output_api)
1489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CheckChange(input_api, output_api):
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results = []
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results.extend(RunUnittests(input_api, output_api))
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results.extend(CheckTODO(input_api, output_api))
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results.extend(CheckUnversionedPPB(input_api, output_api))
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1589ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  results.extend(CheckUpdatedNaClSDK(input_api, output_api))
1599ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Verify all modified *.idl have a matching *.h
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  files = input_api.LocalPaths()
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  h_files = []
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  idl_files = []
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  generators_changed = False
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Find all relevant .h and .idl files.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for filename in files:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name, ext = os.path.splitext(filename)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_parts = name.split(os.sep)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if name_parts[0:2] == ['ppapi', 'c'] and ext == '.h':
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      h_files.append('/'.join(name_parts[2:]))
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    elif name_parts[0:2] == ['ppapi', 'api'] and ext == '.idl':
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      idl_files.append('/'.join(name_parts[2:]))
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    elif name_parts[0:2] == ['ppapi', 'generators']:
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      generators_changed = True
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Generate a list of all appropriate *.h and *.idl changes in this CL.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  both = h_files + idl_files
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # If there aren't any, we are done checking.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if not both: return results
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  missing = []
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for filename in idl_files:
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if filename not in set(h_files):
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      missing.append('ppapi/api/%s.idl' % filename)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # An IDL change that includes [generate_thunk] doesn't need to have
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # an update to the corresponding .h file.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  new_thunk_files = []
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for filename in missing:
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    lines = input_api.RightHandSideLines(lambda f: f.LocalPath() == filename)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for line in lines:
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if line[2].strip() == '[generate_thunk]':
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new_thunk_files.append(filename)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for filename in new_thunk_files:
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    missing.remove(filename)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if missing:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.append(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output_api.PresubmitPromptWarning(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'Missing PPAPI header, no change or skipped generation?',
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            long_text='\n  '.join(missing)))
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  missing_dev = []
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  missing_stable = []
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  missing_priv = []
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for filename in h_files:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if filename not in set(idl_files):
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name_parts = filename.split(os.sep)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if name_parts[-1] == 'pp_macros':
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        # The C header generator adds a PPAPI_RELEASE macro based on all the
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        # IDL files, so pp_macros.h may change while its IDL does not.
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        lines = input_api.RightHandSideLines(
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            lambda f: f.LocalPath() == 'ppapi/c/%s.h' % filename)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        releaseChanged = False
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for line in lines:
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          if line[2].split()[:2] == ['#define', 'PPAPI_RELEASE']:
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            results.append(
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                output_api.PresubmitPromptOrNotify(
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    'PPAPI_RELEASE has changed', long_text=line[2]))
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            releaseChanged = True
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if releaseChanged:
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          continue
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if 'trusted' in name_parts:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        missing_priv.append('  ppapi/c/%s.h' % filename)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if 'private' in name_parts:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        missing_priv.append('  ppapi/c/%s.h' % filename)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if 'dev' in name_parts:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        missing_dev.append('  ppapi/c/%s.h' % filename)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      missing_stable.append('  ppapi/c/%s.h' % filename)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if missing_priv:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.append(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output_api.PresubmitPromptWarning(
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'Missing PPAPI IDL for private interface, please generate IDL:',
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            long_text='\n'.join(missing_priv)))
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if missing_dev:
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.append(
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output_api.PresubmitPromptWarning(
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'Missing PPAPI IDL for DEV, required before moving to stable:',
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            long_text='\n'.join(missing_dev)))
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if missing_stable:
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    # It might be okay that the header changed without a corresponding IDL
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    # change. E.g., comment indenting may have been changed. Treat this as a
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    # warning.
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if generators_changed:
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      results.append(
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          output_api.PresubmitPromptWarning(
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              'Missing PPAPI IDL for stable interface (due to change in ' +
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              'generators?):',
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              long_text='\n'.join(missing_stable)))
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    else:
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      results.append(
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          output_api.PresubmitError(
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              'Missing PPAPI IDL for stable interface:',
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)              long_text='\n'.join(missing_stable)))
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Verify all *.h files match *.idl definitions, use:
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #   --test to prevent output to disk
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #   --diff to generate a unified diff
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #   --out to pick which files to examine (only the ones in the CL)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi_dir = input_api.PresubmitLocalPath()
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cmd = [sys.executable, 'generator.py',
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         '--wnone', '--diff', '--test','--cgen', '--range=start,end']
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Only generate output for IDL files references (as *.h or *.idl) in this CL
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cmd.append('--out=' + ','.join([name + '.idl' for name in both]))
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cmd_results = RunCmdAndCheck(cmd,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               'PPAPI IDL Diff detected: Run the generator.',
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               output_api,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               os.path.join(ppapi_dir, 'generators'))
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if cmd_results:
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.extend(cmd_results)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return results
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CheckChangeOnUpload(input_api, output_api):
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckChange(input_api, output_api)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CheckChangeOnCommit(input_api, output_api):
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckChange(input_api, output_api)
296