From e7730752b569444f57a5874a48ad28d6020eca6b Mon Sep 17 00:00:00 2001
From: Marta Rybczynska <marta.rybczynska@huawei.com>
Date: Fri, 17 Jun 2022 09:19:11 +0200
Subject: [PATCH] scripts/cve-report.py: rename from cve-json-to-csv and add
 summary

Make the report generation more customizable. Apart from the CSV report,
add also a summary report including the number of CVEs in each package.

Signed-off-by: Marta Rybczynska <marta.rybczynska@huawei.com>
---
 scripts/{cve-json-to-csv.py => cve-report.py} | 54 ++++++++++++++-----
 1 file changed, 42 insertions(+), 12 deletions(-)
 rename scripts/{cve-json-to-csv.py => cve-report.py} (69%)

diff --git a/scripts/cve-json-to-csv.py b/scripts/cve-report.py
similarity index 69%
rename from scripts/cve-json-to-csv.py
rename to scripts/cve-report.py
index b0ef1af6..98ab0599 100644
--- a/scripts/cve-json-to-csv.py
+++ b/scripts/cve-report.py
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: Apache-2.0
 
 # CVE-check example script
-# Convert the cve-check JSON output to a CSV file
+# Reporting based on the cve-check JSON format: conversion to CSV and summary
 
 import sys
 import getopt
@@ -11,6 +11,8 @@ import getopt
 infile = "in.json"
 outfile = "out.csv"
 show_all = False
+show_summary = False
+to_csv = False
 
 
 def show_syntax_and_exit(code):
@@ -19,9 +21,13 @@ def show_syntax_and_exit(code):
     Arguments:
         code: the error code to return
     """
-    print("Syntax: %s [-h][-i inputfile][-o outputfile] [-a]" % __name__)
+    print("Syntax: %s [-h] [-a] [-s] [-c] [-i inputfile][-o outputfile]" % sys.argv[0])
     print("Default files: in.json and out.csv")
-    print("Use -a or -all to list all issues, otherwise we filter only unpatched ones")
+    print(
+        "Use -c or --to-csv to generate a CSV report, output file is then needed, out.csv by default"
+    )
+    print("Use -a or --all to list all issues, otherwise we filter only unpatched ones")
+    print("Use -s or --summary to show a summary of the issues")
     sys.exit(code)
 
 
@@ -42,20 +48,26 @@ def parse_args(argv):
     Arguments:
         argv: program arguments
     """
-    global infile, outfile, show_all
+    global infile, outfile, show_all, show_summary, to_csv
     try:
-        opts, args = getopt.getopt(argv, "hi:o:a", ["input", "output"])
+        opts, args = getopt.getopt(
+            argv, "hi:o:asc", ["help", "input", "output", "summary", "to-csv"]
+        )
     except getopt.GetoptError:
         show_syntax_and_exit(1)
     for opt, arg in opts:
-        if opt == "-h":
+        if opt in ("-h", "--help"):
             show_syntax_and_exit(0)
+        elif opt in ("-a", "--all"):
+            show_all = True
         elif opt in ("-i", "--input"):
             infile = arg
+        elif opt in ("-c", "--to-csv"):
+            to_csv = True
         elif opt in ("-o", "--output"):
             outfile = arg
-        elif opt in ("-a", "--all"):
-            show_all = True
+        elif opt in ("-s", "--summary"):
+            show_summary = True
 
 
 def load_json(filename):
@@ -79,7 +91,7 @@ def load_json(filename):
     return out
 
 
-def write_csv(filename, data, unpatched_only):
+def process_data(filename, data, unpatched_only, do_summary, do_csv):
     """
     Write the resulting CSV with one line for each package
     Arguments:
@@ -95,6 +107,7 @@ def write_csv(filename, data, unpatched_only):
         exit_error(1, "Mandatory 'package' key not found")
 
     lines = ""
+    total_issue_count = 0
     for package in data["package"]:
         keys_in_package = {"name", "layer", "version", "issue"}
         if keys_in_package - package.keys():
@@ -107,6 +120,11 @@ def write_csv(filename, data, unpatched_only):
         package_name = package["name"]
         layer = package["layer"]
         package_version = package["version"]
+        package_summary = "Issues for package %s (version %s):\n\t" % (
+            package_name,
+            package_version,
+        )
+        issue_count = 0
 
         for issue in package["issue"]:
             keys_in_issue = {"id", "scorev2", "scorev3", "vector", "status"}
@@ -132,15 +150,27 @@ def write_csv(filename, data, unpatched_only):
                     scorev3,
                     vector,
                 )
+                package_summary += "%s " % (cve_id)
+                issue_count += 1
+
+        if do_summary and issue_count > 0:
+            package_summary += "\n\tCount: %d\n" % (issue_count)
+            print(package_summary)
+
+        total_issue_count += issue_count
+
+    if do_csv:
+        with open(filename, "w") as f:
+            f.write(lines)
 
-    with open(filename, "w") as f:
-        f.write(lines)
+    if do_summary:
+        print("Global issue count: %d" % (total_issue_count))
 
 
 def main(argv):
     parse_args(argv)
     data = load_json(infile)
-    write_csv(outfile, data, not show_all)
+    process_data(outfile, data, not show_all, show_summary, to_csv)
 
 
 if __name__ == "__main__":
-- 
GitLab