pw_presubmit: Build file check; fatal pylint
- Check that all C, C++ sources appear in BUILD and BUILD.gn files.
- Check that all .rst files appear in BUILD.gn files.
- Make the pylint check fatal. The full presubmit will fail until some
issues are fixed. Incremental presubmits (e.g. with the pre-push hook
or pw presubmit --base master) will pass (unless there are errors).
Change-Id: Id42cc2e06278d0e56017a2008676db8e77ba6c20
diff --git a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
index bf1a224..1dde12c 100755
--- a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
+++ b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
@@ -34,7 +34,7 @@
from pw_presubmit import format_code
from pw_presubmit.install_hook import install_hook
-from pw_presubmit import call, filter_paths, PresubmitFailure
+from pw_presubmit import call, filter_paths, plural, PresubmitFailure
_LOG: logging.Logger = logging.getLogger(__name__)
@@ -171,12 +171,7 @@
@filter_paths(endswith='.py')
def pylint(paths):
- try:
- run_python_module('pylint', '-j', '0', *paths)
- except PresubmitFailure:
- # TODO(hepler): Enforce pylint when it passes.
- _LOG.warning('pylint checks FAILED!')
- _LOG.warning('Treating this as a warning... for now.')
+ run_python_module('pylint', '-j', '0', *paths)
@filter_paths(endswith='.py', exclude=r'(?:.+/)?setup\.py')
@@ -270,6 +265,52 @@
CODE_FORMAT = (copyright_notice, *format_code.PRESUBMIT_CHECKS)
#
+# General presubmit checks
+#
+
+
+def _read_contents(paths, comment: bytes = b'#') -> bytearray:
+ contents = bytearray()
+
+ for path in paths:
+ with open(path, 'rb') as file:
+ for line in file:
+ line = line.strip()
+ if not line.startswith(comment):
+ contents += line
+
+ return contents
+
+
+@filter_paths(endswith=('.rst', *format_code.C_FORMAT.extensions))
+def source_is_in_build_files(paths):
+ build = _read_contents(
+ pw_presubmit.git_stdout('ls-files', 'BUILD', '*/BUILD').split())
+ build_gn = _read_contents(
+ pw_presubmit.git_stdout('ls-files', 'BUILD.gn', '*/BUILD.gn').split())
+
+ failed = []
+
+ for path in paths:
+ filename = os.path.basename(path).encode()
+
+ if not filename.endswith(b'.rst') and filename not in build:
+ _LOG.warning('Missing from Bazel BUILD files: %s', path)
+ failed.append(path)
+
+ if filename not in build_gn:
+ _LOG.warning('Missing from GN BUILD.gn files: %s', path)
+ failed.append(path)
+
+ if failed:
+ _LOG.warning('%s are missing from build files!',
+ plural(failed, 'source'))
+ raise PresubmitFailure
+
+
+GENERAL = (source_is_in_build_files, )
+
+#
# Presubmit check programs
#
QUICK_PRESUBMIT: Sequence = (
@@ -278,10 +319,11 @@
gn_clang_build,
pw_presubmit.pragma_once,
*CODE_FORMAT,
+ *GENERAL,
)
PROGRAMS: Dict[str, Sequence] = {
- 'full': INIT + GN + CC + PYTHON + BAZEL + CODE_FORMAT,
+ 'full': INIT + GN + CC + PYTHON + BAZEL + CODE_FORMAT + GENERAL,
'quick': QUICK_PRESUBMIT,
}