| 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 |