2019-10-29 16:01:39 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# coding=utf-8
|
|
|
|
#
|
|
|
|
# CI script to check build logs for warnings.
|
|
|
|
# Reads the list of builds, in the format produced by find_apps.py or build_apps.py, and finds warnings in the
|
|
|
|
# log files for every build.
|
|
|
|
# Exits with a non-zero exit code if any warning is found.
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import logging
|
2020-06-28 05:56:04 +00:00
|
|
|
import os
|
2019-10-29 16:01:39 +00:00
|
|
|
import re
|
2020-06-28 05:56:04 +00:00
|
|
|
import sys
|
2019-10-29 16:01:39 +00:00
|
|
|
|
|
|
|
try:
|
2020-04-23 10:48:51 +00:00
|
|
|
from find_build_apps import BuildItem, setup_logging
|
2019-10-29 16:01:39 +00:00
|
|
|
except ImportError:
|
2021-01-26 02:49:01 +00:00
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
2020-04-23 10:48:51 +00:00
|
|
|
from find_build_apps import BuildItem, setup_logging
|
2019-10-29 16:01:39 +00:00
|
|
|
|
2021-01-26 02:49:01 +00:00
|
|
|
WARNING_REGEX = re.compile(r'(?:error|warning)[^\w]', re.MULTILINE | re.IGNORECASE)
|
2019-10-29 16:01:39 +00:00
|
|
|
|
|
|
|
IGNORE_WARNS = [
|
|
|
|
re.compile(r_str) for r_str in [
|
2021-01-26 02:49:01 +00:00
|
|
|
r'library/error\.o',
|
2021-04-20 09:25:00 +00:00
|
|
|
r'/.*error\S*\.o',
|
2021-01-26 02:49:01 +00:00
|
|
|
r'.*error.*\.c\.obj',
|
2021-04-16 11:52:56 +00:00
|
|
|
r'.*error.*\.cpp\.obj',
|
|
|
|
r'.*error.*\.cxx\.obj',
|
|
|
|
r'.*error.*\.cc\.obj',
|
2021-01-26 02:49:01 +00:00
|
|
|
r'-Werror',
|
|
|
|
r'error\.d',
|
2021-04-20 09:25:00 +00:00
|
|
|
r'/.*error\S*.d',
|
2021-01-26 02:49:01 +00:00
|
|
|
r'reassigning to symbol',
|
|
|
|
r'changes choice state',
|
|
|
|
r'crosstool_version_check\.cmake',
|
|
|
|
r'CryptographyDeprecationWarning',
|
2022-01-05 04:18:50 +00:00
|
|
|
r'Warning: \d+/\d+ app partitions are too small for binary',
|
|
|
|
r'CMake Deprecation Warning at main/lib/tinyxml2/CMakeLists\.txt:11 \(cmake_policy\)',
|
2019-10-29 16:01:39 +00:00
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def line_has_warnings(line): # type: (str) -> bool
|
2020-04-24 03:03:35 +00:00
|
|
|
if not WARNING_REGEX.search(line):
|
2019-10-29 16:01:39 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
has_warnings = True
|
|
|
|
for ignored in IGNORE_WARNS:
|
|
|
|
if re.search(ignored, line):
|
|
|
|
has_warnings = False
|
|
|
|
break
|
|
|
|
|
|
|
|
return has_warnings
|
|
|
|
|
|
|
|
|
2020-06-24 05:52:50 +00:00
|
|
|
def main(): # type: () -> None
|
2021-01-26 02:49:01 +00:00
|
|
|
parser = argparse.ArgumentParser(description='ESP-IDF app builder')
|
2019-10-29 16:01:39 +00:00
|
|
|
parser.add_argument(
|
2021-01-26 02:49:01 +00:00
|
|
|
'-v',
|
|
|
|
'--verbose',
|
|
|
|
action='count',
|
|
|
|
help='Increase the logging level of the script. Can be specified multiple times.',
|
2019-10-29 16:01:39 +00:00
|
|
|
)
|
|
|
|
parser.add_argument(
|
2021-01-26 02:49:01 +00:00
|
|
|
'--log-file',
|
|
|
|
type=argparse.FileType('w'),
|
|
|
|
help='Write the script log to the specified file, instead of stderr',
|
2019-10-29 16:01:39 +00:00
|
|
|
)
|
|
|
|
parser.add_argument(
|
2021-01-26 02:49:01 +00:00
|
|
|
'build_list',
|
|
|
|
type=argparse.FileType('r'),
|
|
|
|
nargs='?',
|
2019-10-29 16:01:39 +00:00
|
|
|
default=sys.stdin,
|
2021-01-26 02:49:01 +00:00
|
|
|
help='Name of the file to read the list of builds from. If not specified, read from stdin.',
|
2019-10-29 16:01:39 +00:00
|
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
setup_logging(args)
|
|
|
|
|
|
|
|
build_items = [BuildItem.from_json(line) for line in args.build_list]
|
|
|
|
if not build_items:
|
2021-01-26 02:49:01 +00:00
|
|
|
logging.warning('Empty build list')
|
2020-06-29 10:11:49 +00:00
|
|
|
SystemExit(0)
|
2019-10-29 16:01:39 +00:00
|
|
|
|
|
|
|
found_warnings = 0
|
|
|
|
for build_item in build_items:
|
|
|
|
if not build_item.build_log_path:
|
2021-01-26 02:49:01 +00:00
|
|
|
logging.debug('No log file for {}'.format(build_item.work_dir))
|
2019-10-29 16:01:39 +00:00
|
|
|
continue
|
2021-01-26 02:49:01 +00:00
|
|
|
with open(build_item.build_log_path, 'r') as log_file:
|
2019-10-29 16:01:39 +00:00
|
|
|
for line_no, line in enumerate(log_file):
|
|
|
|
if line_has_warnings(line):
|
2021-01-26 02:49:01 +00:00
|
|
|
logging.error('Issue in app {}, config {}:'.format(build_item.app_dir, build_item.config_name))
|
|
|
|
logging.error(line.rstrip('\n'))
|
|
|
|
logging.error('See {}:{} for details'.format(os.path.basename(build_item.build_log_path),
|
2019-10-29 16:01:39 +00:00
|
|
|
line_no + 1))
|
|
|
|
found_warnings += 1
|
|
|
|
break
|
|
|
|
|
|
|
|
if found_warnings:
|
2021-01-26 02:49:01 +00:00
|
|
|
logging.error('Checked {} builds, found {} warnings'.format(len(build_items), found_warnings))
|
2019-10-29 16:01:39 +00:00
|
|
|
raise SystemExit(1)
|
|
|
|
|
2021-01-26 02:49:01 +00:00
|
|
|
logging.info('No warnings found')
|
2019-10-29 16:01:39 +00:00
|
|
|
|
|
|
|
|
2021-01-26 02:49:01 +00:00
|
|
|
if __name__ == '__main__':
|
2019-10-29 16:01:39 +00:00
|
|
|
main()
|