Skip to content

Commit 9004c10

Browse files
Merge pull request Ericsson#3588 from milanlakhani/lano/reportconverter-files
Avoid plist filenames being the same
2 parents 3246665 + 1c36d2f commit 9004c10

28 files changed

+146
-74
lines changed

docs/tools/report-converter.md

+9-8
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,15 @@ optional arguments:
8484
file name output of this tool. This tool can produce
8585
multiple plist files on the given code analyzer output
8686
result file. The problem is if we run this tool
87-
multiple times on the same directory, it may override
88-
some plist files. To prevent this we can generate a
89-
unique hash into the plist file names with this
90-
option. For example: '{source_file}_{analyzer}_xxxxx'.
91-
{source_file} and {analyzer} are special values which
92-
will be replaced with the current analyzer and source
93-
file name where the bug was found. (default:
94-
{source_file}_{analyzer})
87+
multiple times on the same file, it may override some
88+
plist files. To prevent this we can generate a unique
89+
hash into the plist file names with this option. For
90+
example: '{source_file}_{analyzer}_{file_hash}_xxxxx'.
91+
{source_file}, {analyzer} and {file_hash} are special
92+
values which will be replaced with the current
93+
analyzer, source file name and hash of the absolute
94+
file path where the bug was found. (default:
95+
{source_file}_{analyzer}_{file_hash})
9596
-c, --clean Delete files stored in the output directory. (default:
9697
False)
9798
-v, --verbose Set verbosity level. (default: False)

tools/report-converter/codechecker_report_converter/analyzers/analyzer_result.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from abc import ABCMeta, abstractmethod
1414
from collections import defaultdict
15+
import hashlib
1516
from typing import Dict, List, Optional
1617

1718
from codechecker_report_converter.report import Report, report_file
@@ -39,7 +40,7 @@ def transform(
3940
analyzer_result_file_path: str,
4041
output_dir_path: str,
4142
export_type: str,
42-
file_name: str = "{source_file}_{analyzer}",
43+
file_name: str = "{source_file}_{analyzer}_{file_hash}",
4344
metadata: Optional[Dict[str, str]] = None
4445
) -> bool:
4546
"""
@@ -143,15 +144,19 @@ def _write(
143144

144145
file_to_report: Dict[str, List[Report]] = defaultdict(list)
145146
for report in reports:
146-
file_to_report[report.file.original_path].append(report)
147+
file_path = os.path.normpath(report.file.original_path)
148+
file_to_report[file_path].append(report)
147149

148150
analyzer_info = AnalyzerInfo(name=self.TOOL_NAME)
149151
for file_path, file_reports in file_to_report.items():
150152
source_file = os.path.basename(file_path)
153+
file_hash = hashlib.md5(file_path.encode(errors='ignore')) \
154+
.hexdigest()
151155

152156
out_file_name = file_name \
153157
.replace("{source_file}", source_file) \
154-
.replace("{analyzer}", self.TOOL_NAME)
158+
.replace("{analyzer}", self.TOOL_NAME) \
159+
.replace("{file_hash}", file_hash)
155160
out_file_name = f"{out_file_name}.{export_type}"
156161
out_file_path = os.path.join(output_dir, out_file_name)
157162

tools/report-converter/codechecker_report_converter/cli.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -172,20 +172,22 @@ def __add_arguments_to_parser(parser):
172172
type=str,
173173
dest='filename',
174174
metavar='FILENAME',
175-
default="{source_file}_{analyzer}",
175+
default="{source_file}_{analyzer}_{file_hash}",
176176
help="This option can be used to override the default "
177177
"plist file name output of this tool. This tool "
178178
"can produce multiple plist files on the given "
179179
"code analyzer output result file. The problem "
180180
"is if we run this tool multiple times on the "
181-
"same directory, it may override some plist "
182-
"files. To prevent this we can generate a unique "
183-
"hash into the plist file names with this "
184-
"option. For example: "
185-
"'{source_file}_{analyzer}_xxxxx'. {source_file} "
186-
"and {analyzer} are special values which will "
187-
"be replaced with the current analyzer and "
188-
"source file name where the bug was found.")
181+
"same file, it may override some plist files. To "
182+
"prevent this we can generate a unique hash into "
183+
"the plist file names with this option. For "
184+
"example: "
185+
"'{source_file}_{analyzer}_{file_hash}_xxxxx'. "
186+
"{source_file}, {analyzer} and {file_hash} are "
187+
"special values which will be replaced with the "
188+
"current analyzer, source file name and hash of "
189+
"the absolute file path where the bug was "
190+
"found. ")
189191

190192
parser.add_argument('-c', '--clean',
191193
dest="clean",

tools/report-converter/tests/functional/cmdline/test_cmdline.py

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
This module tests the report-converter tool.
1111
"""
1212

