scanoss 1.25.1__py3-none-any.whl → 1.25.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
scanoss/__init__.py CHANGED
@@ -22,4 +22,4 @@ SPDX-License-Identifier: MIT
22
22
  THE SOFTWARE.
23
23
  """
24
24
 
25
- __version__ = '1.25.1'
25
+ __version__ = '1.25.2'
@@ -1 +1 @@
1
- date: 20250612124028, utime: 1749732028
1
+ date: 20250618150502, utime: 1750259102
@@ -177,11 +177,7 @@ class Copyleft(PolicyCheck):
177
177
  # Extract component and license data from file and dependency results. Both helpers mutate `components`
178
178
  self._get_components_data(self.results, components)
179
179
  self._get_dependencies_data(self.results, components)
180
- # Convert to list and process licenses
181
- results_list = list(components.values())
182
- for component in results_list:
183
- component['licenses'] = list(component['licenses'].values())
184
- return results_list
180
+ return self._convert_components_to_list(components)
185
181
 
186
182
  def run(self):
187
183
  """
@@ -212,6 +212,10 @@ class PolicyCheck(ScanossBase):
212
212
  else:
213
213
  purl = new_component['purl']
214
214
 
215
+ if not purl:
216
+ self.print_debug(f'WARNING: _append_component: No purl found for new component: {new_component}')
217
+ return components
218
+
215
219
  component_key = f'{purl}@{new_component["version"]}'
216
220
  components[component_key] = {
217
221
  'purl': purl,
@@ -222,14 +226,21 @@ class PolicyCheck(ScanossBase):
222
226
  if not new_component.get('licenses'):
223
227
  self.print_debug(f'WARNING: Results missing licenses. Skipping: {new_component}')
224
228
  return components
229
+
230
+
231
+ licenses_order_by_source_priority = self._get_licenses_order_by_source_priority(new_component['licenses'])
225
232
  # Process licenses for this component
226
- for license_item in new_component['licenses']:
233
+ for license_item in licenses_order_by_source_priority:
227
234
  if license_item.get('name'):
228
235
  spdxid = license_item['name']
236
+ source = license_item.get('source')
237
+ if not source:
238
+ source = 'unknown'
229
239
  components[component_key]['licenses'][spdxid] = {
230
240
  'spdxid': spdxid,
231
241
  'copyleft': self.license_util.is_copyleft(spdxid),
232
242
  'url': self.license_util.get_spdx_url(spdxid),
243
+ 'source': source,
233
244
  }
234
245
  return components
235
246
 
@@ -261,10 +272,12 @@ class PolicyCheck(ScanossBase):
261
272
  if len(c.get('purl')) <= 0:
262
273
  self.print_debug(f'WARNING: Result missing purls. Skipping: {c}')
263
274
  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}'
268
281
  if component_key not in components:
269
282
  components = self._append_component(components, c, component_id, status)
270
283
  # End component loop
@@ -296,10 +309,12 @@ class PolicyCheck(ScanossBase):
296
309
  if not dependency.get('purl'):
297
310
  self.print_debug(f'WARNING: Dependency result missing purl. Skipping: {dependency}')
298
311
  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}'
303
318
  if component_key not in components:
304
319
  components = self._append_component(components, dependency, component_id, status)
305
320
  # End dependency loop
@@ -411,6 +426,61 @@ class PolicyCheck(ScanossBase):
411
426
  self.print_stderr(f'ERROR: Problem parsing input JSON: {e}')
412
427
  return None
413
428
 
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
+
414
484
  #
415
485
  # End of PolicyCheck Class
416
486
  #
@@ -254,10 +254,7 @@ class UndeclaredComponent(PolicyCheck):
254
254
  # Extract file and snippet components
255
255
  components = self._get_components_data(self.results, components)
256
256
  # Convert to list and process licenses
257
- results_list = list(components.values())
258
- for component in results_list:
259
- component['licenses'] = list(component['licenses'].values())
260
- return results_list
257
+ return self._convert_components_to_list(components)
261
258
 
262
259
  def run(self):
263
260
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scanoss
3
- Version: 1.25.1
3
+ Version: 1.25.2
4
4
  Summary: Simple Python library to leverage the SCANOSS APIs
5
5
  Home-page: https://scanoss.com
6
6
  Author: SCANOSS
@@ -4,7 +4,7 @@ protoc_gen_swagger/options/annotations_pb2.py,sha256=b25EDD6gssUWnFby9gxgcpLIROT
4
4
  protoc_gen_swagger/options/annotations_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
5
5
  protoc_gen_swagger/options/openapiv2_pb2.py,sha256=vYElGp8E1vGHszvWqX97zNG9GFJ7u2QcdK9ouq0XdyI,14939
6
6
  protoc_gen_swagger/options/openapiv2_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
7
- scanoss/__init__.py,sha256=zoc5i9zIZ6i9BDBRPHBqmnNWz1ctPZAr9pCu2Pamvlg,1146
7
+ scanoss/__init__.py,sha256=9K1SKldg4taEpZ7t4H-Z45hI8SIqMlSmjp6TFz3Km2w,1146
8
8
  scanoss/cli.py,sha256=SAB0xuHjEEw20YtYAPSZwrQaVf4JUsm8NRcVArMzd4U,69099
