| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- #!/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
- import os
- import re
- import sys
- try:
- from find_build_apps import BuildItem, setup_logging
- except ImportError:
- sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
- from find_build_apps import BuildItem, setup_logging
- WARNING_REGEX = re.compile(r'(?:error|warning)[^\w]', re.MULTILINE | re.IGNORECASE)
- IGNORE_WARNS = [
- re.compile(r_str) for r_str in [
- r'library/error\.o',
- r'/.*error\S*\.o',
- r'.*error.*\.c\.obj',
- r'.*error.*\.cpp\.obj',
- r'.*error.*\.cxx\.obj',
- r'.*error.*\.cc\.obj',
- r'-Werror',
- r'error\.d',
- r'/.*error\S*.d',
- r'reassigning to symbol',
- r'changes choice state',
- r'crosstool_version_check\.cmake',
- r'CryptographyDeprecationWarning',
- r'Warning: \d+/\d+ app partitions are too small for binary'
- ]
- ]
- def line_has_warnings(line): # type: (str) -> bool
- if not WARNING_REGEX.search(line):
- return False
- has_warnings = True
- for ignored in IGNORE_WARNS:
- if re.search(ignored, line):
- has_warnings = False
- break
- return has_warnings
- def main(): # type: () -> None
- parser = argparse.ArgumentParser(description='ESP-IDF app builder')
- parser.add_argument(
- '-v',
- '--verbose',
- action='count',
- help='Increase the logging level of the script. Can be specified multiple times.',
- )
- parser.add_argument(
- '--log-file',
- type=argparse.FileType('w'),
- help='Write the script log to the specified file, instead of stderr',
- )
- parser.add_argument(
- 'build_list',
- type=argparse.FileType('r'),
- nargs='?',
- default=sys.stdin,
- help='Name of the file to read the list of builds from. If not specified, read from stdin.',
- )
- args = parser.parse_args()
- setup_logging(args)
- build_items = [BuildItem.from_json(line) for line in args.build_list]
- if not build_items:
- logging.warning('Empty build list')
- SystemExit(0)
- found_warnings = 0
- for build_item in build_items:
- if not build_item.build_log_path:
- logging.debug('No log file for {}'.format(build_item.work_dir))
- continue
- with open(build_item.build_log_path, 'r') as log_file:
- for line_no, line in enumerate(log_file):
- if line_has_warnings(line):
- 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),
- line_no + 1))
- found_warnings += 1
- break
- if found_warnings:
- logging.error('Checked {} builds, found {} warnings'.format(len(build_items), found_warnings))
- raise SystemExit(1)
- logging.info('No warnings found')
- if __name__ == '__main__':
- main()
|