Files
pkgscripts-ng/include/errors.py
2020-09-18 09:05:10 +00:00

128 lines
3.2 KiB
Python
Executable File

#!/usr/bin/env python
# Copyright (c) 2000-2020 Synology Inc. All rights reserved.
import sys
import os
import re
import json
import subprocess
sys.path.append(os.path.dirname(os.path.abspath(sys.argv[0])) + '/python')
import BuildEnv
LOG_DIR = '/logs'
# "error_pattern": skip_list
BUILD_ERROR_CHECKLIST = {
"line.*syntax error": [],
"Error": ['ignored', 'Error\.[c|o|h|cc|lo|Plo|js]', 'GPG Error', 'distclean'],
"fatal error": [],
"missing separator": [],
"No rule to make target": ["clean", "distclean"],
"don't know": [],
"error:": [],
"was not found in the pkg-config search path": [],
"ld: cannot find": [],
}
INSTALL_ERROR_CHECKLIST = {
"No such file or directory": []
}
def is_skipped_error(error, skip_list):
if not skip_list:
return False
for skip in skip_list:
if skip and re.search(skip, error):
return True
return False
def find_errors(check_list, log):
result = []
for error in check_list:
regex = re.compile(error)
found_error = False
index = 0
for line in log:
index += 1
line = line.strip()
if regex.search(line) and not is_skipped_error(line, check_list[error]):
if not found_error:
result.append('====== Find pattern [%s] ======' % error)
found_error = True
result.append('%s: %s' % (str(index), line))
return result
def load_project_setting(proj, check_list):
error_script = BuildEnv.Project(proj).error_script
if not error_script or not os.path.isfile(error_script):
return
with open(error_script, 'r') as error_skip_file:
try:
error_skip_list = json.load(error_skip_file)
except ValueError:
raise RuntimeError("Can't parse error file %s." % error_script)
for error in error_skip_list:
if error not in check_list:
check_list[error] = error_skip_list[error]
continue
skips = error_skip_list[error]
if isinstance(skips, basestring):
check_list[error].append(skips)
elif isinstance(skips, list):
check_list[error].extend(skips)
else:
raise RuntimeError("Wrong value type: %s." % skips)
def find_project_log(proj, log_type):
return os.path.join(LOG_DIR, proj + '.' + log_type)
def main():
proj = sys.argv[2]
log_type = sys.argv[1]
errors = None
check_list = BUILD_ERROR_CHECKLIST
if log_type == 'install':
check_list.update(INSTALL_ERROR_CHECKLIST)
load_project_setting(proj, check_list)
# If log file doesn't write back to disk, there will raise IOError because of log file not found.
# Do `sync` and reopen file again to prevent log file not found.
try:
log = open(find_project_log(proj, log_type), 'r')
except IOError:
subprocess.check_call(['sync'])
log = open(find_project_log(proj, log_type), 'r')
errors = find_errors(check_list, log.readlines())
log.close()
if errors:
print("\n".join(errors))
sys.exit(2)
sys.exit(0)
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: ./error.py log_type project")
sys.exit(1)
main()