9
9
  scanoss/components.py,sha256=b0R9DdKuXqyQiw5nZZwjQ6NJXBr1U9gyx1RI2FP9ozA,14511
10
10
  scanoss/constants.py,sha256=FWCZG8gQputKwV7XwvW1GuwDXL4wDLQyVRGdwygg578,320
@@ -57,14 +57,14 @@ scanoss/api/vulnerabilities/__init__.py,sha256=IFrDk_DTJgKSZmmU-nuLXuq_s8sQZlrSC
57
57
  scanoss/api/vulnerabilities/v2/__init__.py,sha256=IFrDk_DTJgKSZmmU-nuLXuq_s8sQZlrSCHhIDMJT4r0,1122
58
58
  scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py,sha256=CFhF80av8tenGvn9AIsGEtRJPuV2dC_syA5JLZb2lDw,5464
59
59
  scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py,sha256=HlS4k4Zmx6RIAqaO9I96jD-eyF5yU6Xx04pVm7pdqOg,6864
60
- scanoss/data/build_date.txt,sha256=DgM1g6ceMq5HR3AeQ6XArgq0PfNCFKqT1ujuejYzZaI,40
60
+ scanoss/data/build_date.txt,sha256=3-u7TU-KPaW2lJLuHTSTYQJlq8aqKlVQv7MRd_B-xvQ,40
61
61
  scanoss/data/scanoss-settings-schema.json,sha256=ClkRYAkjAN0Sk704G8BE_Ok006oQ6YnIGmX84CF8h9w,8798
62
62
  scanoss/data/spdx-exceptions.json,sha256=s7UTYxC7jqQXr11YBlIWYCNwN6lRDFTR33Y8rpN_dA4,17953
63
63
  scanoss/data/spdx-licenses.json,sha256=A6Z0q82gaTLtnopBfzeIVZjJFxkdRW1g2TuumQc-lII,228794
64
64
  scanoss/inspection/__init__.py,sha256=0hjb5ktavp7utJzFhGMPImPaZiHWgilM2HwvTp5lXJE,1122
65
- scanoss/inspection/copyleft.py,sha256=lOOq3-HwIvYVd0a_A0o2pG-m0rtFBHxXjEBLtHpRJto,8671
66
- scanoss/inspection/policy_check.py,sha256=ldUcKBXD74P4ldO417GP5PqJHE-BagDPBDOK-e3KZco,16009
67
- scanoss/inspection/undeclared_component.py,sha256=7WRLdDSf_XWtDMlvKRo3nvBy_041gQ2xR2zXqFCzmz0,11155
65
+ scanoss/inspection/copyleft.py,sha256=MqkixiGnOs7IEfhSmX5zRkJmmouHc76q8LP2Rqdu4AQ,8495
66
+ scanoss/inspection/policy_check.py,sha256=k8v7ei3oZBERt4l8S3AWEVn-qA2TsGkfYJT_i21M0s4,19076
67
+ scanoss/inspection/undeclared_component.py,sha256=my-KPEeFx7P2VG2dsYm5-7y83DDMGzf0MnBQdPExIHk,11026
68
68
  scanoss/inspection/utils/license_utils.py,sha256=Zb6QLmVJb86lKCwZyBsmwakyAtY1SXa54kUyyKmWMqA,5093
69
69
  scanoss/scanners/__init__.py,sha256=D4C0lWLuNp8k_BjQZEc07WZcUgAvriVwQWOk063b0ZU,1122
70
70
  scanoss/scanners/container_scanner.py,sha256=leP4roes6B9B95F49mJ0P_F8WcKCQkvJgk9azWyJrjg,16294
@@ -76,9 +76,9 @@ scanoss/utils/abstract_presenter.py,sha256=teiDTxBj5jBMCk2T8i4l1BJPf_u4zBLWrtCTF
76
76
  scanoss/utils/crc64.py,sha256=TMrwQimSdE6imhFOUL7oAG6Kxu-8qMpGWMuMg8QpSVs,3169
77
77
  scanoss/utils/file.py,sha256=62cA9a17TU9ZvfA3FY5HY4-QOajJeSrc8S6xLA_f-3M,2980
78
78
  scanoss/utils/simhash.py,sha256=6iu8DOcecPAY36SZjCOzrrLMT9oIE7-gI6QuYwUQ7B0,5793
79
- scanoss-1.25.1.dist-info/licenses/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
80
- scanoss-1.25.1.dist-info/METADATA,sha256=yIG7_hq018z-_68-M0jwt6hSb3oK5yol9Wku4k3m2V4,6060
81
- scanoss-1.25.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
- scanoss-1.25.1.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
83
- scanoss-1.25.1.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
84
- scanoss-1.25.1.dist-info/RECORD,,
79
+ scanoss-1.25.2.dist-info/licenses/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
80
+ scanoss-1.25.2.dist-info/METADATA,sha256=tLuNgHCCKBeUfqk0EWRkr5iv35GBIybi0nMBSBi1huw,6060
81
+ scanoss-1.25.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
+ scanoss-1.25.2.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
83
+ scanoss-1.25.2.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
84
+ scanoss-1.25.2.dist-info/RECORD,,