[clang] 97a304c - [scan-build-py] Add sarif-html support in scan-build-py

Marco Vanotti via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 23 14:41:58 PST 2021


Author: Daniel Hwang
Date: 2021-02-23T14:41:48-08:00
New Revision: 97a304cc8f949e40693d63b855b4b24bc81fa729

URL: https://github.com/llvm/llvm-project/commit/97a304cc8f949e40693d63b855b4b24bc81fa729
DIFF: https://github.com/llvm/llvm-project/commit/97a304cc8f949e40693d63b855b4b24bc81fa729.diff

LOG: [scan-build-py] Add sarif-html support in scan-build-py

Update scan-build-py to be able to trigger sarif-html output format in clang static analyzer.

NOTE: testcase `test_sarif_and_html_creates_sarif_and_html_reports` will fail if the default clang does not have change https://reviews.llvm.org/D96389 . This can be remediated by pointing the default clang in arguments.py to a locally built clang. I was unable to figure out where these particular tests for scan-build-py are being invoked (aside from manually), so any help there would be greatly appreciated.

Reviewed By: aabbaabb, xazax.hun

Differential Revision: https://reviews.llvm.org/D96570

Added: 
    

Modified: 
    clang/tools/scan-build-py/libscanbuild/analyze.py
    clang/tools/scan-build-py/libscanbuild/arguments.py
    clang/tools/scan-build-py/libscanbuild/report.py
    clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py

Removed: 
    


################################################################################
diff  --git a/clang/tools/scan-build-py/libscanbuild/analyze.py b/clang/tools/scan-build-py/libscanbuild/analyze.py
index dbe08be9b24a..9a249a8e15cb 100644
--- a/clang/tools/scan-build-py/libscanbuild/analyze.py
+++ b/clang/tools/scan-build-py/libscanbuild/analyze.py
@@ -356,11 +356,14 @@ def report_directory(hint, keep, output_format):
         yield name
     finally:
         if os.listdir(name):
-            if output_format != 'sarif':
+            if output_format not in ['sarif', 'sarif-html']: # FIXME:
                 # 'scan-view' currently does not support sarif format.
                 msg = "Run 'scan-view %s' to examine bug reports."
+            elif output_format == 'sarif-html':
+                msg = "Run 'scan-view %s' to examine bug reports or see " \
+                    "merged sarif results at %s/results-merged.sarif."
             else:
-                msg = "View result at %s/results-merged.sarif."
+                msg = "View merged sarif results at %s/results-merged.sarif."
             keep = True
         else:
             if keep:
@@ -438,7 +441,7 @@ def wrapper(*args, **kwargs):
           'direct_args',  # arguments from command line
           'force_debug',  # kill non debug macros
           'output_dir',  # where generated report files shall go
-          'output_format',  # it's 'plist', 'html', 'plist-html', 'plist-multi-file', or 'sarif'
+          'output_format',  # it's 'plist', 'html', 'plist-html', 'plist-multi-file', 'sarif', or 'sarif-html'
           'output_failures',  # generate crash reports or not
           'ctu'])  # ctu control options
 def run(opts):
@@ -542,7 +545,9 @@ def target():
                                               dir=opts['output_dir'])
             os.close(handle)
             return name
-        elif opts['output_format'] == 'sarif':
+        elif opts['output_format'] in {
+                'sarif',
+                'sarif-html'}:
             (handle, name) = tempfile.mkstemp(prefix='result-',
                                               suffix='.sarif',
                                               dir=opts['output_dir'])

diff  --git a/clang/tools/scan-build-py/libscanbuild/arguments.py b/clang/tools/scan-build-py/libscanbuild/arguments.py
index e1d654b331cb..7af25ecdf302 100644
--- a/clang/tools/scan-build-py/libscanbuild/arguments.py
+++ b/clang/tools/scan-build-py/libscanbuild/arguments.py
@@ -252,6 +252,14 @@ def create_analyze_parser(from_build_command):
         default='html',
         action='store_const',
         help="""Cause the results as a result.sarif file.""")
