1
0
Fork 0

Merge pull request #5 from dreamer/po/ci-improvements-1

Enforce limit on issues found in static analysis
This commit is contained in:
krcroft 2019-09-26 13:30:30 -07:00 committed by GitHub
commit 57aaed6399
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 12 deletions

View file

@ -12,7 +12,7 @@ jobs:
- name: "Install packages"
run: sudo apt-get install libsdl1.2-dev libsdl-net1.2-dev libsdl-sound1.2-dev python3-setuptools
- name: "Install scan-build (Python version)"
run: sudo pip3 install scan-build
run: sudo pip3 install scan-build beautifulsoup4 html5lib
- name: Build
run: |
# build steps
@ -27,3 +27,9 @@ jobs:
with:
name: report
path: report
- name: Summarize report
run: |
# summary
echo "Full report is included in build Artifacts"
echo
./scripts/count-bugs.py report/*/index.html

74
scripts/count-bugs.py Executable file
View file

@ -0,0 +1,74 @@
#!/usr/bin/python3
# Copyright (c) 2019 Patryk Obara <patryk.obara@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later
# This script prints a summary snippet of information out of reports created
# by scan-build or analyze-build for Clang's static code analysis.
#
# Usage: ./count-warnings.py path/to/report/index.html
#
# This script depends on BeautifulSoup module, if you're distribution is
# missing it, you can use pipenv to install it for virtualenv spanning only
# this repo: pipenv install beautifulsoup4 html5lib
# pylint: disable=invalid-name
# pylint: disable=missing-docstring
import sys
from bs4 import BeautifulSoup
# Maximum allowed number of issues; if report will include more bugs,
# then script will return with status 1. Simply change this line if you
# want to set a different limit.
#
MAX_ISSUES = 113
def summary_values(summary_table):
if not summary_table:
return
for row in summary_table.find_all('tr'):
description = row.find('td', 'SUMM_DESC')
value = row.find('td', 'Q')
if description is None or value is None:
continue
yield description.get_text(), int(value.get_text())
def read_soup(index_html):
with open(index_html) as index:
soup = BeautifulSoup(index, 'html5lib')
tables = soup.find_all('table')
summary = tables[1]
return {bug: count for bug, count in summary_values(summary)}
def find_longest_name_length(names):
return max(len(x) for x in names)
def print_summary(issues):
summary = list(issues.items())
size = find_longest_name_length(issues.keys()) + 1
for warning, count in sorted(summary, key=lambda x: -x[1]):
print(' {text:{field_size}s}: {count}'.format(
text=warning, count=count, field_size=size))
print()
def main():
bug_types = read_soup(sys.argv[1])
total = bug_types.pop('All Bugs')
if bug_types:
print("Bugs grouped by type:\n")
print_summary(bug_types)
print('Total: {} bugs (out of {} allowed)\n'.format(total, MAX_ISSUES))
if total > MAX_ISSUES:
print('Error: upper limit of allowed bugs is', MAX_ISSUES)
sys.exit(1)
if __name__ == '__main__':
main()

29
scripts/count-warnings.py Normal file → Executable file
View file

@ -1,8 +1,9 @@
#!/usr/bin/python3
# Copyright (c) 2019 Patryk Obara
# Copyright (c) 2019 Patryk Obara <patryk.obara@gmail.com>
# SPDX-License-Identifier: GPL-2.0-or-later
# This script counts and all warnings and prints a summary.
# This script counts all compiler warnings and prints a summary.
#
# Usage: ./count-warnings.py build.log
# Usage: cat "*.log" | ./count-warnings.py -
@ -18,11 +19,11 @@ import os
import re
import sys
# Maximum allowed number of warnings; if build will include more warnings,
# Maximum allowed number of issues; if build will include more warnings,
# then script will return with status 1. Simply change this line if you
# want to set a different limit.
#
MAX_WARNINGS = 357
MAX_ISSUES = 357
# For recognizing warnings in GCC format in stderr:
#
@ -63,11 +64,16 @@ def get_input_lines(name):
return logs.readlines()
def print_summary(warning_types):
print("Warnings grouped by type:\n")
summary = list(warning_types.items())
def find_longest_name_length(names):
return max(len(x) for x in names)
def print_summary(issues):
summary = list(issues.items())
size = find_longest_name_length(issues.keys()) + 1
for warning, count in sorted(summary, key=lambda x: -x[1]):
print(' {:28s}: {}'.format(warning, count))
print(' {text:{field_size}s}: {count}'.format(
text=warning, count=count, field_size=size))
print()
@ -77,10 +83,11 @@ def main():
for line in get_input_lines(sys.argv[1]):
total += count_warning(line, warning_types)
if warning_types:
print("Warnings grouped by type:\n")
print_summary(warning_types)
print('Total: {} warnings\n'.format(total))
if total > MAX_WARNINGS:
print('Error: upper limit of warnings is', MAX_WARNINGS)
print('Total: {} warnings (out of {} allowed)\n'.format(total, MAX_ISSUES))
if total > MAX_ISSUES:
print('Error: upper limit of allowed warnings is', MAX_ISSUES)
sys.exit(1)