1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
11 def RunCmdAndCheck(cmd
, err_string
, output_api
, cwd
=None):
13 p
= subprocess
.Popen(cmd
, cwd
=cwd
,
14 stdout
=subprocess
.PIPE
,
15 stderr
=subprocess
.PIPE
)
16 (p_stdout
, p_stderr
) = p
.communicate()
19 output_api
.PresubmitError(err_string
,
24 def RunUnittests(input_api
, output_api
):
25 # Run some Generator unittests if the generator source was changed.
27 files
= input_api
.LocalPaths()
29 for filename
in files
:
30 name_parts
= filename
.split(os
.sep
)
31 if name_parts
[0:2] == ['ppapi', 'generators']:
32 generator_files
.append(filename
)
33 if generator_files
!= []:
34 cmd
= [ sys
.executable
, 'idl_gen_pnacl.py', '--wnone', '--test']
35 ppapi_dir
= input_api
.PresubmitLocalPath()
36 results
.extend(RunCmdAndCheck(cmd
,
37 'PPAPI IDL Pnacl unittest failed.',
39 os
.path
.join(ppapi_dir
, 'generators')))
43 # If any .srpc files were changed, run run_srpcgen.py --diff_mode.
44 def CheckSrpcChange(input_api
, output_api
):
45 if [True for filename
in input_api
.LocalPaths() if
46 os
.path
.splitext(filename
)[1] == '.srpc']:
47 return RunCmdAndCheck([sys
.executable
,
48 os
.path
.join(input_api
.PresubmitLocalPath(),
49 'native_client', 'src',
50 'shared', 'ppapi_proxy',
53 'PPAPI SRPC Diff detected: Run run_srpcgen.py.',
58 # Verify that the files do not contain a 'TODO' in them.
59 RE_TODO
= re
.compile(r
'\WTODO\W', flags
=re
.I
)
60 def CheckTODO(input_api
, output_api
):
61 files
= input_api
.LocalPaths()
64 for filename
in files
:
65 name
, ext
= os
.path
.splitext(filename
)
66 name_parts
= name
.split(os
.sep
)
68 # Only check normal build sources.
69 if ext
not in ['.h', '.cc', '.idl']:
72 # Only examine the ppapi directory.
73 if name_parts
[0] != 'ppapi':
76 # Only examine public plugin facing directories.
77 if name_parts
[1] not in ['api', 'c', 'cpp', 'utility']:
80 # Only examine public stable interfaces.
81 if name_parts
[2] in ['dev', 'private', 'trusted']:
84 filepath
= os
.path
.join('..', filename
)
85 if RE_TODO
.search(open(filepath
, 'rb').read()):
89 return [output_api
.PresubmitError(
90 'TODOs found in stable public PPAPI files:',
91 long_text
='\n'.join(todo
))]
94 # Verify that no CPP wrappers use un-versioned PPB interface name macros.
95 RE_UNVERSIONED_PPB
= re
.compile(r
'\bPPB_\w+_INTERFACE\b')
96 def CheckUnversionedPPB(input_api
, output_api
):
97 files
= input_api
.LocalPaths()
100 for filename
in files
:
101 name
, ext
= os
.path
.splitext(filename
)
102 name_parts
= name
.split(os
.sep
)
104 # Only check C++ sources.
105 if ext
not in ['.cc']:
108 # Only examine the public plugin facing ppapi/cpp directory.
109 if name_parts
[0:2] != ['ppapi', 'cpp']:
112 # Only examine public stable and trusted interfaces.
113 if name_parts
[2] in ['dev', 'private']:
116 filepath
= os
.path
.join('..', filename
)
117 if RE_UNVERSIONED_PPB
.search(open(filepath
, 'rb').read()):
118 todo
.append(filename
)
121 return [output_api
.PresubmitError(
122 'Unversioned PPB interface references found in PPAPI C++ wrappers:',
123 long_text
='\n'.join(todo
))]
126 def CheckChange(input_api
, output_api
):
129 results
.extend(CheckSrpcChange(input_api
, output_api
))
131 results
.extend(RunUnittests(input_api
, output_api
))
133 results
.extend(CheckTODO(input_api
, output_api
))
135 results
.extend(CheckUnversionedPPB(input_api
, output_api
))
137 # Verify all modified *.idl have a matching *.h
138 files
= input_api
.LocalPaths()
142 # Find all relevant .h and .idl files.
143 for filename
in files
:
144 name
, ext
= os
.path
.splitext(filename
)
145 name_parts
= name
.split(os
.sep
)
146 if name_parts
[0:2] == ['ppapi', 'c'] and ext
== '.h':
147 h_files
.append('/'.join(name_parts
[2:]))
148 if name_parts
[0:2] == ['ppapi', 'api'] and ext
== '.idl':
149 idl_files
.append('/'.join(name_parts
[2:]))
151 # Generate a list of all appropriate *.h and *.idl changes in this CL.
152 both
= h_files
+ idl_files
154 # If there aren't any, we are done checking.
155 if not both
: return results
158 for filename
in idl_files
:
159 if filename
not in set(h_files
):
160 missing
.append(' ppapi/c/%s.idl' % filename
)
164 output_api
.PresubmitPromptWarning(
165 'Missing PPAPI header, no change or skipped generation?',
166 long_text
='\n'.join(missing
)))
171 for filename
in h_files
:
172 if filename
not in set(idl_files
):
173 name_parts
= filename
.split(os
.sep
)
175 if 'trusted' in name_parts
:
176 missing_priv
.append(' ppapi/c/%s.h' % filename
)
179 if 'private' in name_parts
:
180 missing_priv
.append(' ppapi/c/%s.h' % filename
)
183 if 'dev' in name_parts
:
184 missing_dev
.append(' ppapi/c/%s.h' % filename
)
187 missing_stable
.append(' ppapi/c/%s.h' % filename
)
191 output_api
.PresubmitPromptWarning(
192 'Missing PPAPI IDL for private interface, please generate IDL:',
193 long_text
='\n'.join(missing_priv
)))
197 output_api
.PresubmitPromptWarning(
198 'Missing PPAPI IDL for DEV, required before moving to stable:',
199 long_text
='\n'.join(missing_dev
)))
203 output_api
.PresubmitError(
204 'Missing PPAPI IDL for stable interface:',
205 long_text
='\n'.join(missing_stable
)))
207 # Verify all *.h files match *.idl definitions, use:
208 # --test to prevent output to disk
209 # --diff to generate a unified diff
210 # --out to pick which files to examine (only the ones in the CL)
211 ppapi_dir
= input_api
.PresubmitLocalPath()
212 cmd
= [sys
.executable
, 'generator.py',
213 '--wnone', '--diff', '--test','--cgen', '--range=start,end']
215 # Only generate output for IDL files references (as *.h or *.idl) in this CL
216 cmd
.append('--out=' + ','.join([name
+ '.idl' for name
in both
]))
217 cmd_results
= RunCmdAndCheck(cmd
,
218 'PPAPI IDL Diff detected: Run the generator.',
220 os
.path
.join(ppapi_dir
, 'generators'))
222 results
.extend(cmd_results
)
227 def CheckChangeOnUpload(input_api
, output_api
):
228 return CheckChange(input_api
, output_api
)
231 def CheckChangeOnCommit(input_api
, output_api
):
232 return CheckChange(input_api
, output_api
)