scanoss 1.25.1__tar.gz → 1.25.2__tar.gz

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.
Files changed (97) hide show
  1. {scanoss-1.25.1/src/scanoss.egg-info → scanoss-1.25.2}/PKG-INFO +1 -1
  2. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/__init__.py +1 -1
  3. scanoss-1.25.2/src/scanoss/data/build_date.txt +1 -0
  4. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/inspection/copyleft.py +1 -5
  5. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/inspection/policy_check.py +79 -9
  6. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/inspection/undeclared_component.py +1 -4
  7. {scanoss-1.25.1 → scanoss-1.25.2/src/scanoss.egg-info}/PKG-INFO +1 -1
  8. {scanoss-1.25.1 → scanoss-1.25.2}/tests/test_policy_inspect.py +8 -9
  9. scanoss-1.25.1/src/scanoss/data/build_date.txt +0 -1
  10. {scanoss-1.25.1 → scanoss-1.25.2}/LICENSE +0 -0
  11. {scanoss-1.25.1 → scanoss-1.25.2}/PACKAGE.md +0 -0
  12. {scanoss-1.25.1 → scanoss-1.25.2}/README.md +0 -0
  13. {scanoss-1.25.1 → scanoss-1.25.2}/pyproject.toml +0 -0
  14. {scanoss-1.25.1 → scanoss-1.25.2}/setup.cfg +0 -0
  15. {scanoss-1.25.1 → scanoss-1.25.2}/src/protoc_gen_swagger/__init__.py +0 -0
  16. {scanoss-1.25.1 → scanoss-1.25.2}/src/protoc_gen_swagger/options/__init__.py +0 -0
  17. {scanoss-1.25.1 → scanoss-1.25.2}/src/protoc_gen_swagger/options/annotations_pb2.py +0 -0
  18. {scanoss-1.25.1 → scanoss-1.25.2}/src/protoc_gen_swagger/options/annotations_pb2_grpc.py +0 -0
  19. {scanoss-1.25.1 → scanoss-1.25.2}/src/protoc_gen_swagger/options/openapiv2_pb2.py +0 -0
  20. {scanoss-1.25.1 → scanoss-1.25.2}/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py +0 -0
  21. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/__init__.py +0 -0
  22. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/common/__init__.py +0 -0
  23. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/common/v2/__init__.py +0 -0
  24. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/common/v2/scanoss_common_pb2.py +0 -0
  25. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py +0 -0
  26. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/components/__init__.py +0 -0
  27. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/components/v2/__init__.py +0 -0
  28. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/components/v2/scanoss_components_pb2.py +0 -0
  29. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py +0 -0
  30. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +0 -0
  31. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +0 -0
  32. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/dependencies/__init__.py +0 -0
  33. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/dependencies/v2/__init__.py +0 -0
  34. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +0 -0
  35. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +0 -0
  36. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/geoprovenance/__init__.py +0 -0
  37. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/geoprovenance/v2/__init__.py +0 -0
  38. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py +0 -0
  39. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py +0 -0
  40. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/scanning/__init__.py +0 -0
  41. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/scanning/v2/__init__.py +0 -0
  42. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/scanning/v2/scanoss_scanning_pb2.py +0 -0
  43. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +0 -0
  44. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/semgrep/__init__.py +0 -0
  45. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/semgrep/v2/__init__.py +0 -0
  46. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +0 -0
  47. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +0 -0
  48. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/vulnerabilities/__init__.py +0 -0
  49. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/vulnerabilities/v2/__init__.py +0 -0
  50. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +0 -0
  51. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +0 -0
  52. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/cli.py +0 -0
  53. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/components.py +0 -0
  54. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/constants.py +0 -0
  55. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/cryptography.py +0 -0
  56. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/csvoutput.py +0 -0
  57. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/cyclonedx.py +0 -0
  58. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/data/scanoss-settings-schema.json +0 -0
  59. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/data/spdx-exceptions.json +0 -0
  60. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/data/spdx-licenses.json +0 -0
  61. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/file_filters.py +0 -0
  62. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/filecount.py +0 -0
  63. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/inspection/__init__.py +0 -0
  64. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/inspection/utils/license_utils.py +0 -0
  65. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/results.py +0 -0
  66. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scancodedeps.py +0 -0
  67. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanner.py +0 -0
  68. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanners/__init__.py +0 -0
  69. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanners/container_scanner.py +0 -0
  70. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanners/folder_hasher.py +0 -0
  71. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanners/scanner_config.py +0 -0
  72. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanners/scanner_hfh.py +0 -0
  73. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanoss_settings.py +0 -0
  74. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanossapi.py +0 -0
  75. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanossbase.py +0 -0
  76. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanossgrpc.py +0 -0
  77. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scanpostprocessor.py +0 -0
  78. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/scantype.py +0 -0
  79. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/spdxlite.py +0 -0
  80. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/threadeddependencies.py +0 -0
  81. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/threadedscanning.py +0 -0
  82. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/utils/__init__.py +0 -0
  83. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/utils/abstract_presenter.py +0 -0
  84. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/utils/crc64.py +0 -0
  85. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/utils/file.py +0 -0
  86. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/utils/simhash.py +0 -0
  87. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss/winnowing.py +0 -0
  88. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss.egg-info/SOURCES.txt +0 -0
  89. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss.egg-info/dependency_links.txt +0 -0
  90. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss.egg-info/entry_points.txt +0 -0
  91. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss.egg-info/requires.txt +0 -0
  92. {scanoss-1.25.1 → scanoss-1.25.2}/src/scanoss.egg-info/top_level.txt +0 -0
  93. {scanoss-1.25.1 → scanoss-1.25.2}/tests/test_csv_output.py +0 -0
  94. {scanoss-1.25.1 → scanoss-1.25.2}/tests/test_file_filters.py +0 -0
  95. {scanoss-1.25.1 → scanoss-1.25.2}/tests/test_scan_post_processor.py +0 -0
  96. {scanoss-1.25.1 → scanoss-1.25.2}/tests/test_spdxlite.py +0 -0
  97. {scanoss-1.25.1 → scanoss-1.25.2}/tests/test_winnowing.py +0 -0
