Count the bugs reported by PVS-Studio
This commit is contained in:
parent
7c4c246082
commit
9df802fd56
2 changed files with 95 additions and 4 deletions
21
.github/workflows/analysis.yml
vendored
21
.github/workflows/analysis.yml
vendored
|
@ -94,19 +94,32 @@ jobs:
|
|||
sudo dpkg -i "pvs-package/pvs.deb"
|
||||
pvs-studio-analyzer credentials "${{ secrets.PvsStudioName }}" "${{ secrets.PvsStudioKey }}"
|
||||
- name: Build
|
||||
run: pvs-studio-analyzer trace -- ./scripts/build.sh -c gcc -t debug
|
||||
run: |
|
||||
set -xeu
|
||||
./autogen.sh
|
||||
export FLAGS="-Og"
|
||||
./configure CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}"
|
||||
pvs-studio-analyzer trace -- make
|
||||
- name: Analyze
|
||||
run: |
|
||||
set -xeu
|
||||
pvs-studio-analyzer analyze -o pvs-analysis.log -j "$(nproc)"
|
||||
plog-converter -a "64:1;OP:1,2,3;CS:1;MISRA:1,2" \
|
||||
-p "dosbox-staging" -v "${GITHUB_SHA:0:8}" -t "fullhtml" \
|
||||
-d "V1042" -o "pvs-analysis-report" "pvs-analysis.log"
|
||||
criteria="GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2"
|
||||
plog-converter -a "${criteria}" -d V1042 -t csv -o pvs-report.csv pvs-analysis.log
|
||||
plog-converter -a "${criteria}" -d V1042 -t fullhtml -p dosbox-staging \
|
||||
-v "${GITHUB_SHA:0:8}" -o pvs-analysis-report pvs-analysis.log
|
||||
- name: Upload report
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: pvs-analysis-report
|
||||
path: pvs-analysis-report
|
||||
- name: Summarize report
|
||||
env:
|
||||
MAX_BUGS: 356
|
||||
run: |
|
||||
echo "Full report is included in build Artifacts"
|
||||
echo
|
||||
./scripts/count-pvs-bugs.py pvs-report.csv "${MAX_BUGS}"
|
||||
|
||||
dynamic_matrix:
|
||||
name: ${{ matrix.compiler }} dynamic sanitizers
|
||||
|
|
78
scripts/count-pvs-bugs.py
Executable file
78
scripts/count-pvs-bugs.py
Executable file
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (C) 2020 Kevin Croft <krcroft@gmail.com>
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Count the number of issues found in an PVS-Studio report.
|
||||
|
||||
Usage: count-pvs-issues.py REPORT [MAX-ISSUES]
|
||||
Where:
|
||||
- REPORT is a file in CSV-format
|
||||
- MAX-ISSUES is as a positive integer indicating the maximum
|
||||
issues that should be permitted before returning failure
|
||||
to the shell. Default is non-limit.
|
||||
|
||||
"""
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
import collections
|
||||
import csv
|
||||
import os
|
||||
import sys
|
||||
|
||||
def parse_issues(filename):
|
||||
"""
|
||||
Returns a dict of int keys and a list of string values, where the:
|
||||
- keys are V### PVS-Studio error codes
|
||||
- values are the message of the issue as found in a specific file
|
||||
|
||||
"""
|
||||
issues = collections.defaultdict(list)
|
||||
with open(filename) as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
full = row['ErrorCode'] # extract the full code as an URL string
|
||||
code = full[full.rfind('V'):full.rfind('"')] # get the trailing "V###" code
|
||||
if code.startswith('V'):
|
||||
# Convert the V### string into an integer for easy sorting
|
||||
issues[int(code[1:])].append(row['Message'])
|
||||
return issues
|
||||
|
||||
|
||||
def main(argv):
|
||||
# assume success until proven otherwise
|
||||
rcode = 0
|
||||
|
||||
# Get the issues and the total tally
|
||||
issues = parse_issues(argv[1])
|
||||
tally = sum(len(messages) for messages in issues.values())
|
||||
|
||||
if tally > 0:
|
||||
# Step through the codes and summarize
|
||||
print("Issues are tallied and sorted by code:\n")
|
||||
print(" code | issue-string in common to all instances | tally")
|
||||
print(" ----- --------------------------------------------- -----")
|
||||
|
||||
for code in sorted(issues.keys()):
|
||||
messages = issues[code]
|
||||
in_common = os.path.commonprefix(messages)[:45]
|
||||
if len(in_common.split(' ')) < 4:
|
||||
in_common = 'N/A (too little in-common between issues)'
|
||||
print(f' [{code:4}] {in_common:45} : {len(messages)}')
|
||||
|
||||
# Print the tally against the desired maximum
|
||||
if len(sys.argv) == 3:
|
||||
max_issues = int(sys.argv[2])
|
||||
print(f'\nTotal: {tally} issues (out of {max_issues} allowed)')
|
||||
if tally > max_issues:
|
||||
rcode = 1
|
||||
else:
|
||||
print(f'\nTotal: {tally} issues')
|
||||
|
||||
return rcode
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
Loading…
Add table
Reference in a new issue