Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # |
Leonardo Sandoval | 579c737 | 2020-10-23 15:23:32 -0500 | [diff] [blame^] | 3 | # Copyright (c) 2019-2020 Arm Limited. All rights reserved. |
Fathi Boudra | 422bf77 | 2019-12-02 11:10:16 +0200 | [diff] [blame] | 4 | # |
| 5 | # SPDX-License-Identifier: BSD-3-Clause |
| 6 | # |
| 7 | # |
| 8 | # Given URL to a job instance, this script walks the job hierarchy, and inspects |
| 9 | # for Coverity scan report. CIDs from individual reports are collected and |
| 10 | # printed as a summary of defects for the entire scan. |
| 11 | |
| 12 | import argparse |
| 13 | import coverity_parser |
| 14 | import job_walker |
| 15 | import json |
| 16 | import sys |
| 17 | import urllib.request |
| 18 | |
| 19 | parser = argparse.ArgumentParser() |
| 20 | parser.add_argument("build_url", |
| 21 | help="URL to specific build number to walk") |
| 22 | opts = parser.parse_args() |
| 23 | |
| 24 | # Parse the given job |
| 25 | top = job_walker.JobInstance(opts.build_url) |
| 26 | top.parse() |
| 27 | |
| 28 | # Iterate through terminal jobs, i.e., those with a config, viz. tf-worker |
| 29 | merged_issues = {} |
| 30 | for job in filter(lambda j: j.config, top.walk()): |
| 31 | # Collect CIDs from archived defects.json |
| 32 | try: |
| 33 | # Open json as text, not bytes |
| 34 | with job.open_artefact("defects.json", text=True) as fd: |
| 35 | issues = json.load(fd) |
| 36 | except urllib.error.HTTPError: |
| 37 | print("warning: unable to read defects.json from " + job.url, |
| 38 | file=sys.stderr) |
| 39 | continue |
| 40 | |
| 41 | merged_issues.update({coverity_parser.make_key(i): i for i in issues}) |
| 42 | |
| 43 | # Sort merged issues by file name, line number, checker, and then CID. |
| 44 | sorted_issue_keys = sorted(merged_issues.keys()) |
| 45 | |
| 46 | if sorted_issue_keys: |
| 47 | # Generate HTML table with issue description |
| 48 | print(""" |
| 49 | <style> |
| 50 | #coverity-table { |
| 51 | display: block; |
| 52 | max-height: 600px; |
| 53 | overflow-y: auto; |
| 54 | } |
| 55 | #coverity-table thead td { |
| 56 | font-weight: bold; |
| 57 | } |
| 58 | #coverity-table td { |
| 59 | font-size: 0.9em; |
| 60 | } |
| 61 | #coverity-table .cov-file { |
| 62 | color: brown; |
| 63 | } |
| 64 | #coverity-table .cov-line { |
| 65 | color: darkviolet; |
| 66 | } |
| 67 | #coverity-table .cov-cid { |
| 68 | color: orangered; |
| 69 | } |
| 70 | #coverity-table .cov-mandatory { |
| 71 | background-color: #ff4d4d; |
| 72 | } |
| 73 | #coverity-table .cov-required { |
| 74 | background-color: #ffcccc; |
| 75 | } |
| 76 | </style> |
| 77 | <table id="coverity-table" cellpadding="2"> |
| 78 | <thead> |
| 79 | <tr> |
| 80 | <td>File</td> |
| 81 | <td>Line</td> |
| 82 | <td>Checker</td> |
| 83 | <td>CID</td> |
| 84 | <td>Description</td> |
| 85 | </tr> |
| 86 | </thead><tbody>""") |
| 87 | for key in sorted_issue_keys: |
| 88 | print(coverity_parser.format_issue_html(merged_issues[key])) |
| 89 | print("</tbody></table>") |
| 90 | print('<div style="line-height: 3em; font-weight: bold;">{} defects reported.</div>'.format( |
| 91 | len(sorted_issue_keys))) |