@@ -242,26 +242,23 @@ fn main() -> Result<()> {
242242
243243 let rules_file = matches. opt_str ( "r" ) ;
244244
245- if directory_to_analyze_option. is_none ( ) {
245+ let Some ( directory_to_analyze ) = directory_to_analyze_option. map ( PathBuf :: from ) else {
246246 eprintln ! ( "no directory passed, specify a directory with option -i" ) ;
247247 print_usage ( & program, opts) ;
248248 exit ( EXIT_CODE_NO_DIRECTORY )
249- }
250-
251- let directory_to_analyze = directory_to_analyze_option. unwrap ( ) ;
252- let directory_path = std:: path:: Path :: new ( & directory_to_analyze) ;
249+ } ;
253250
254- if !directory_path . is_dir ( ) {
251+ if !directory_to_analyze . is_dir ( ) {
255252 eprintln ! ( "directory to analyze is not correct" ) ;
256253 exit ( EXIT_CODE_INVALID_DIRECTORY )
257254 }
258255
259- if !are_subdirectories_safe ( directory_path , & subdirectories_to_analyze) {
256+ if !are_subdirectories_safe ( & directory_to_analyze , & subdirectories_to_analyze) {
260257 eprintln ! ( "sub-directories are not safe and point outside of the repository" ) ;
261258 exit ( EXIT_CODE_UNSAFE_SUBDIRECTORIES )
262259 }
263260
264- let configuration_file_and_method = get_config ( directory_to_analyze. as_str ( ) , use_debug) ;
261+ let configuration_file_and_method = get_config ( & directory_to_analyze, use_debug) ;
265262
266263 let ( configuration_file, configuration_method) : (
267264 Option < file_v1:: ConfigFile > ,
@@ -274,13 +271,15 @@ fn main() -> Result<()> {
274271 Err ( err) => {
275272 eprintln ! (
276273 "Error reading configuration file from {}:\n {}" ,
277- directory_to_analyze, err
274+ directory_to_analyze. display( ) ,
275+ err
278276 ) ;
279277 exit ( EXIT_CODE_INVALID_CONFIGURATION )
280278 }
281279 } ;
280+ let sast_config = configuration_file. as_ref ( ) . and_then ( |cfg| cfg. sast ( ) ) ;
282281
283- if configuration_file . is_none ( ) && use_debug {
282+ if sast_config . is_none ( ) && use_debug {
284283 eprintln ! ( "INFO: no configuration detected locally or remotely" )
285284 }
286285
@@ -290,11 +289,11 @@ fn main() -> Result<()> {
290289 . unwrap_or_default ( ) ;
291290 let mut rules: Vec < Rule > = Vec :: new ( ) ;
292291
293- // A list of rulesets that were fetched due to being specifically listed in a ConfigFile::use_rulesets list.
294- let mut fetched_rulesets = Vec :: < & str > :: new ( ) ;
292+ // Rulesets to exclude when fetching default rulesets
293+ let mut excluded_rulesets = Vec :: < & str > :: new ( ) ;
295294 // if there is a configuration file, we load the rules from it. But it means
296295 // we cannot have the rule parameter given.
297- if let Some ( conf) = & configuration_file {
296+ if let Some ( conf) = sast_config {
298297 ignore_gitignore = conf
299298 . global_config
300299 . as_ref ( )
@@ -306,20 +305,18 @@ fn main() -> Result<()> {
306305 }
307306
308307 if static_analysis_enabled {
309- if let Some ( rulesets) = & conf. use_rulesets {
310- let rules_from_api = get_rules_from_rulesets ( rulesets, use_staging, use_debug)
311- . inspect_err ( |e| {
312- if let DatadogApiError :: RulesetNotFound ( rs) = e {
313- eprintln ! ( "Error: ruleset {rs} not found" ) ;
314- exit ( EXIT_CODE_RULESET_NOT_FOUND ) ;
315- }
316- } )
317- . context ( "error when reading rules from API" ) ?;
318- rules. extend ( rules_from_api) ;
319- for r in rulesets {
320- fetched_rulesets. push ( r. as_str ( ) ) ;
321- }
322- }
308+ let explicit_rs = conf. explicit_rulesets ( ) . collect :: < Vec < _ > > ( ) ;
309+ let rules_from_api = get_rules_from_rulesets ( & explicit_rs, use_staging, use_debug)
310+ . inspect_err ( |e| {
311+ if let DatadogApiError :: RulesetNotFound ( rs) = e {
312+ eprintln ! ( "Error: ruleset {rs} not found" ) ;
313+ exit ( EXIT_CODE_RULESET_NOT_FOUND ) ;
314+ }
315+ } )
316+ . context ( "error when reading rules from API" ) ?;
317+ rules. extend ( rules_from_api) ;
318+ excluded_rulesets. extend ( explicit_rs) ;
319+ excluded_rulesets. extend ( conf. ignore_rulesets . iter ( ) . map ( String :: as_str) ) ;
323320 }
324321 // copy the only and ignore paths from the configuration file
325322 if let Some ( pc) = conf. global_config . as_ref ( ) . and_then ( |g| g. paths . as_ref ( ) ) {
@@ -343,18 +340,19 @@ fn main() -> Result<()> {
343340 if static_analysis_enabled {
344341 // if there is no config file, we take the default rules from our APIs.
345342 if rules_file. is_none ( ) {
346- if configuration_file . is_none ( ) {
347- println ! ( "WARNING: no configuration file detected, getting the default rules from the Datadog API" ) ;
343+ if sast_config . is_none ( ) {
344+ println ! ( "WARNING: no SAST configuration detected, getting the default rules from the Datadog API" ) ;
348345 println ! ( "Check the following resources to configure your rules:" ) ;
349346 println ! (
350347 " - Datadog documentation: https://docs.datadoghq.com/code_analysis/static_analysis"
351348 ) ;
352349 println ! ( " - Static analyzer repository on GitHub: https://github.com/DataDog/datadog-static-analyzer" ) ;
353350 }
354- let should_fetch = !matches ! ( & configuration_file, Some ( config) if config. use_default_rulesets == Some ( false ) ) ;
351+
352+ let should_fetch = sast_config. is_none_or ( |c| c. use_default_rulesets != Some ( false ) ) ;
355353 if should_fetch {
356354 let rulesets_from_api =
357- get_all_default_rulesets ( use_staging, use_debug, & fetched_rulesets )
355+ get_all_default_rulesets ( use_staging, use_debug, & excluded_rulesets )
358356 . context ( "cannot get default rules" ) ?;
359357 rules. extend ( rulesets_from_api. into_iter ( ) . flat_map ( |rs| rs. into_rules ( ) ) ) ;
360358 }
@@ -382,7 +380,7 @@ fn main() -> Result<()> {
382380
383381 // ignore all directories that are in gitignore
384382 if !ignore_gitignore {
385- match read_files_from_gitignore ( directory_to_analyze. as_str ( ) ) {
383+ match read_files_from_gitignore ( & directory_to_analyze) {
386384 Ok ( paths_from_gitignore) => {
387385 path_config
388386 . ignore
@@ -403,7 +401,7 @@ fn main() -> Result<()> {
403401 let languages = get_languages_for_rules ( & rules) ;
404402
405403 let files_in_repository = get_files (
406- directory_to_analyze. as_str ( ) ,
404+ & directory_to_analyze,
407405 subdirectories_to_analyze. clone ( ) ,
408406 & path_config,
409407 )
@@ -424,7 +422,7 @@ fn main() -> Result<()> {
424422 use_debug,
425423 configuration_method,
426424 ignore_gitignore,
427- source_directory : directory_to_analyze. clone ( ) ,
425+ source_directory : directory_to_analyze. to_string_lossy ( ) . to_string ( ) ,
428426 source_subdirectories : subdirectories_to_analyze. clone ( ) ,
429427 path_config,
430428 rules_file,
@@ -542,7 +540,7 @@ fn main() -> Result<()> {
542540
543541 // if diff-aware is enabled, we filter the files and keep only the files we want to analyze from diff-aware
544542 let files_to_analyze = if let Some ( dap) = & diff_aware_parameters {
545- filter_files_by_diff_aware_info ( & files_filtered_by_size, directory_path , dap)
543+ filter_files_by_diff_aware_info ( & files_filtered_by_size, & directory_to_analyze , dap)
546544 } else {
547545 files_filtered_by_size
548546 } ;
0 commit comments