PRESUBMIT.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Copyright 2017 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.
  4. """Presubmit script for //testing/buildbot/filters.
  5. See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
  6. for more details about the presubmit API built into depot_tools.
  7. """
  8. import os
  9. import re
  10. USE_PYTHON3 = True
  11. def _CheckFilterFileFormat(input_api, output_api):
  12. """This ensures all modified filter files are free of common syntax errors.
  13. See the following for the correct syntax of these files:
  14. https://chromium.googlesource.com/chromium/src/+/main/testing/buildbot/filters/README.md#file-syntax
  15. As well as:
  16. https://bit.ly/chromium-test-list-format
  17. """
  18. errors = []
  19. warnings = []
  20. for f in input_api.AffectedFiles():
  21. filename = os.path.basename(f.LocalPath())
  22. if not filename.endswith('.filter'):
  23. # Non-filter files. Ignore these.
  24. continue
  25. inclusions = 0
  26. exclusions = 0
  27. for line_num, line in enumerate(f.NewContents()):
  28. # Implicitly allow for trailing (but not leading) whitespace.
  29. # Allow nocheck comments
  30. line = line.rstrip().replace('# nocheck', '')
  31. if not line:
  32. # Empty line. Ignore these.
  33. continue
  34. if line.startswith('#'):
  35. # A comment. Ignore these.
  36. continue
  37. if line.find('#') >= 0:
  38. errors.append(
  39. '%s:%d "#" is not a valid method separator. Use ".": "%s"' % (
  40. filename, line_num, line))
  41. continue
  42. if line.startswith('//') or line.startswith('/*'):
  43. errors.append(
  44. '%s:%d Not a valid comment syntax. Use "#" instead: "%s"' % (
  45. filename, line_num, line))
  46. continue
  47. if not re.match(r'^\S+$', line):
  48. errors.append(
  49. '%s:%d Line must not contain whitespace: "%s"' % (
  50. filename, line_num, line))
  51. continue
  52. if line[0] == '-':
  53. exclusions += 1
  54. else:
  55. inclusions += 1
  56. # If we have a mix of exclusions and inclusions, print a warning with a
  57. # Y/N prompt to the author. Though this is a valid syntax, it's possible
  58. # that such a combination will lead to a situation where zero tests are run.
  59. if exclusions and inclusions:
  60. warnings.append(
  61. '%s: Contains both inclusions (%d) and exclusions (%d). This may '
  62. 'result in no tests running. Are you sure this is correct?' % (
  63. filename, inclusions, exclusions))
  64. res = []
  65. if errors:
  66. res.append(output_api.PresubmitError(
  67. 'Filter files do not follow the correct format:',
  68. long_text='\n'.join(errors)))
  69. if warnings:
  70. res.append(output_api.PresubmitPromptWarning(
  71. 'Filter files may be incorrect:\n%s' % '\n'.join(warnings)))
  72. return res
  73. def CommonChecks(input_api, output_api):
  74. return _CheckFilterFileFormat(input_api, output_api)
  75. def CheckChangeOnUpload(input_api, output_api):
  76. return CommonChecks(input_api, output_api)
  77. def CheckChangeOnCommit(input_api, output_api):
  78. return CommonChecks(input_api, output_api)