Skip to content

Commit 7b063da

Browse files
committed
[feat] Print statistics after analysis through Makefile
"CodeChecker analyze --makefile ..." is generating a Makefile that contains analyzer commands. With "make" command one can execute analysis using this generated Makefile. This commit is about printing some statistics about the analysis based on the Makefile. The statistics contain the number of successful and failed analysis.
1 parent b049040 commit 7b063da

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

analyzer/codechecker_analyzer/makefile.py

+51-3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ def __init__(self, analyzers, output_path, config_map,
5656
self.__stats_dir = statistics_data['stats_out_dir']
5757

5858
self.__makefile = os.path.join(output_path, 'Makefile')
59+
self.__stat_sh = os.path.join(output_path, 'print_stat.sh')
60+
self.__exit_codes_dir = os.path.join(output_path, 'exit_codes')
5961

6062
self.__config = None
6163
self.__func_map_cmd = None
@@ -110,13 +112,51 @@ def __write_default_targets(self, mfile):
110112
analyzer.
111113
"""
112114
mfile.write("# Default target to run all analysis.\n"
113-
"default: all\n\n")
115+
"default: create_exit_code_folder all\n"
116+
f"\t@bash {self.__stat_sh}\n"
117+
f"\t@rm -rf {self.__exit_codes_dir}\n\n"
118+
"# Folder for creating exit codes of analyses.\n"
119+
"create_exit_code_folder:\n"
120+
f"\t@rm -rf {self.__exit_codes_dir}\n"
121+
f"\t@mkdir {self.__exit_codes_dir}\n\n")
114122

115123
for analyzer in self.__analyzers:
116124
analyzer_name = self.__format_analyzer_type(analyzer)
117125
mfile.write(f"# Target to run only '{analyzer_name}' analysis.\n"
118126
f"all: all_{analyzer_name}\n\n")
119127

128+
def __write_print_stats(self, sfile):
129+
""" Write target to print analyzer statistics.
130+
131+
At the end of the analysis the Makefile should print statistics about
132+
how many actions were analyzed by the specific analyzers.
133+
"""
134+
sfile.write(f'''#!/usr/bin/env bash
135+
declare -A success
136+
declare -A all
137+
sum=0
138+
139+
for filename in $(ls {self.__exit_codes_dir}); do
140+
success[$filename]=$(grep ^0$ {self.__exit_codes_dir}/$filename | wc -l)
141+
all[$filename]=$(wc -l < {self.__exit_codes_dir}/$filename)
142+
sum=$(($sum + ${{all[$filename]}}))
143+
done
144+
145+
echo "----==== Summary ====----"
146+
147+
echo "Successfully analyzed"
148+
for analyzer in "${{!success[@]}}"; do
149+
echo $analyzer: ${{success[$analyzer]}}
150+
done
151+
152+
echo "Failed to analyze"
153+
for analyzer in "${{!success[@]}}"; do
154+
echo $analyzer: $((${{all[$analyzer]}} - ${{success[$analyzer]}}))
155+
done
156+
157+
echo "Total analyzed compilation commands: $sum"
158+
echo "----=================----"''')
159+
120160
def __get_ctu_pre_analysis_cmds(self, action):
121161
""" Get CTU pre-analysis commands. """
122162
cmds = []
@@ -238,6 +278,9 @@ def __write_analysis_targets(self, mfile, action, post_pre_all_target):
238278
target = self.__get_target_name(action)
239279
analyzer_name = self.__format_analyzer_type(action.analyzer_type)
240280

281+
save_exit_code = \
282+
f"; echo $$? >> {self.__exit_codes_dir}/{action.analyzer_type}"
283+
241284
if action.analyzer_type == ClangTidy.ANALYZER_NAME:
242285
analyzer_output_file = rh.analyzer_result_file + ".output"
243286
file_name = "{source_file}_{analyzer}_" + target
@@ -247,11 +290,12 @@ def __write_analysis_targets(self, mfile, action, post_pre_all_target):
247290
"--filename", file_name,
248291
analyzer_output_file]
249292

250-
command = f"@{' '.join(analyzer_cmd)} > {analyzer_output_file}\n" \
293+
command = f"@{' '.join(analyzer_cmd)} > " \
294+
f"{analyzer_output_file}{save_exit_code}\n" \
251295
f"\t@{' '.join(report_converter_cmd)} 1>/dev/null\n" \
252296
f"\t@rm -rf {analyzer_output_file}\n"
253297
else:
254-
command = f"@{' '.join(analyzer_cmd)} 1>/dev/null"
298+
command = f"@{' '.join(analyzer_cmd)} 1>/dev/null{save_exit_code}"
255299

256300
mfile.write(
257301
f'{target}: {post_pre_all_target}\n'
@@ -265,6 +309,10 @@ def create(self, actions):
265309
LOG.info("Creating Makefile from the analyzer commands: '%s'...",
266310
self.__makefile)
267311

312+
with open(self.__stat_sh, 'w+',
313+
encoding='utf-8', errors='ignore') as sfile:
314+
self.__write_print_stats(sfile)
315+
268316
with open(self.__makefile, 'w+',
269317
encoding='utf-8', errors='ignore') as mfile:
270318
self.__write_header(mfile)

0 commit comments

Comments
 (0)