8181
8282notice_path = os .path .join (os .path .abspath (os .path .dirname (__file__ )), 'NOTICE' )
8383notice_text = open (notice_path ).read ()
84-
84+
8585delimiter = '\n \n \n '
8686[notice_text , extra_notice_text ] = notice_text .split (delimiter , 1 )
8787extra_notice_text = delimiter + extra_notice_text
88-
88+
8989delimiter = '\n \n '
9090[notice_text , acknowledgment_text ] = notice_text .split (delimiter , 1 )
9191acknowledgment_text = delimiter + acknowledgment_text
92-
92+
9393notice = acknowledgment_text .strip ().replace (' ' , '' )
9494
9595
@@ -208,6 +208,9 @@ def validate_formats(ctx, param, value):
208208 help = 'Include the detected licenses matched text. Has no effect unless --license is requested.' )
209209@click .option ('--only-findings' , is_flag = True , default = False ,
210210 help = 'Only return files or directories with findings for the requested scans. Files without findings are omitted.' )
211+ @click .option ('--strip-root' , is_flag = True , default = False ,
212+ help = 'Strip the root directory segment of all paths. The default is to always '
213+ 'include the last directory segment of the scanned path such that all paths have a common root directory.' )
211214
212215@click .option ('-f' , '--format' , is_flag = False , default = 'json' , show_default = True , metavar = '<style>' ,
213216 help = ('Set <output_file> format <style> to one of the standard formats: %s '
@@ -230,7 +233,7 @@ def scancode(ctx,
230233 input , output_file ,
231234 copyright , license , package ,
232235 email , url , info ,
233- license_score , license_text , only_findings ,
236+ license_score , license_text , only_findings , strip_root ,
234237 format , verbose , quiet , processes ,
235238 diag , timeout , max_memory ,
236239 * args , ** kwargs ):
@@ -275,6 +278,7 @@ def scancode(ctx,
275278 scanners = OrderedDict (zip (possible_scans .keys (), zip (possible_scans .values (), scan_functions )))
276279
277280 scans_cache_class = get_scans_cache_class ()
281+
278282 try :
279283 files_count , results = scan (input_path = input ,
280284 scanners = scanners ,
@@ -286,10 +290,12 @@ def scancode(ctx,
286290 timeout = timeout , max_memory = max_memory ,
287291 diag = diag ,
288292 scans_cache_class = scans_cache_class ,
289- )
293+ strip_root = strip_root )
290294 if not quiet :
291295 echo_stderr ('Saving results.' , fg = 'green' )
296+
292297 save_results (scanners , only_findings , files_count , results , format , input , output_file )
298+
293299 finally :
294300 # cleanup
295301 cache = scans_cache_class ()
@@ -306,9 +312,10 @@ def scan(input_path,
306312 verbose = False , quiet = False ,
307313 processes = 1 , timeout = DEFAULT_TIMEOUT , max_memory = DEFAULT_MAX_MEMORY ,
308314 diag = False ,
309- scans_cache_class = None ):
315+ scans_cache_class = None ,
316+ strip_root = False ):
310317 """
311- Return a tuple of (files_count, indexing_time, scan_results) where
318+ Return a tuple of (files_count, scan_results) where
312319 scan_results is an iterable. Run each requested scan proper: each individual file
313320 scan is cached on disk to free memory. Then the whole set of scans is loaded from
314321 the cache and streamed at the end.
@@ -432,7 +439,25 @@ def scan_event(item):
432439
433440 # finally return an iterator on cached results
434441 cached_scan = scans_cache_class ()
435- return files_count , cached_scan .iterate (scans )
442+ root_dir = _get_root_dir (input_path , strip_root )
443+ return files_count , cached_scan .iterate (scans , root_dir )
444+
445+
446+ def _get_root_dir (input_path , strip_root = False ):
447+ """
448+ Return a root dir name or None.
449+ """
450+ if strip_root :
451+ root_dir = None
452+ else :
453+ _scanned_path = os .path .abspath (os .path .normpath (os .path .expanduser (input_path )))
454+ if filetype .is_dir (_scanned_path ):
455+ root_dir = _scanned_path
456+ else :
457+ root_dir = fileutils .parent_directory (_scanned_path )
458+ root_dir = fileutils .file_name (root_dir )
459+
460+ return root_dir
436461
437462
438463def _resource_logger (logfile_fd , resources ):
@@ -575,7 +600,7 @@ def has_findings(active_scans, file_data):
575600 return any (file_data .get (scan_name ) for scan_name in active_scans )
576601
577602
578- def save_results (scanners , only_findings , files_count , scanned_files , format , input , output_file ):
603+ def save_results (scanners , only_findings , files_count , results , format , input , output_file ):
579604 """
580605 Save scan results to file or screen.
581606 """
@@ -589,11 +614,10 @@ def save_results(scanners, only_findings, files_count, scanned_files, format, in
589614
590615 # FIXME: this is forcing all the scan results to be loaded in memory
591616 # and defeats lazy loading from cache
592- scanned_files = [file_data for file_data in scanned_files
593- if has_findings (active_scans , file_data )]
617+ results = [file_data for file_data in results if has_findings (active_scans , file_data )]
594618 # FIXME: computing len before hand will need a list and therefore need loding
595619 # it all aheaed of time
596- files_count = len (scanned_files )
620+ files_count = len (results )
597621
598622 # note: in tests, sys.stdout is not used, but some io wrapper with no name
599623 # attributes
@@ -609,7 +633,7 @@ def save_results(scanners, only_findings, files_count, scanned_files, format, in
609633 if not os .path .isfile (format ):
610634 echo_stderr ('\n Invalid template passed.' , fg = 'red' )
611635 else :
612- for template_chunk in as_template (scanned_files , template = format ):
636+ for template_chunk in as_template (results , template = format ):
613637 try :
614638 output_file .write (template_chunk )
615639 except Exception as e :
@@ -619,4 +643,4 @@ def save_results(scanners, only_findings, files_count, scanned_files, format, in
619643 raise e
620644 return
621645
622- write_formatted_output (scanners , files_count , version , notice , scanned_files , format , input , output_file , echo_stderr )
646+ write_formatted_output (scanners , files_count , version , notice , results , format , input , output_file , echo_stderr )
0 commit comments