13+
import glob
1314
import json
1415
import os
1516
import subprocess
@@ -39,6 +40,9 @@ def test_metadata(self):
3940
'analyzer_command=' + analyzer_command])
4041
self.assertEqual(0, ret)
4142

43+
self.assertEqual(
44+
len(glob.glob(os.path.join(tmp_dir, '*.plist'))), 2)
45+
4246
metadata_file = os.path.join(tmp_dir, "metadata.json")
4347
self.assertTrue(os.path.exists(metadata_file))
4448

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
all:
2-
golint ./files/simple.go > simple.out
2+
golint ./files/simple.go ./files/b/simple.go > simple.out
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package pgk
2+
3+
type T2 int
4+
5+
var Y2, Z2 int
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
./files/simple.go:3:6: exported type T should have comment or be unexported
22
./files/simple.go:5:5: exported var Z should have its own declaration
3+
./files/b/simple.go:3:6: exported type T2 should have comment or be unexported
4+
./files/b/simple.go:5:5: exported var Z2 should have its own declaration

tools/report-converter/tests/unit/analyzers/test_asan_parser.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ def tearDown(self):
5252
def test_asan(self):
5353
""" Test for the asan.plist file. """
5454
self.analyzer_result.transform(
55-
'asan.out', self.cc_result_dir, plist.EXTENSION)
55+
'asan.out', self.cc_result_dir, plist.EXTENSION,
56+
file_name="{source_file}_{analyzer}")
5657

5758
with open('asan.plist', mode='rb') as pfile:
5859
exp = plistlib.load(pfile)

tools/report-converter/tests/unit/analyzers/test_clang_tidy_parser.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ def __check_analyzer_result(self, analyzer_result, analyzer_result_plist,
5454
source_files, expected_plist):
5555
""" Check the result of the analyzer transformation. """
5656
self.analyzer_result.transform(
57-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
57+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
58+
file_name="{source_file}_{analyzer}")
5859

5960
plist_file = os.path.join(self.cc_result_dir, analyzer_result_plist)
6061
with open(plist_file, mode='rb') as pfile:

tools/report-converter/tests/unit/analyzers/test_coccinelle_parser.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,25 @@ def test_no_cocci_output_file(self):
4343
'sample.c')
4444

4545
ret = self.analyzer_result.transform(
46-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
46+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
47+
file_name="{source_file}_{analyzer}")
4748
self.assertFalse(ret)
4849

4950
def test_transform_dir(self):
5051
""" Test transforming a directory. """
5152
analyzer_result = os.path.join(self.test_files)
5253

5354
ret = self.analyzer_result.transform(
54-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
55+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
56+
file_name="{source_file}_{analyzer}")
5557
self.assertFalse(ret)
5658

5759
def test_transform_single_file(self):
5860
""" Test transforming single output file. """
5961
analyzer_result = os.path.join(self.test_files, 'sample.out')
6062
self.analyzer_result.transform(
61-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
63+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
64+
file_name="{source_file}_{analyzer}")
6265

6366
plist_file = os.path.join(self.cc_result_dir,
6467
'sample.c_coccinelle.plist')

