11
11
from scrub .utils .filtering import do_filtering
12
12
from scrub .utils import do_clean
13
13
from scrub .utils import scrub_utilities
14
+ from scrub .tools .parsers import translate_results
14
15
15
16
16
17
def parse_arguments ():
@@ -40,7 +41,8 @@ def parse_arguments():
40
41
logging_level = logging .INFO
41
42
42
43
# Run analysis
43
- main (pathlib .Path (args ['config' ]).resolve (), args ['clean' ], logging_level , args ['tools' ], args ['targets' ], args ['define' ])
44
+ main (pathlib .Path (args ['config' ]).resolve (), args ['clean' ], logging_level , args ['tools' ], args ['targets' ],
45
+ args ['define' ])
44
46
45
47
46
48
def main (conf_file = pathlib .Path ('./scrub.cfg' ).resolve (), clean = False , console_logging = logging .INFO , tools = None ,
@@ -90,14 +92,23 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
90
92
try :
91
93
shutil .copyfile (conf_file , str (scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('scrub.cfg' )))
92
94
except PermissionError :
93
- print ("WARNING: Could not create copy of configuration file {}" .format (scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('scrub.cfg' )))
95
+ print ("WARNING: Could not create copy of configuration file {}"
96
+ .format (scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('scrub.cfg' )))
94
97
95
98
# Create a VERSION file
96
99
try :
97
100
with open (str (scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('VERSION' )), 'w' ) as output_fh :
98
101
output_fh .write (__version__ )
99
102
except PermissionError :
100
- logging .warning ('Could not create VERSION file {}' .format (str (scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('VERSION' ))))
103
+ logging .warning ('Could not create VERSION file {}'
104
+ .format (str (scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('VERSION' ))))
105
+
106
+ # Check for SARIF import conflicts
107
+ if scrub_conf_data .get ("sonarqube_import" ) and scrub_conf_data .get ("codesonar_import" ):
108
+ print ("ERROR: Conflict in SARIF import instructions. "
109
+ "SARIF results can only be imported into one tool at a time." )
110
+ print (" Please select SONARQUBE_IMPORT or CODESONAR_IMPORT, but not both." )
111
+ sys .exit (10 )
101
112
102
113
try :
103
114
# Get the templates
@@ -108,6 +119,14 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
108
119
available_analysis_templates = (available_analysis_templates +
109
120
scrub_conf_data .get ('custom_templates' ).replace ('\" ' , '' ).split (',' ))
110
121
122
+ # If we're doing SARIF import, we need to move that tool to the end
123
+ if scrub_conf_data .get ('sonarqube_import' ):
124
+ available_analysis_templates .remove (scrub_path .joinpath ('tools/templates/sonarqube.template' ))
125
+ available_analysis_templates .append (scrub_path .joinpath ('tools/templates/sonarqube.template' ))
126
+ elif scrub_conf_data .get ('codesonar_import' ):
127
+ available_analysis_templates .remove (scrub_path .joinpath ('tools/templates/codesonar.template' ))
128
+ available_analysis_templates .append (scrub_path .joinpath ('tools/templates/codesonar.template' ))
129
+
111
130
# Check to make sure at least one possible template has been identified
112
131
if len (available_analysis_templates ) == 0 :
113
132
print ('WARNING: No analysis templates have been found.' )
@@ -123,17 +142,14 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
123
142
analysis_templates = []
124
143
for template in available_analysis_templates :
125
144
for tool in tools :
126
- if template .name == tool + '.template' :
145
+ if template .name == tool + '.template' :
127
146
analysis_templates .append (template )
128
147
scrub_conf_data .update ({tool .lower () + '_warnings' : True })
129
148
else :
130
149
analysis_templates = available_analysis_templates
131
150
132
151
# Perform analysis using the template
133
152
for analysis_template in analysis_templates :
134
- # Initialize variables
135
- execution_time = 0
136
-
137
153
# Get the tool name
138
154
tool_name = analysis_template .stem
139
155
@@ -145,6 +161,8 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
145
161
analysis_scripts_dir = scrub_conf_data .get ('scrub_analysis_dir' ).joinpath ('analysis_scripts' )
146
162
analysis_script = analysis_scripts_dir .joinpath (tool_name + '.sh' )
147
163
tool_analysis_dir = scrub_conf_data .get ('scrub_working_dir' ).joinpath (tool_name + '_analysis' )
164
+ sarif_import_dir = tool_analysis_dir .joinpath ('sarif_imports' )
165
+ parser = importlib .import_module ('scrub.tools.parsers.get_' + tool_name .lower () + '_warnings' )
148
166
149
167
# Add derived values to configuration values
150
168
scrub_conf_data .update ({'tool_analysis_dir' : tool_analysis_dir })
@@ -155,6 +173,18 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
155
173
# Create the tool analysis directory
156
174
scrub_utilities .create_dir (tool_analysis_dir , True , True )
157
175
176
+ # Is SARIF import being performed?
177
+ if scrub_conf_data .get (tool_name + '_import' ):
178
+ scrub_utilities .create_dir (sarif_import_dir , True , True )
179
+
180
+ # Iterate through the existing SARIF files, process them, and drop them into the expected directory
181
+ for sarif_file in list (scrub_conf_data .get ('sarif_results_dir' ).glob ('*.sarif' )):
182
+ if sarif_file .stem != tool_name :
183
+ translate_results .format_sarif_for_upload (sarif_file ,
184
+ sarif_import_dir .joinpath (sarif_file .name ),
185
+ scrub_conf_data .get ('source_dir' ),
186
+ tool_name )
187
+
158
188
# Create the log file
159
189
analysis_log_file = scrub_conf_data .get ('scrub_log_dir' ).joinpath (tool_name + '.log' )
160
190
scrub_utilities .create_logger (analysis_log_file , console_logging )
@@ -198,6 +228,9 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
198
228
# Check the tool analysis directory
199
229
scrub_utilities .check_artifact (tool_analysis_dir , True )
200
230
231
+ # Parse the results files
232
+ parser .parse_warnings (tool_analysis_dir , scrub_conf_data )
233
+
201
234
# Check the raw results files
202
235
for raw_results_file in scrub_conf_data .get ('raw_results_dir' ).glob (tool_name + '_*.scrub' ):
203
236
scrub_utilities .check_artifact (raw_results_file , False )
@@ -226,17 +259,17 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
226
259
# Calculate the execution time
227
260
execution_time = time .time () - start_time
228
261
229
- # Update the execution status
230
- execution_status .append ([tool_name , tool_execution_status , execution_time ])
262
+ # Update the execution status
263
+ execution_status .append ([tool_name , tool_execution_status , execution_time ])
231
264
232
- # Perform filtering and track execution time, if necessary
233
- if perform_filtering :
234
- start_time = time .time ()
235
- filtering_status = do_filtering .run_analysis (scrub_conf_data , console_logging )
236
- execution_time = time .time () - start_time
265
+ # Perform filtering and track execution time, if necessary
266
+ if perform_filtering :
267
+ start_time = time .time ()
268
+ filtering_status = do_filtering .run_analysis (scrub_conf_data , console_logging )
269
+ execution_time = time .time () - start_time
237
270
238
- # Update the execution status
239
- execution_status .append (['filtering' , filtering_status , execution_time ])
271
+ # Update the execution status
272
+ execution_status .append (['filtering' , filtering_status , execution_time ])
240
273
241
274
finally :
242
275
# Move the results back with the source code if necessary
@@ -255,15 +288,16 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
255
288
shutil .rmtree (scrub_conf_data .get ('scrub_working_dir' ))
256
289
257
290
except PermissionError :
258
- print ("\t WARNING: Could not move results from {} to {}" .format (scrub_conf_data .get ('scrub_working_dir' ), scrub_conf_data .get ('scrub_analysis_dir' )))
291
+ print ("\t WARNING: Could not move results from {} to {}" .format (scrub_conf_data .get ('scrub_working_dir' ),
292
+ scrub_conf_data .get ('scrub_analysis_dir' )))
259
293
print ("\t \t Results will remain at {}" .format (scrub_conf_data .get ('scrub_working_dir' )))
260
294
261
295
# Create a visible directory of results, if it doesn't already exist
262
296
viewable_results_dir = scrub_conf_data .get ('source_dir' ).joinpath ('scrub_results' )
263
297
scrub_utilities .create_dir (viewable_results_dir , False )
264
298
265
299
# Create symbolic links for the output files
266
- file_extensions = ['*.scrub' , 'sarif_results/*.sarif' ]
300
+ file_extensions = ['*.scrub' , 'sarif_results/*.sarif' , '*_metrics.csv' ]
267
301
for extension in file_extensions :
268
302
for scrub_file in scrub_conf_data .get ('scrub_analysis_dir' ).glob (extension ):
269
303
symlink_path = viewable_results_dir .joinpath (scrub_file .name )
@@ -272,8 +306,8 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
272
306
os .symlink (os .path .relpath (str (scrub_file ), str (viewable_results_dir )), symlink_path )
273
307
274
308
except PermissionError :
275
- logging .warning ('Could not create symbolic link {}' . format ( viewable_results_dir . joinpath ( scrub_file . name )))
276
-
309
+ logging .warning ('Could not create symbolic link {}'
310
+ . format ( viewable_results_dir . joinpath ( scrub_file . name )))
277
311
278
312
# Print a status message
279
313
tool_failure_count = 0
@@ -299,8 +333,11 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
299
333
exit_code = 'Unknown error'
300
334
301
335
# Print the status message
302
- print ('\t %s | %s: %s' % (time .strftime ("%H:%M:%S" , time .gmtime (status [2 ])), status [0 ], exit_code ))
303
- print ('\t --------------------------------------------------' )
336
+ if status [0 ] == 'filtering' :
337
+ print ('\t %s | %s: %s' % (time .strftime ("%H:%M:%S" , time .gmtime (status [2 ])), status [0 ], exit_code ))
338
+ else :
339
+ print ('\t --------------------------------------------------' )
340
+ print ('\t %s | %s: %s' % (time .strftime ("%H:%M:%S" , time .gmtime (status [2 ])), status [0 ], exit_code ))
304
341
305
342
# Print the execution time
306
343
print ('\n \t Total Execution Time: %s\n ' % time .strftime ("%H:%M:%S" , time .gmtime (total_execution_time )))
@@ -338,4 +375,4 @@ def main(conf_file=pathlib.Path('./scrub.cfg').resolve(), clean=False, console_l
338
375
getattr (module_object , "run_analysis" )(scrub_conf_data , console_logging )
339
376
340
377
# Set the exit code
341
- sys .exit (tool_failure_count )
378
+ sys .exit (tool_failure_count )
0 commit comments