@@ -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
@@ -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'
@@ -0,0 +1 @@
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
@@ -114,7 +114,7 @@ class MyTestCase(unittest.TestCase):
114
114
  copyleft = Copyleft(filepath=input_file_name, format_type='json', explicit='MIT')
115
115
  status, results = copyleft.run()
116
116
  details = json.loads(results['details'])
117
- self.assertEqual(len(details['components']), 3)
117
+ self.assertEqual(len(details['components']), 2)
118
118
  self.assertEqual(status, 0)
119
119
 
120
120
  """
@@ -144,11 +144,10 @@ class MyTestCase(unittest.TestCase):
144
144
  expected_detail_output = (
145
145
  '### Copyleft licenses \n | Component | Version | License | URL | Copyleft |\n'
146
146
  ' | - | :-: | - | - | :-: |\n'
147
- '| pkg:github/scanoss/engine | 4.0.4 | MIT | https://spdx.org/licenses/MIT.html | YES | \n'
148
147
  ' | pkg:npm/%40electron/rebuild | 3.7.0 | MIT | https://spdx.org/licenses/MIT.html | YES |\n'
149
148
  '| pkg:npm/%40emotion/react | 11.13.3 | MIT | https://spdx.org/licenses/MIT.html | YES | \n'
150
149
  )
151
- expected_summary_output = '3 component(s) with copyleft licenses were found.\n'
150
+ expected_summary_output = '2 component(s) with copyleft licenses were found.\n'
152
151
  self.assertEqual(
153
152
  re.sub(r'\s|\\(?!`)|\\(?=`)', '', results['details']),
154
153
  re.sub(r'\s|\\(?!`)|\\(?=`)', '', expected_detail_output),
@@ -214,9 +213,9 @@ class MyTestCase(unittest.TestCase):
214
213
  expected_details_output = """ ### Undeclared components
215
214
  | Component | Version | License |
216
215
  | - | - | - |
217
- | pkg:github/scanoss/scanner.c | 1.3.3 | BSD-2-Clause - GPL-2.0-only |
216
+ | pkg:github/scanoss/scanner.c | 1.3.3 | GPL-2.0-only |
218
217
  | pkg:github/scanoss/scanner.c | 1.1.4 | GPL-2.0-only |
219
- | pkg:github/scanoss/wfp | 6afc1f6 | Zlib - GPL-2.0-only | """
218
+ | pkg:github/scanoss/wfp | 6afc1f6 | GPL-2.0-only | """
220
219
 
221
220
  expected_summary_output = """3 undeclared component(s) were found.
222
221
  Add the following snippet into your `sbom.json` file
@@ -257,9 +256,9 @@ class MyTestCase(unittest.TestCase):
257
256
  expected_details_output = """ ### Undeclared components
258
257
  | Component | Version | License |
259
258
  | - | - | - |
260
- | pkg:github/scanoss/scanner.c | 1.3.3 | BSD-2-Clause - GPL-2.0-only |
259
+ | pkg:github/scanoss/scanner.c | 1.3.3 | GPL-2.0-only |
261
260
  | pkg:github/scanoss/scanner.c | 1.1.4 | GPL-2.0-only |
262
- | pkg:github/scanoss/wfp | 6afc1f6 | Zlib - GPL-2.0-only | """
261
+ | pkg:github/scanoss/wfp | 6afc1f6 | GPL-2.0-only | """
263
262
 
264
263
  expected_summary_output = """3 undeclared component(s) were found.
265
264
  Add the following snippet into your `scanoss.json` file
@@ -332,9 +331,9 @@ class MyTestCase(unittest.TestCase):
332
331
  details = results['details']
333
332
  summary = results['summary']
334
333
  expected_details_output = """|*Component*|*Version*|*License*|
335
- |pkg:github/scanoss/scanner.c|1.3.3|BSD-2-Clause - GPL-2.0-only|
334
+ |pkg:github/scanoss/scanner.c|1.3.3|GPL-2.0-only|
336
335
  |pkg:github/scanoss/scanner.c|1.1.4|GPL-2.0-only|
337
- |pkg:github/scanoss/wfp|6afc1f6|Zlib - GPL-2.0-only|
336
+ |pkg:github/scanoss/wfp|6afc1f6|GPL-2.0-only|
338
337
  """
339
338
  expected_summary_output = """3 undeclared component(s) were found.
340
339
  Add the following snippet into your `scanoss.json` file
@@ -1 +0,0 @@
1
- date: 20250612124028, utime: 1749732028
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes