OLD | NEW |
1 # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 1 # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
2 # | 2 # |
3 # Use of this source code is governed by a BSD-style license | 3 # Use of this source code is governed by a BSD-style license |
4 # that can be found in the LICENSE file in the root of the source | 4 # that can be found in the LICENSE file in the root of the source |
5 # tree. An additional intellectual property rights grant can be found | 5 # tree. An additional intellectual property rights grant can be found |
6 # in the file PATENTS. All contributing project authors may | 6 # in the file PATENTS. All contributing project authors may |
7 # be found in the AUTHORS file in the root of the source tree. | 7 # be found in the AUTHORS file in the root of the source tree. |
8 | 8 |
9 import os | 9 import os |
10 import re | 10 import re |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 if input_api.is_committing: | 220 if input_api.is_committing: |
221 # TODO(kjellander): Change back to PresubmitError below when we're | 221 # TODO(kjellander): Change back to PresubmitError below when we're |
222 # confident with the lint settings. | 222 # confident with the lint settings. |
223 res_type = output_api.PresubmitPromptWarning | 223 res_type = output_api.PresubmitPromptWarning |
224 else: | 224 else: |
225 res_type = output_api.PresubmitPromptWarning | 225 res_type = output_api.PresubmitPromptWarning |
226 result = [res_type('Changelist failed cpplint.py check.')] | 226 result = [res_type('Changelist failed cpplint.py check.')] |
227 | 227 |
228 return result | 228 return result |
229 | 229 |
230 def _CheckNoRtcBaseDeps(input_api, gyp_files, output_api): | 230 def _CheckNoRtcBaseDeps(input_api, gn_files, output_api): |
231 pattern = input_api.re.compile(r"base.gyp:rtc_base\s*'") | |
232 violating_files = [] | |
233 for f in gyp_files: | |
234 gyp_exceptions = ( | |
235 'audio_device.gypi', | |
236 'base_tests.gyp', | |
237 'desktop_capture.gypi', | |
238 'p2p.gyp', | |
239 'sdk.gyp', | |
240 'webrtc_test_common.gyp', | |
241 'webrtc_tests.gypi', | |
242 ) | |
243 if f.LocalPath().endswith(gyp_exceptions): | |
244 continue | |
245 contents = input_api.ReadFile(f) | |
246 if pattern.search(contents): | |
247 violating_files.append(f) | |
248 if violating_files: | |
249 return [output_api.PresubmitError( | |
250 'Depending on rtc_base is not allowed. Change your dependency to ' | |
251 'rtc_base_approved and possibly sanitize and move the desired source ' | |
252 'file(s) to rtc_base_approved.\nChanged GYP files:', | |
253 items=violating_files)] | |
254 return [] | |
255 | |
256 def _CheckNoRtcBaseDepsGn(input_api, gn_files, output_api): | |
257 pattern = input_api.re.compile(r'base:rtc_base\s*"') | 231 pattern = input_api.re.compile(r'base:rtc_base\s*"') |
258 violating_files = [] | 232 violating_files = [] |
259 for f in gn_files: | 233 for f in gn_files: |
260 gn_exceptions = ( | 234 gn_exceptions = ( |
261 os.path.join('audio_device', 'BUILD.gn'), | 235 os.path.join('audio_device', 'BUILD.gn'), |
262 os.path.join('base_tests', 'BUILD.gn'), | 236 os.path.join('base_tests', 'BUILD.gn'), |
263 os.path.join('desktop_capture', 'BUILD.gn'), | 237 os.path.join('desktop_capture', 'BUILD.gn'), |
264 os.path.join('p2p', 'BUILD.gn'), | 238 os.path.join('p2p', 'BUILD.gn'), |
265 os.path.join('sdk', 'BUILD.gn'), | 239 os.path.join('sdk', 'BUILD.gn'), |
266 os.path.join('webrtc_test_common', 'BUILD.gn'), | 240 os.path.join('webrtc_test_common', 'BUILD.gn'), |
(...skipping 14 matching lines...) Expand all Loading... |
281 if pattern.search(contents): | 255 if pattern.search(contents): |
282 violating_files.append(f) | 256 violating_files.append(f) |
283 if violating_files: | 257 if violating_files: |
284 return [output_api.PresubmitError( | 258 return [output_api.PresubmitError( |
285 'Depending on rtc_base is not allowed. Change your dependency to ' | 259 'Depending on rtc_base is not allowed. Change your dependency to ' |
286 'rtc_base_approved and possibly sanitize and move the desired source ' | 260 'rtc_base_approved and possibly sanitize and move the desired source ' |
287 'file(s) to rtc_base_approved.\nChanged GN files:', | 261 'file(s) to rtc_base_approved.\nChanged GN files:', |
288 items=violating_files)] | 262 items=violating_files)] |
289 return [] | 263 return [] |
290 | 264 |
291 def _CheckNoSourcesAboveGyp(input_api, gyp_files, output_api): | |
292 # Disallow referencing source files with paths above the GYP file location. | |
293 source_pattern = input_api.re.compile(r'\'sources\'.*?\[(.*?)\]', | |
294 re.MULTILINE | re.DOTALL) | |
295 file_pattern = input_api.re.compile(r"'((\.\./.*?)|(<\(webrtc_root\).*?))'") | |
296 violating_gyp_files = set() | |
297 violating_source_entries = [] | |
298 for gyp_file in gyp_files: | |
299 if 'supplement.gypi' in gyp_file.LocalPath(): | |
300 # Exclude supplement.gypi from this check, as the LSan and TSan | |
301 # suppression files are located in a different location. | |
302 continue | |
303 contents = input_api.ReadFile(gyp_file) | |
304 for source_block_match in source_pattern.finditer(contents): | |
305 # Find all source list entries starting with ../ in the source block | |
306 # (exclude overrides entries). | |
307 for file_list_match in file_pattern.finditer(source_block_match.group(1)): | |
308 source_file = file_list_match.group(1) | |
309 if 'overrides/' not in source_file: | |
310 violating_source_entries.append(source_file) | |
311 violating_gyp_files.add(gyp_file) | |
312 if violating_gyp_files: | |
313 return [output_api.PresubmitError( | |
314 'Referencing source files above the directory of the GYP file is not ' | |
315 'allowed. Please introduce new GYP targets and/or GYP files in the ' | |
316 'proper location instead.\n' | |
317 'Invalid source entries:\n' | |
318 '%s\n' | |
319 'Violating GYP files:' % '\n'.join(violating_source_entries), | |
320 items=violating_gyp_files)] | |
321 return [] | |
322 | 265 |
323 def _CheckNoSourcesAboveGn(input_api, gn_files, output_api): | 266 def _CheckNoSourcesAbove(input_api, gn_files, output_api): |
324 # Disallow referencing source files with paths above the GN file location. | 267 # Disallow referencing source files with paths above the GN file location. |
325 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]', | 268 source_pattern = input_api.re.compile(r' +sources \+?= \[(.*?)\]', |
326 re.MULTILINE | re.DOTALL) | 269 re.MULTILINE | re.DOTALL) |
327 file_pattern = input_api.re.compile(r'"((\.\./.*?)|(//.*?))"') | 270 file_pattern = input_api.re.compile(r'"((\.\./.*?)|(//.*?))"') |
328 violating_gn_files = set() | 271 violating_gn_files = set() |
329 violating_source_entries = [] | 272 violating_source_entries = [] |
330 for gn_file in gn_files: | 273 for gn_file in gn_files: |
331 contents = input_api.ReadFile(gn_file) | 274 contents = input_api.ReadFile(gn_file) |
332 for source_block_match in source_pattern.finditer(contents): | 275 for source_block_match in source_pattern.finditer(contents): |
333 # Find all source list entries starting with ../ in the source block | 276 # Find all source list entries starting with ../ in the source block |
334 # (exclude overrides entries). | 277 # (exclude overrides entries). |
335 for file_list_match in file_pattern.finditer(source_block_match.group(1)): | 278 for file_list_match in file_pattern.finditer(source_block_match.group(1)): |
336 source_file = file_list_match.group(1) | 279 source_file = file_list_match.group(1) |
337 if 'overrides/' not in source_file: | 280 if 'overrides/' not in source_file: |
338 violating_source_entries.append(source_file) | 281 violating_source_entries.append(source_file) |
339 violating_gn_files.add(gn_file) | 282 violating_gn_files.add(gn_file) |
340 if violating_gn_files: | 283 if violating_gn_files: |
341 return [output_api.PresubmitError( | 284 return [output_api.PresubmitError( |
342 'Referencing source files above the directory of the GN file is not ' | 285 'Referencing source files above the directory of the GN file is not ' |
343 'allowed. Please introduce new GYP targets and/or GN files in the ' | 286 'allowed. Please introduce new GN targets in the proper location ' |
344 'proper location instead.\n' | 287 'instead.\n' |
345 'Invalid source entries:\n' | 288 'Invalid source entries:\n' |
346 '%s\n' | 289 '%s\n' |
347 'Violating GN files:' % '\n'.join(violating_source_entries), | 290 'Violating GN files:' % '\n'.join(violating_source_entries), |
348 items=violating_gn_files)] | 291 items=violating_gn_files)] |
349 return [] | 292 return [] |
350 | 293 |
351 def _CheckGypChanges(input_api, output_api): | |
352 source_file_filter = lambda x: input_api.FilterSourceFile( | |
353 x, white_list=(r'.+\.(gyp|gypi)$',)) | |
354 | |
355 gyp_files = [] | |
356 for f in input_api.AffectedSourceFiles(source_file_filter): | |
357 if f.LocalPath().startswith('webrtc'): | |
358 gyp_files.append(f) | |
359 | |
360 result = [] | |
361 if gyp_files: | |
362 result.append(output_api.PresubmitNotifyResult( | |
363 'As you\'re changing GYP files: please make sure corresponding ' | |
364 'BUILD.gn files are also updated.\nChanged GYP files:', | |
365 items=gyp_files)) | |
366 result.extend(_CheckNoRtcBaseDeps(input_api, gyp_files, output_api)) | |
367 result.extend(_CheckNoSourcesAboveGyp(input_api, gyp_files, output_api)) | |
368 return result | |
369 | |
370 def _CheckGnChanges(input_api, output_api): | 294 def _CheckGnChanges(input_api, output_api): |
371 source_file_filter = lambda x: input_api.FilterSourceFile( | 295 source_file_filter = lambda x: input_api.FilterSourceFile( |
372 x, white_list=(r'.+\.(gn|gni)$',)) | 296 x, white_list=(r'.+\.(gn|gni)$',)) |
373 | 297 |
374 gn_files = [] | 298 gn_files = [] |
375 for f in input_api.AffectedSourceFiles(source_file_filter): | 299 for f in input_api.AffectedSourceFiles(source_file_filter): |
376 if f.LocalPath().startswith('webrtc'): | 300 if f.LocalPath().startswith('webrtc'): |
377 gn_files.append(f) | 301 gn_files.append(f) |
378 | 302 |
379 result = [] | 303 result = [] |
380 if gn_files: | 304 if gn_files: |
381 result.append(output_api.PresubmitNotifyResult( | 305 result.extend(_CheckNoRtcBaseDeps(input_api, gn_files, output_api)) |
382 'As you\'re changing GN files: please make sure corresponding GYP' | 306 result.extend(_CheckNoSourcesAbove(input_api, gn_files, output_api)) |
383 'files are also updated.\nChanged GN files:', | |
384 items=gn_files)) | |
385 result.extend(_CheckNoRtcBaseDepsGn(input_api, gn_files, output_api)) | |
386 result.extend(_CheckNoSourcesAboveGn(input_api, gn_files, output_api)) | |
387 return result | 307 return result |
388 | 308 |
389 def _CheckUnwantedDependencies(input_api, output_api): | 309 def _CheckUnwantedDependencies(input_api, output_api): |
390 """Runs checkdeps on #include statements added in this | 310 """Runs checkdeps on #include statements added in this |
391 change. Breaking - rules is an error, breaking ! rules is a | 311 change. Breaking - rules is an error, breaking ! rules is a |
392 warning. | 312 warning. |
393 """ | 313 """ |
394 # Copied from Chromium's src/PRESUBMIT.py. | 314 # Copied from Chromium's src/PRESUBMIT.py. |
395 | 315 |
396 # We need to wait until we have an input_api object and use this | 316 # We need to wait until we have an input_api object and use this |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 r'^buildtools[\\\/].*\.py$', | 447 r'^buildtools[\\\/].*\.py$', |
528 r'^chromium[\\\/].*\.py$', | 448 r'^chromium[\\\/].*\.py$', |
529 r'^mojo.*[\\\/].*\.py$', | 449 r'^mojo.*[\\\/].*\.py$', |
530 r'^out.*[\\\/].*\.py$', | 450 r'^out.*[\\\/].*\.py$', |
531 r'^testing[\\\/].*\.py$', | 451 r'^testing[\\\/].*\.py$', |
532 r'^third_party[\\\/].*\.py$', | 452 r'^third_party[\\\/].*\.py$', |
533 r'^tools[\\\/]clang[\\\/].*\.py$', | 453 r'^tools[\\\/]clang[\\\/].*\.py$', |
534 r'^tools[\\\/]generate_library_loader[\\\/].*\.py$', | 454 r'^tools[\\\/]generate_library_loader[\\\/].*\.py$', |
535 r'^tools[\\\/]generate_stubs[\\\/].*\.py$', | 455 r'^tools[\\\/]generate_stubs[\\\/].*\.py$', |
536 r'^tools[\\\/]gn[\\\/].*\.py$', | 456 r'^tools[\\\/]gn[\\\/].*\.py$', |
537 r'^tools[\\\/]gyp[\\\/].*\.py$', | |
538 r'^tools[\\\/]isolate_driver.py$', | 457 r'^tools[\\\/]isolate_driver.py$', |
539 r'^tools[\\\/]mb[\\\/].*\.py$', | 458 r'^tools[\\\/]mb[\\\/].*\.py$', |
540 r'^tools[\\\/]protoc_wrapper[\\\/].*\.py$', | 459 r'^tools[\\\/]protoc_wrapper[\\\/].*\.py$', |
541 r'^tools[\\\/]python[\\\/].*\.py$', | 460 r'^tools[\\\/]python[\\\/].*\.py$', |
542 r'^tools[\\\/]python_charts[\\\/]data[\\\/].*\.py$', | 461 r'^tools[\\\/]python_charts[\\\/]data[\\\/].*\.py$', |
543 r'^tools[\\\/]refactoring[\\\/].*\.py$', | 462 r'^tools[\\\/]refactoring[\\\/].*\.py$', |
544 r'^tools[\\\/]swarming_client[\\\/].*\.py$', | 463 r'^tools[\\\/]swarming_client[\\\/].*\.py$', |
545 r'^tools[\\\/]vim[\\\/].*\.py$', | 464 r'^tools[\\\/]vim[\\\/].*\.py$', |
546 # TODO(phoglund): should arguably be checked. | 465 # TODO(phoglund): should arguably be checked. |
547 r'^tools[\\\/]valgrind-webrtc[\\\/].*\.py$', | 466 r'^tools[\\\/]valgrind-webrtc[\\\/].*\.py$', |
548 r'^tools[\\\/]valgrind[\\\/].*\.py$', | 467 r'^tools[\\\/]valgrind[\\\/].*\.py$', |
549 r'^tools[\\\/]win[\\\/].*\.py$', | 468 r'^tools[\\\/]win[\\\/].*\.py$', |
550 r'^xcodebuild.*[\\\/].*\.py$',), | 469 r'^xcodebuild.*[\\\/].*\.py$',), |
551 disabled_warnings=['F0401', # Failed to import x | 470 disabled_warnings=['F0401', # Failed to import x |
552 'E0611', # No package y in x | 471 'E0611', # No package y in x |
553 'W0232', # Class has no __init__ method | 472 'W0232', # Class has no __init__ method |
554 ], | 473 ], |
555 pylintrc='pylintrc')) | 474 pylintrc='pylintrc')) |
556 | 475 |
557 # TODO(nisse): talk/ is no more, so make below checks simpler? | 476 # TODO(nisse): talk/ is no more, so make below checks simpler? |
558 # WebRTC can't use the presubmit_canned_checks.PanProjectChecks function since | 477 # WebRTC can't use the presubmit_canned_checks.PanProjectChecks function since |
559 # we need to have different license checks in talk/ and webrtc/ directories. | 478 # we need to have different license checks in talk/ and webrtc/ directories. |
560 # Instead, hand-picked checks are included below. | 479 # Instead, hand-picked checks are included below. |
561 | 480 |
562 # .m and .mm files are ObjC files. For simplicity we will consider .h files in | 481 # .m and .mm files are ObjC files. For simplicity we will consider .h files in |
563 # ObjC subdirectories ObjC headers. | 482 # ObjC subdirectories ObjC headers. |
564 objc_filter_list = (r'.+\.m$', r'.+\.mm$', r'.+objc\/.+\.h$') | 483 objc_filter_list = (r'.+\.m$', r'.+\.mm$', r'.+objc\/.+\.h$') |
565 # Skip long-lines check for DEPS, GN and GYP files. | 484 # Skip long-lines check for DEPS and GN files. |
566 build_file_filter_list = (r'.+\.gyp$', r'.+\.gypi$', r'.+\.gn$', r'.+\.gni$', | 485 build_file_filter_list = (r'.+\.gn$', r'.+\.gni$', 'DEPS') |
567 'DEPS') | |
568 eighty_char_sources = lambda x: input_api.FilterSourceFile(x, | 486 eighty_char_sources = lambda x: input_api.FilterSourceFile(x, |
569 black_list=build_file_filter_list + objc_filter_list) | 487 black_list=build_file_filter_list + objc_filter_list) |
570 hundred_char_sources = lambda x: input_api.FilterSourceFile(x, | 488 hundred_char_sources = lambda x: input_api.FilterSourceFile(x, |
571 white_list=objc_filter_list) | 489 white_list=objc_filter_list) |
572 results.extend(input_api.canned_checks.CheckLongLines( | 490 results.extend(input_api.canned_checks.CheckLongLines( |
573 input_api, output_api, maxlen=80, source_file_filter=eighty_char_sources)) | 491 input_api, output_api, maxlen=80, source_file_filter=eighty_char_sources)) |
574 results.extend(input_api.canned_checks.CheckLongLines( | 492 results.extend(input_api.canned_checks.CheckLongLines( |
575 input_api, output_api, maxlen=100, | 493 input_api, output_api, maxlen=100, |
576 source_file_filter=hundred_char_sources)) | 494 source_file_filter=hundred_char_sources)) |
577 | 495 |
578 results.extend(input_api.canned_checks.CheckChangeHasNoTabs( | 496 results.extend(input_api.canned_checks.CheckChangeHasNoTabs( |
579 input_api, output_api)) | 497 input_api, output_api)) |
580 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace( | 498 results.extend(input_api.canned_checks.CheckChangeHasNoStrayWhitespace( |
581 input_api, output_api)) | 499 input_api, output_api)) |
582 results.extend(input_api.canned_checks.CheckChangeTodoHasOwner( | 500 results.extend(input_api.canned_checks.CheckChangeTodoHasOwner( |
583 input_api, output_api)) | 501 input_api, output_api)) |
584 results.extend(_CheckNativeApiHeaderChanges(input_api, output_api)) | 502 results.extend(_CheckNativeApiHeaderChanges(input_api, output_api)) |
585 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) | 503 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) |
586 results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) | 504 results.extend(_CheckNoFRIEND_TEST(input_api, output_api)) |
587 results.extend(_CheckGypChanges(input_api, output_api)) | |
588 results.extend(_CheckGnChanges(input_api, output_api)) | 505 results.extend(_CheckGnChanges(input_api, output_api)) |
589 results.extend(_CheckUnwantedDependencies(input_api, output_api)) | 506 results.extend(_CheckUnwantedDependencies(input_api, output_api)) |
590 results.extend(_CheckJSONParseErrors(input_api, output_api)) | 507 results.extend(_CheckJSONParseErrors(input_api, output_api)) |
591 results.extend(_RunPythonTests(input_api, output_api)) | 508 results.extend(_RunPythonTests(input_api, output_api)) |
592 return results | 509 return results |
593 | 510 |
594 | 511 |
595 def CheckChangeOnUpload(input_api, output_api): | 512 def CheckChangeOnUpload(input_api, output_api): |
596 results = [] | 513 results = [] |
597 results.extend(_CommonChecks(input_api, output_api)) | 514 results.extend(_CommonChecks(input_api, output_api)) |
(...skipping 11 matching lines...) Expand all Loading... |
609 input_api, output_api)) | 526 input_api, output_api)) |
610 results.extend(input_api.canned_checks.CheckChangeHasDescription( | 527 results.extend(input_api.canned_checks.CheckChangeHasDescription( |
611 input_api, output_api)) | 528 input_api, output_api)) |
612 results.extend(_CheckChangeHasBugField(input_api, output_api)) | 529 results.extend(_CheckChangeHasBugField(input_api, output_api)) |
613 results.extend(input_api.canned_checks.CheckChangeHasTestField( | 530 results.extend(input_api.canned_checks.CheckChangeHasTestField( |
614 input_api, output_api)) | 531 input_api, output_api)) |
615 results.extend(input_api.canned_checks.CheckTreeIsOpen( | 532 results.extend(input_api.canned_checks.CheckTreeIsOpen( |
616 input_api, output_api, | 533 input_api, output_api, |
617 json_url='http://webrtc-status.appspot.com/current?format=json')) | 534 json_url='http://webrtc-status.appspot.com/current?format=json')) |
618 return results | 535 return results |
OLD | NEW |