+    format_group.add_argument(
+        '--sarif-html',
+        '-sarif-html',
+        dest='output_format',
+        const='sarif-html',
+        default='html',
+        action='store_const',
+        help="""Cause the results as a result.sarif file and .html files.""")
 
     advanced = parser.add_argument_group('advanced options')
     advanced.add_argument(

diff  --git a/clang/tools/scan-build-py/libscanbuild/report.py b/clang/tools/scan-build-py/libscanbuild/report.py
index 734f530ebfc1..46338b86d26d 100644
--- a/clang/tools/scan-build-py/libscanbuild/report.py
+++ b/clang/tools/scan-build-py/libscanbuild/report.py
@@ -26,8 +26,8 @@
 def document(args):
     """ Generates cover report and returns the number of bugs/crashes. """
 
-    html_reports_available = args.output_format in {'html', 'plist-html'}
-    sarif_reports_available = args.output_format in {'sarif'}
+    html_reports_available = args.output_format in {'html', 'plist-html', 'sarif-html'}
+    sarif_reports_available = args.output_format in {'sarif', 'sarif-html'}
 
     logging.debug('count crashes and bugs')
     crash_count = sum(1 for _ in read_crashes(args.output))

diff  --git a/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py b/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
index 7af3eea4dd5e..90db89f62636 100644
--- a/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
+++ b/clang/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
@@ -102,7 +102,11 @@ def get_html_count(directory):
     def get_plist_count(directory):
         return len(glob.glob(os.path.join(directory, 'report-*.plist')))
 
-    def test_default_creates_html_report(self):
+    @staticmethod
+    def get_sarif_count(directory):
+        return len(glob.glob(os.path.join(directory, 'result-*.sarif')))
+
+    def test_default_only_creates_html_report(self):
         with libear.TemporaryDirectory() as tmpdir:
             cdb = prepare_cdb('regular', tmpdir)
             exit_code, reportdir = run_analyzer(tmpdir, cdb, [])
@@ -110,8 +114,9 @@ def test_default_creates_html_report(self):
                 os.path.exists(os.path.join(reportdir, 'index.html')))
             self.assertEqual(self.get_html_count(reportdir), 2)
             self.assertEqual(self.get_plist_count(reportdir), 0)
+            self.assertEqual(self.get_sarif_count(reportdir), 0)
 
-    def test_plist_and_html_creates_html_report(self):
+    def test_plist_and_html_creates_html_and_plist_reports(self):
         with libear.TemporaryDirectory() as tmpdir:
             cdb = prepare_cdb('regular', tmpdir)
             exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist-html'])
@@ -119,8 +124,9 @@ def test_plist_and_html_creates_html_report(self):
                 os.path.exists(os.path.join(reportdir, 'index.html')))
             self.assertEqual(self.get_html_count(reportdir), 2)
             self.assertEqual(self.get_plist_count(reportdir), 5)
+            self.assertEqual(self.get_sarif_count(reportdir), 0)
 
-    def test_plist_does_not_creates_html_report(self):
+    def test_plist_only_creates_plist_report(self):
         with libear.TemporaryDirectory() as tmpdir:
             cdb = prepare_cdb('regular', tmpdir)
             exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--plist'])
@@ -128,6 +134,31 @@ def test_plist_does_not_creates_html_report(self):
                 os.path.exists(os.path.join(reportdir, 'index.html')))
             self.assertEqual(self.get_html_count(reportdir), 0)
             self.assertEqual(self.get_plist_count(reportdir), 5)
+            self.assertEqual(self.get_sarif_count(reportdir), 0)
+
+    def test_sarif_only_creates_sarif_result(self):
+        with libear.TemporaryDirectory() as tmpdir:
+            cdb = prepare_cdb('regular', tmpdir)
+            exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--sarif'])
+            self.assertFalse(
+                os.path.exists(os.path.join(reportdir, 'index.html')))
+            self.assertTrue(
+                os.path.exists(os.path.join(reportdir, 'results-merged.sarif')))
+            self.assertEqual(self.get_html_count(reportdir), 0)
+            self.assertEqual(self.get_plist_count(reportdir), 0)
+            self.assertEqual(self.get_sarif_count(reportdir), 5)
+
+    def test_sarif_and_html_creates_sarif_and_html_reports(self):
+        with libear.TemporaryDirectory() as tmpdir:
+            cdb = prepare_cdb('regular', tmpdir)
+            exit_code, reportdir = run_analyzer(tmpdir, cdb, ['--sarif-html'])
+            self.assertTrue(
+                os.path.exists(os.path.join(reportdir, 'index.html')))
+            self.assertTrue(
+                os.path.exists(os.path.join(reportdir, 'results-merged.sarif')))
+            self.assertEqual(self.get_html_count(reportdir), 2)
+            self.assertEqual(self.get_plist_count(reportdir), 0)
+            self.assertEqual(self.get_sarif_count(reportdir), 5)
 
 
 class FailureReportTest(unittest.TestCase):


        


More information about the cfe-commits mailing list