@@ -212,6 +212,10 @@ def _append_component(
212212        else :
213213            purl  =  new_component ['purl' ]
214214
215+         if  not  purl :
216+             self .print_debug (f'WARNING: _append_component: No purl found for new component: { new_component }  ' )
217+             return  components 
218+ 
215219        component_key  =  f'{ purl }  @{ new_component ["version" ]}  ' 
216220        components [component_key ] =  {
217221            'purl' : purl ,
@@ -222,14 +226,21 @@ def _append_component(
222226        if  not  new_component .get ('licenses' ):
223227            self .print_debug (f'WARNING: Results missing licenses. Skipping: { new_component }  ' )
224228            return  components 
229+ 
230+ 
231+         licenses_order_by_source_priority  =  self ._get_licenses_order_by_source_priority (new_component ['licenses' ])
225232        # Process licenses for this component 
226-         for  license_item  in  new_component [ 'licenses' ] :
233+         for  license_item  in  licenses_order_by_source_priority :
227234            if  license_item .get ('name' ):
228235                spdxid  =  license_item ['name' ]
236+                 source  =  license_item .get ('source' )
237+                 if  not  source :
238+                     source  =  'unknown' 
229239                components [component_key ]['licenses' ][spdxid ] =  {
230240                    'spdxid' : spdxid ,
231241                    'copyleft' : self .license_util .is_copyleft (spdxid ),
232242                    'url' : self .license_util .get_spdx_url (spdxid ),
243+                     'source' : source ,
233244                }
234245        return  components 
235246
@@ -261,10 +272,12 @@ def _get_components_data(self, results: Dict[str, Any], components: Dict[str, An
261272                    if  len (c .get ('purl' )) <=  0 :
262273                        self .print_debug (f'WARNING: Result missing purls. Skipping: { c }  ' )
263274                        continue 
264-                     if  not  c .get ('version' ):
265-                         self .print_msg (f'WARNING: Result missing version. Skipping: { c }  ' )
266-                         continue 
267-                     component_key  =  f'{ c ["purl" ][0 ]}  @{ c ["version" ]}  ' 
275+                     version  =  c .get ('version' )
276+                     if  not  version :
277+                         self .print_debug (f'WARNING: Result missing version. Setting it to unknown: { c }  ' )
278+                         version  =  'unknown' 
279+                         c ['version' ] =  version  #If no version exists. Set 'unknown' version to current component 
280+                     component_key  =  f'{ c ["purl" ][0 ]}  @{ version }  ' 
268281                    if  component_key  not  in   components :
269282                        components  =  self ._append_component (components , c , component_id , status )
270283            # End component loop 
@@ -296,10 +309,12 @@ def _get_dependencies_data(self, results: Dict[str, Any], components: Dict[str,
296309                        if  not  dependency .get ('purl' ):
297310                            self .print_debug (f'WARNING: Dependency result missing purl. Skipping: { dependency }  ' )
298311                            continue 
299-                         if  not  dependency .get ('version' ):
300-                             self .print_msg (f'WARNING: Dependency result missing version. Skipping: { dependency }  ' )
301-                             continue 
302-                         component_key  =  f'{ dependency ["purl" ]}  @{ dependency ["version" ]}  ' 
312+                         version  =  c .get ('version' )
313+                         if  not  version :
314+                             self .print_debug (f'WARNING: Result missing version. Setting it to unknown: { c }  ' )
315+                             version  =  'unknown' 
316+                             c ['version' ] =  version   # If no version exists. Set 'unknown' version to current component 
317+                         component_key  =  f'{ dependency ["purl" ]}  @{ version }  ' 
303318                        if  component_key  not  in   components :
304319                            components  =  self ._append_component (components , dependency , component_id , status )
305320                    # End dependency loop 
@@ -411,6 +426,61 @@ def _load_input_file(self):
411426                self .print_stderr (f'ERROR: Problem parsing input JSON: { e }  ' )
412427        return  None 
413428
429+     def  _convert_components_to_list (self , components : dict ):
430+         if  components  is  None :
431+             self .print_debug (f'WARNING: Components is empty { self .results }  ' )
432+             return  None 
433+         results_list  =  list (components .values ())
434+         for  component  in  results_list :
435+             licenses  =  component .get ('licenses' )
436+             if  licenses  is  not   None :
437+                 component ['licenses' ] =  list (licenses .values ())
438+             else :
439+                 self .print_debug (f'WARNING: Licenses missing for: { component }  ' )
440+                 component ['licenses' ] =  []
441+         return  results_list 
442+ 
443+     def  _get_licenses_order_by_source_priority (self ,licenses_data ):
444+         """ 
445+         Select licenses based on source priority: 
446+         1. component_declared (highest priority) 
447+         2. license_file 
448+         3. file_header 
449+         4. scancode (lowest priority) 
450+ 
451+         If any high-priority source is found, return only licenses from that source. 
452+         If none found, return all licenses. 
453+ 
454+         Returns: list with ordered licenses by source. 
455+         """ 
456+         # Define priority order (highest to lowest) 
457+         priority_sources  =  ['component_declared' , 'license_file' , 'file_header' , 'scancode' ]
458+ 
459+         # Group licenses by source 
460+         licenses_by_source  =  {}
461+         for  license_item  in  licenses_data :
462+ 
463+             source  =  license_item .get ('source' , 'unknown' )
464+             if  source  not  in   licenses_by_source :
465+                 licenses_by_source [source ] =  {}
466+ 
467+             license_name  =  license_item .get ('name' )
468+             if  license_name :
469+                 # Use license name as key, store full license object as value 
470+                 # If duplicate license names exist in same source, the last one wins 
471+                 licenses_by_source [source ][license_name ] =  license_item 
472+ 
473+         # Find the highest priority source that has licenses 
474+         for  priority_source  in  priority_sources :
475+             if  priority_source  in  licenses_by_source :
476+                 self .print_trace (f'Choosing { priority_source }   as source' )
477+                 return  list (licenses_by_source [priority_source ].values ())
478+ 
479+         # If no priority sources found, combine all licenses into a single list 
480+         self .print_debug ("No priority sources found, returning all licenses as list" )
481+         return  licenses_data 
482+ 
483+ 
414484# 
415485# End of PolicyCheck Class 
416486# 
0 commit comments