tools/report-converter/tests/unit/analyzers/test_cppcheck_parser.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,26 @@ def test_no_plist_file(self):
5959
'divide_zero.cpp')
6060

6161
ret = self.analyzer_result.transform(
62-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
62+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
63+
file_name="{source_file}_{analyzer}")
6364
self.assertFalse(ret)
6465

6566
def test_no_plist_dir(self):
6667
""" Test transforming single plist file. """
6768
analyzer_result = os.path.join(self.test_files, 'non_existing')
6869

6970
ret = self.analyzer_result.transform(
70-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
71+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
72+
file_name="{source_file}_{analyzer}")
7173
self.assertFalse(ret)
7274

7375
def test_transform_single_file(self):
7476
""" Test transforming single plist file. """
7577
analyzer_result = os.path.join(
7678
self.test_files, 'out', 'divide_zero.plist')
7779
self.analyzer_result.transform(
78-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
80+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
81+
file_name="{source_file}_{analyzer}")
7982

8083
plist_file = os.path.join(self.cc_result_dir,
8184
'divide_zero.cpp_cppcheck.plist')
@@ -99,7 +102,8 @@ def test_transform_directory(self):
99102
""" Test transforming a directory of plist files. """
100103
analyzer_result = os.path.join(self.test_files, 'out')
101104
self.analyzer_result.transform(
102-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
105+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
106+
file_name="{source_file}_{analyzer}")
103107

104108
plist_file = os.path.join(self.cc_result_dir,
105109
'divide_zero.cpp_cppcheck.plist')

tools/report-converter/tests/unit/analyzers/test_cpplint_parser.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,25 @@ def test_no_cpplint_output_file(self):
4242
'sample.cpp')
4343

4444
ret = self.analyzer_result.transform(
45-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
45+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
46+
file_name="{source_file}_{analyzer}")
4647
self.assertFalse(ret)
4748

4849
def test_transform_dir(self):
4950
""" Test transforming a directory. """
5051
analyzer_result = os.path.join(self.test_files)
5152

5253
ret = self.analyzer_result.transform(
53-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
54+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
55+
file_name="{source_file}_{analyzer}")
5456
self.assertFalse(ret)
5557

5658
def test_transform_single_file(self):
5759
""" Test transforming single output file. """
5860
analyzer_result = os.path.join(self.test_files, 'sample.out')
5961
self.analyzer_result.transform(
60-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
62+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
63+
file_name="{source_file}_{analyzer}")
6164

6265
plist_file = os.path.join(self.cc_result_dir,
6366
'sample.cpp_cpplint.plist')

tools/report-converter/tests/unit/analyzers/test_eslint_parser.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,25 @@ def test_no_json_file(self):
4242
'index.js')
4343

4444
ret = self.analyzer_result.transform(
45-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
45+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
46+
file_name="{source_file}_{analyzer}")
4647
self.assertFalse(ret)
4748

4849
def test_transform_dir(self):
4950
""" Test transforming single plist file. """
5051
analyzer_result = os.path.join(self.test_files)
5152

5253
ret = self.analyzer_result.transform(
53-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
54+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
55+
file_name="{source_file}_{analyzer}")
5456
self.assertFalse(ret)
5557

5658
def test_transform_single_file(self):
5759
""" Test transforming single plist file. """
5860
analyzer_result = os.path.join(self.test_files, 'reports.json')
5961
self.analyzer_result.transform(
60-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
62+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
63+
file_name="{source_file}_{analyzer}")
6164

6265
plist_file = os.path.join(self.cc_result_dir,
6366
'index.js_eslint.plist')

tools/report-converter/tests/unit/analyzers/test_golint_parser.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,25 @@ def test_no_go_output_file(self):
4242
'simple.go')
4343

4444
ret = self.analyzer_result.transform(
45-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
45+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
46+
file_name="{source_file}_{analyzer}")
4647
self.assertFalse(ret)
4748

