Skip to content

Commit 9f33d13

Browse files
committed
chore:SP-2746 Prioritizes licenses by source in inspect copyleft subcommand
1 parent 2d73022 commit 9f33d13

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
## [1.25.2] - 2025-06-18
1313
### Fixed
14-
- Avoids errors when no versions are declared on scanner results in `inspect` subcommand
14+
- Fixed errors when no versions are declared in scanner results for `inspect` subcommand
15+
### Changed
16+
- Prioritized licenses by source priority in `inspect copyleft` subcommand
1517

1618
## [1.25.1] - 2025-06-12
1719
### Fixed

src/scanoss/inspection/policy_check.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,11 @@ def _append_component(
226226
if not new_component.get('licenses'):
227227
self.print_debug(f'WARNING: Results missing licenses. Skipping: {new_component}')
228228
return components
229+
230+
231+
licenses_order_by_source_priority = self._get_licenses_order_by_source_priority(new_component['licenses'])
229232
# Process licenses for this component
230-
for license_item in new_component['licenses']:
233+
for license_item in licenses_order_by_source_priority:
231234
if license_item.get('name'):
232235
spdxid = license_item['name']
233236
source = license_item.get('source')
@@ -436,6 +439,48 @@ def _convert_components_to_list(self, components: dict):
436439
self.print_debug(f'WARNING: Licenses missing for: {component}')
437440
component['licenses'] = []
438441
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+
439484
#
440485
# End of PolicyCheck Class
441486
#

0 commit comments

Comments
 (0)