Repository: ericsson/codechecker
Issue: Unnecessarily generated empty HTML files from CodeChecker parse

**Describe the bug**
`CodeChecker parse reports -e html -o html` generates static HTML files which describe reports in the `report` directory. Such an HTML file is generated for each source files and each analyzers even if the given analyzer doesn't emit any report for the given source file. This "empty" HTML file contains the static frame of the page and its size is 204K. Earlier these files were not generated.

**CodeChecker version**
6.18.1 (current master)

**To Reproduce**
1. Create a source file:
```.c
int main() { sizeof(42); }
```
2. Analyze it: `CodeChecker check -b "gcc main.c" -o reports`
3. Parse the report directory: `CodeChecker parse reports -e html -o html`
4. The resulting `html` directory contains a `.html` for the non-existing reports of ClangSA.

Changed files:
tools/report-converter/codechecker_report_converter/report/output/html/html.py, analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py

diff --git a/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py b/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py
index 12107c7e..6120a55e 100644
--- a/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py
+++ b/analyzer/tests/functional/analyze_and_parse/test_analyze_and_parse.py
@@ -16,6 +16,7 @@ import re
 import shlex
 import shutil
 import subprocess
+import tempfile
 import unittest
 
 from subprocess import CalledProcessError
@@ -24,6 +25,7 @@ from libtest import env
 from libtest import project
 from libtest.codechecker import call_command
 
+from codechecker_report_converter.report import report_file
 from codechecker_report_converter.report.output import baseline
 
 
@@ -640,3 +642,45 @@ class AnalyzeParseTestCase(
         report_hashes = baseline.get_report_hashes([out_file_path])
         self.assertEqual(
             report_hashes, {'3d15184f38c5fa57e479b744fe3f5035'})
+
+    def test_html_output_for_empty_plist(self):
+        """
+        Test that HTML files for empty plist files will not be generated.
+        """
+        with tempfile.TemporaryDirectory() as tmp_dir:
+            plist_file_name = 'empty.plist'
+            plist_file_path = os.path.join(tmp_dir, plist_file_name)
+            report_file.create(plist_file_path, [])
+
+            test_project_notes = os.path.join(
+                self.test_workspaces['NORMAL'], "test_files", "notes",
+                "notes.plist")
+            shutil.copy(test_project_notes, tmp_dir)
+
+            output_path = os.path.join(tmp_dir, 'html')
+            extract_cmd = [
+                'CodeChecker', 'parse',
+                '-e', 'html',
+                '-o', output_path,
+                tmp_dir]
+
+            out, err, result = call_command(
+                extract_cmd, cwd=self.test_dir, env=self.env)
+
+            self.assertEqual(result, 2)
+            self.assertFalse(err)
+
+            self.assertTrue(f'No report data in {plist_file_path}' in out)
+            self.assertTrue(f'Html file was generated:' in out)
+            self.assertTrue('Summary' in out)
+            self.assertTrue('statistics.html' in out)
+            self.assertTrue('index.html' in out)
+
+            self.assertTrue(os.path.exists(
+                os.path.join(output_path, 'index.html')))
+            self.assertTrue(os.path.exists(
+                os.path.join(output_path, 'statistics.html')))
+            self.assertTrue(os.path.exists(
+                os.path.join(output_path, 'notes.plist.html')))
+            self.assertFalse(os.path.exists(
+                os.path.join(output_path, f'{plist_file_name}.html')))
diff --git a/tools/report-converter/codechecker_report_converter/report/output/html/html.py b/tools/report-converter/codechecker_report_converter/report/output/html/html.py
index a68bd4c0..01157cbd 100644
--- a/tools/report-converter/codechecker_report_converter/report/output/html/html.py
+++ b/tools/report-converter/codechecker_report_converter/report/output/html/html.py
@@ -442,18 +442,18 @@ def convert(
     Returns the skipped analyzer result files because of source
     file content change.
     """
+    if not reports:
+        LOG.info(f'No report data in {file_path} file.')
+        return set()
+
     html_filename = f"{os.path.basename(file_path)}.html"
     html_output_path = os.path.join(output_dir_path, html_filename)
-    html_reports, changed_files = html_builder.create(
+    _, changed_files = html_builder.create(
         html_output_path, reports)
 
     if changed_files:
         return changed_files
 
-    if not html_reports:
-        LOG.info(f'No report data in {file_path} file.')
-        return changed_files
-
     LOG.info(f"Html file was generated: {html_output_path}")
     return changed_files