4849
def test_transform_dir(self):
4950
""" Test transforming single plist file. """
5051
analyzer_result = os.path.join(self.test_files)
5152

5253
ret = self.analyzer_result.transform(
53-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
54+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
55+
file_name="{source_file}_{analyzer}")
5456
self.assertFalse(ret)
5557

5658
def test_transform_single_file(self):
5759
""" Test transforming single plist file. """
5860
analyzer_result = os.path.join(self.test_files, 'simple.out')
5961
self.analyzer_result.transform(
60-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
62+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
63+
file_name="{source_file}_{analyzer}")
6164

6265
plist_file = os.path.join(self.cc_result_dir,
6366
'simple.go_golint.plist')

tools/report-converter/tests/unit/analyzers/test_infer_parser.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def test_parsing_cpp_res_dir(self):
5757
analyzer_result = os.path.join(self.test_files, 'infer-out-dead_store')
5858

5959
ret = self.analyzer_result.transform(
60-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
60+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
61+
file_name="{source_file}_{analyzer}")
6162
self.assertTrue(ret)
6263

6364
plist_file = os.path.join(self.cc_result_dir,
@@ -85,7 +86,8 @@ def test_transform_single_cpp_res_file(self):
8586
'report.json')
8687

8788
ret = self.analyzer_result.transform(
88-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
89+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
90+
file_name="{source_file}_{analyzer}")
8991
self.assertTrue(ret)
9092

9193
plist_file = os.path.join(self.cc_result_dir,
@@ -112,7 +114,8 @@ def test_parsing_java_res_dir(self):
112114
'infer-out-null_dereference')
113115

114116
ret = self.analyzer_result.transform(
115-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
117+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
118+
file_name="{source_file}_{analyzer}")
116119
self.assertTrue(ret)
117120

118121
plist_file = os.path.join(self.cc_result_dir,
@@ -141,7 +144,8 @@ def test_transform_single_java_res_file(self):
141144
'report.json')
142145

143146
ret = self.analyzer_result.transform(
144-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
147+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
148+
file_name="{source_file}_{analyzer}")
145149
self.assertTrue(ret)
146150

147151
plist_file = os.path.join(self.cc_result_dir,

tools/report-converter/tests/unit/analyzers/test_kerneldoc_parser.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,25 @@ def test_no_kerneldoc_output_file(self):
4343
'sample.c')
4444

4545
ret = self.analyzer_result.transform(
46-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
46+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
47+
file_name="{source_file}_{analyzer}")
4748
self.assertFalse(ret)
4849

4950
def test_transform_dir(self):
5051
""" Test transforming a directory. """
5152
analyzer_result = os.path.join(self.test_files)
5253

5354
ret = self.analyzer_result.transform(
54-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
55+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
56+
file_name="{source_file}_{analyzer}")
5557
self.assertFalse(ret)
5658

5759
def test_transform_single_file(self):
5860
""" Test transforming single output file. """
5961
analyzer_result = os.path.join(self.test_files, 'sample.out')
6062
self.analyzer_result.transform(
61-
analyzer_result, self.cc_result_dir, plist.EXTENSION)
63+
analyzer_result, self.cc_result_dir, plist.EXTENSION,
64+
file_name="{source_file}_{analyzer}")
6265

6366
plist_file = os.path.join(self.cc_result_dir,
6467
'sample.c_kernel-doc.plist')

tools/report-converter/tests/unit/analyzers/test_lsan_parser.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ def tearDown(self):
5555
def test_san(self):
5656
""" Test for the lsan.plist file. """
5757
self.analyzer_result.transform(
58-
'lsan.out', self.cc_result_dir, plist.EXTENSION)
58+
'lsan.out', self.cc_result_dir, plist.EXTENSION,
59+
file_name="{source_file}_{analyzer}")
5960

6061
with open('lsan.plist', mode='rb') as pfile:
6162
exp = plistlib.load(pfile)

0 commit comments

Comments
 (0)