scanoss 1.27.0__py3-none-any.whl → 1.28.0__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.27.0'
25
+ __version__ = '1.28.0'
scanoss/cyclonedx.py CHANGED
@@ -22,14 +22,13 @@ SPDX-License-Identifier: MIT
22
22
  THE SOFTWARE.
23
23
  """
24
24
 
25
+ import datetime
25
26
  import json
26
27
  import os.path
27
28
  import sys
28
29
  import uuid
29
- import datetime
30
30
 
31
31
  from . import __version__
32
-
33
32
  from .scanossbase import ScanossBase
34
33
  from .spdxlite import SpdxLite
35
34
 
@@ -49,7 +48,7 @@ class CycloneDx(ScanossBase):
49
48
  self.debug = debug
50
49
  self._spdx = SpdxLite(debug=debug)
51
50
 
52
- def parse(self, data: json):
51
+ def parse(self, data: json): # noqa: PLR0912, PLR0915
53
52
  """
54
53
  Parse the given input (raw/plain) JSON string and return CycloneDX summary
55
54
  :param data: json - JSON object
@@ -58,7 +57,7 @@ class CycloneDx(ScanossBase):
58
57
  if not data:
59
58
  self.print_stderr('ERROR: No JSON data provided to parse.')
60
59
  return None, None
61
- self.print_debug(f'Processing raw results into CycloneDX format...')
60
+ self.print_debug('Processing raw results into CycloneDX format...')
62
61
  cdx = {}
63
62
  vdx = {}
64
63
  for f in data:
@@ -171,17 +170,22 @@ class CycloneDx(ScanossBase):
171
170
  success = self.produce_from_str(f.read(), output_file)
172
171
  return success
173
172
 
174
- def produce_from_json(self, data: json, output_file: str = None) -> bool:
173
+ def produce_from_json(self, data: json, output_file: str = None) -> tuple[bool, json]: # noqa: PLR0912
175
174
  """
176
- Produce the CycloneDX output from the input data
177
- :param data: JSON object
178
- :param output_file: Output file (optional)
179
- :return: True if successful, False otherwise
175
+ Produce the CycloneDX output from the raw scan results input data
176
+
177
+ Args:
178
+ data (json): JSON object
179
+ output_file (str, optional): Output file (optional). Defaults to None.
180
+
181
+ Returns:
182
+ bool: True if successful, False otherwise
183
+ json: The CycloneDX output
180
184
  """
181
185
  cdx, vdx = self.parse(data)
182
186
  if not cdx:
183
187
  self.print_stderr('ERROR: No CycloneDX data returned for the JSON string provided.')
184
- return False
188
+ return False, None
185
189
  self._spdx.load_license_data() # Load SPDX license name data for later reference
186
190
  #
187
191
  # Using CDX version 1.4: https://cyclonedx.org/docs/1.4/json/
@@ -264,7 +268,7 @@ class CycloneDx(ScanossBase):
264
268
  if output_file:
265
269
  file.close()
266
270
 
267
- return True
271
+ return True, data
268
272
 
269
273
  def produce_from_str(self, json_str: str, output_file: str = None) -> bool:
270
274
  """
@@ -283,6 +287,87 @@ class CycloneDx(ScanossBase):
283
287
  return False
284
288
  return self.produce_from_json(data, output_file)
285
289
 
290
+ def _normalize_vulnerability_id(self, vuln: dict) -> tuple[str, str]:
291
+ """
292
+ Normalize vulnerability ID and CVE from different possible field names.
293
+ Returns tuple of (vuln_id, vuln_cve).
294
+ """
295
+ vuln_id = vuln.get('ID', '') or vuln.get('id', '')
296
+ vuln_cve = vuln.get('CVE', '') or vuln.get('cve', '')
297
+
298
+ # Skip CPE entries, use CVE if available
299
+ if vuln_id.upper().startswith('CPE:') and vuln_cve:
300
+ vuln_id = vuln_cve
301
+
302
+ return vuln_id, vuln_cve
303
+
304
+ def _create_vulnerability_entry(self, vuln_id: str, vuln: dict, vuln_cve: str, purl: str) -> dict:
305
+ """
306
+ Create a new vulnerability entry for CycloneDX format.
307
+ """
308
+ vuln_source = vuln.get('source', '').lower()
309
+ return {
310
+ 'id': vuln_id,
311
+ 'source': {
312
+ 'name': 'NVD' if vuln_source == 'nvd' else 'GitHub Advisories',
313
+ 'url': f'https://nvd.nist.gov/vuln/detail/{vuln_cve}'
314
+ if vuln_source == 'nvd'
315
+ else f'https://github.com/advisories/{vuln_id}'
316
+ },
317
+ 'ratings': [{'severity': self._sev_lookup(vuln.get('severity', 'unknown').lower())}],
318
+ 'affects': [{'ref': purl}]
319
+ }
320
+
321
+ def append_vulnerabilities(self, cdx_dict: dict, vulnerabilities_data: dict, purl: str) -> dict:
322
+ """
323
+ Append vulnerabilities to an existing CycloneDX dictionary
324
+
325
+ Args:
326
+ cdx_dict (dict): The existing CycloneDX dictionary
327
+ vulnerabilities_data (dict): The vulnerabilities data from get_vulnerabilities_json
328
+ purl (str): The PURL of the component these vulnerabilities affect
329
+
330
+ Returns:
331
+ dict: The updated CycloneDX dictionary with vulnerabilities appended
332
+ """
333
+ if not cdx_dict or not vulnerabilities_data:
334
+ return cdx_dict
335
+
336
+ if 'vulnerabilities' not in cdx_dict:
337
+ cdx_dict['vulnerabilities'] = []
338
+
339
+ # Extract vulnerabilities from the response
340
+ vulns_list = vulnerabilities_data.get('purls', [])
341
+ if not vulns_list:
342
+ return cdx_dict
343
+
344
+ vuln_items = vulns_list[0].get('vulnerabilities', [])
345
+
346
+ for vuln in vuln_items:
347
+ vuln_id, vuln_cve = self._normalize_vulnerability_id(vuln)
348
+
349
+ # Skip empty IDs or CPE-only entries
350
+ if not vuln_id or vuln_id.upper().startswith('CPE:'):
351
+ continue
352
+
353
+ # Check if vulnerability already exists
354
+ existing_vuln = next(
355
+ (v for v in cdx_dict['vulnerabilities'] if v.get('id') == vuln_id),
356
+ None
357
+ )
358
+
359
+ if existing_vuln:
360
+ # Add this PURL to the affects list if not already present
361
+ if not any(ref.get('ref') == purl for ref in existing_vuln.get('affects', [])):
362
+ existing_vuln['affects'].append({'ref': purl})
363
+ else:
364
+ # Create new vulnerability entry
365
+ cdx_dict['vulnerabilities'].append(
366
+ self._create_vulnerability_entry(vuln_id, vuln, vuln_cve, purl)
367
+ )
368
+
369
+ return cdx_dict
370
+
286
371
  @staticmethod
287
372
  def _sev_lookup(value: str):
288
373
  """
@@ -1 +1 @@
1
- date: 20250708100043, utime: 1751968843
1
+ date: 20250710142446, utime: 1752157486
scanoss/scanner.py CHANGED
@@ -22,40 +22,40 @@ SPDX-License-Identifier: MIT
22
22
  THE SOFTWARE.
23
23
  """
24
24
 
25
+ import datetime
25
26
  import json
26
27
  import os
27
- from pathlib import Path
28
28
  import sys
29
- import datetime
29
+ from pathlib import Path
30
30
  from typing import Any, Dict, List, Optional
31
- import importlib_resources
32
31
 
32
+ import importlib_resources
33
33
  from progress.bar import Bar
34
34
  from progress.spinner import Spinner
35
35
  from pypac.parser import PACFile
36
36
 
37
37
  from scanoss.file_filters import FileFilters
38
38
 
39
- from .scanossapi import ScanossApi
40
- from .cyclonedx import CycloneDx
41
- from .spdxlite import SpdxLite
39
+ from . import __version__
42
40
  from .csvoutput import CsvOutput
43
- from .threadedscanning import ThreadedScanning
41
+ from .cyclonedx import CycloneDx
44
42
  from .scancodedeps import ScancodeDeps
45
- from .threadeddependencies import ThreadedDependencies, SCOPE
46
- from .scanossgrpc import ScanossGrpc
47
- from .scantype import ScanType
48
- from .scanossbase import ScanossBase
49
43
  from .scanoss_settings import ScanossSettings
44
+ from .scanossapi import ScanossApi
45
+ from .scanossbase import ScanossBase
46
+ from .scanossgrpc import ScanossGrpc
50
47
  from .scanpostprocessor import ScanPostProcessor
51
- from . import __version__
48
+ from .scantype import ScanType
49
+ from .spdxlite import SpdxLite
50
+ from .threadeddependencies import SCOPE, ThreadedDependencies
51
+ from .threadedscanning import ThreadedScanning
52
52
 
53
53
  FAST_WINNOWING = False
54
54
  try:
55
55
  from scanoss_winnowing.winnowing import Winnowing
56
56
 
57
57
  FAST_WINNOWING = True
58
- except ModuleNotFoundError or ImportError:
58
+ except (ModuleNotFoundError, ImportError):
59
59
  FAST_WINNOWING = False
60
60
  from .winnowing import Winnowing
61
61
 
@@ -284,7 +284,7 @@ class Scanner(ScanossBase):
284
284
  return True
285
285
  return False
286
286
 
287
- def scan_folder_with_options(
287
+ def scan_folder_with_options( # noqa: PLR0913
288
288
  self,
289
289
  scan_dir: str,
290
290
  deps_file: str = None,
@@ -332,7 +332,7 @@ class Scanner(ScanossBase):
332
332
  success = False
333
333
  return success
334
334
 
335
- def scan_folder(self, scan_dir: str) -> bool:
335
+ def scan_folder(self, scan_dir: str) -> bool: # noqa: PLR0912, PLR0915
336
336
  """
337
337
  Scan the specified folder producing fingerprints, send to the SCANOSS API and return results
338
338
 
@@ -400,7 +400,7 @@ class Scanner(ScanossBase):
400
400
  scan_block += wfp
401
401
  scan_size = len(scan_block.encode('utf-8'))
402
402
  wfp_file_count += 1
403
- # If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue
403
+ # If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue # noqa: E501
404
404
  if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
405
405
  self.threaded_scan.queue_add(scan_block)
406
406
  queue_size += 1
@@ -484,7 +484,7 @@ class Scanner(ScanossBase):
484
484
  self.__log_result(json.dumps(results, indent=2, sort_keys=True))
485
485
  elif self.output_format == 'cyclonedx':
486
486
  cdx = CycloneDx(self.debug, self.scan_output)
487
- success = cdx.produce_from_json(results)
487
+ success, _ = cdx.produce_from_json(results)
488
488
  elif self.output_format == 'spdxlite':
489
489
  spdxlite = SpdxLite(self.debug, self.scan_output)
490
490
  success = spdxlite.produce_from_json(results)
@@ -509,7 +509,7 @@ class Scanner(ScanossBase):
509
509
  for response in scan_responses:
510
510
  if response is not None:
511
511
  if file_map:
512
- response = self._deobfuscate_filenames(response, file_map)
512
+ response = self._deobfuscate_filenames(response, file_map) # noqa: PLW2901
513
513
  results.update(response)
514
514
 
515
515
  dep_files = dep_responses.get('files', None) if dep_responses else None
@@ -532,7 +532,7 @@ class Scanner(ScanossBase):
532
532
  deobfuscated[key] = value
533
533
  return deobfuscated
534
534
 
535
- def scan_file_with_options(
535
+ def scan_file_with_options( # noqa: PLR0913
536
536
  self,
537
537
  file: str,
538
538
  deps_file: str = None,
@@ -603,7 +603,7 @@ class Scanner(ScanossBase):
603
603
  success = False
604
604
  return success
605
605
 
606
- def scan_files(self, files: []) -> bool:
606
+ def scan_files(self, files: []) -> bool: # noqa: PLR0912, PLR0915
607
607
  """
608
608
  Scan the specified list of files, producing fingerprints, send to the SCANOSS API and return results
609
609
  Please note that by providing an explicit list you bypass any exclusions that may be defined on the scanner
@@ -657,7 +657,7 @@ class Scanner(ScanossBase):
657
657
  file_count += 1
658
658
  if self.threaded_scan:
659
659
  wfp_size = len(wfp.encode('utf-8'))
660
- # If the WFP is bigger than the max post size and we already have something stored in the scan block, add it to the queue
660
+ # If the WFP is bigger than the max post size and we already have something stored in the scan block, add it to the queue # noqa: E501
661
661
  if scan_block != '' and (wfp_size + scan_size) >= self.max_post_size:
662
662
  self.threaded_scan.queue_add(scan_block)
663
663
  queue_size += 1
@@ -666,7 +666,7 @@ class Scanner(ScanossBase):
666
666
  scan_block += wfp
667
667
  scan_size = len(scan_block.encode('utf-8'))
668
668
  wfp_file_count += 1
669
- # If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue
669
+ # If the scan request block (group of WFPs) or larger than the POST size or we have reached the file limit, add it to the queue # noqa: E501
670
670
  if wfp_file_count > self.post_file_count or scan_size >= self.max_post_size:
671
671
  self.threaded_scan.queue_add(scan_block)
672
672
  queue_size += 1
@@ -755,7 +755,7 @@ class Scanner(ScanossBase):
755
755
  success = False
756
756
  return success
757
757
 
758
- def scan_wfp_file(self, file: str = None) -> bool:
758
+ def scan_wfp_file(self, file: str = None) -> bool: # noqa: PLR0912, PLR0915
759
759
  """
760
760
  Scan the contents of the specified WFP file (in the current process)
761
761
  :param file: Scan the contents of the specified WFP file (in the current process)
@@ -436,10 +436,12 @@ class ContainerScannerPresenter(AbstractPresenter):
436
436
  scan_results = {}
437
437
  for f in self.scanner.decorated_scan_results['files']:
438
438
  scan_results[f['file']] = [f]
439
- if not cdx.produce_from_json(scan_results, self.output_file):
439
+ success, cdx_output = cdx.produce_from_json(scan_results)
440
+ if not success:
440
441
  error_msg = 'Failed to produce CycloneDX output'
441
442
  self.base.print_stderr(error_msg)
442
- raise ValueError(error_msg)
443
+ return None
444
+ return json.dumps(cdx_output, indent=2)
443
445
 
444
446
  def _format_spdxlite_output(self) -> str:
445
447
  """
@@ -162,7 +162,7 @@ class ScannerHFHPresenter(AbstractPresenter):
162
162
  else str(self.scanner.scan_results)
163
163
  )
164
164
 
165
- def _format_cyclonedx_output(self) -> str:
165
+ def _format_cyclonedx_output(self) -> str: # noqa: PLR0911
166
166
  if not self.scanner.scan_results:
167
167
  return ''
168
168
  try:
@@ -193,17 +193,28 @@ class ScannerHFHPresenter(AbstractPresenter):
193
193
  }
194
194
  ]
195
195
  }
196
+
197
+ get_vulnerabilities_json_request = {
198
+ 'purls': [{'purl': purl, 'requirement': best_match_version['version']}],
199
+ }
196
200
 
197
201
  decorated_scan_results = self.scanner.client.get_dependencies(get_dependencies_json_request)
202
+ vulnerabilities = self.scanner.client.get_vulnerabilities_json(get_vulnerabilities_json_request)
198
203
 
199
- cdx = CycloneDx(self.base.debug, self.output_file)
204
+ cdx = CycloneDx(self.base.debug)
200
205
  scan_results = {}
201
206
  for f in decorated_scan_results['files']:
202
207
  scan_results[f['file']] = [f]
203
- if not cdx.produce_from_json(scan_results, self.output_file):
208
+ success, cdx_output = cdx.produce_from_json(scan_results)
209
+ if not success:
204
210
  error_msg = 'ERROR: Failed to produce CycloneDX output'
205
211
  self.base.print_stderr(error_msg)
206
- raise ValueError(error_msg)
212
+ return None
213
+
214
+ if vulnerabilities:
215
+ cdx_output = cdx.append_vulnerabilities(cdx_output, vulnerabilities, purl)
216
+
217
+ return json.dumps(cdx_output, indent=2)
207
218
  except Exception as e:
208
219
  self.base.print_stderr(f'ERROR: Failed to get license information: {e}')
209
220
  return None
scanoss/scanossgrpc.py CHANGED
@@ -326,7 +326,7 @@ class ScanossGrpc(ScanossBase):
326
326
  request = ParseDict(purls, PurlRequest()) # Parse the JSON/Dict into the purl request object
327
327
  metadata = self.metadata[:]
328
328
  metadata.append(('x-request-id', request_id)) # Set a Request ID
329
- self.print_debug(f'Sending crypto data for decoration (rqId: {request_id})...')
329
+ self.print_debug(f'Sending vulnerability data for decoration (rqId: {request_id})...')
330
330
  resp = self.vuln_stub.GetVulnerabilities(request, metadata=metadata, timeout=self.timeout)
331
331
  except Exception as e:
332
332
  self.print_stderr(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scanoss
3
- Version: 1.27.0
3
+ Version: 1.28.0
4
4
  Summary: Simple Python library to leverage the SCANOSS APIs
5
5
  Home-page: https://scanoss.com
6
6
  Author: SCANOSS
@@ -4,22 +4,22 @@ 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=YH4I-lAz5Zn3nEU1mwGqNZPPhcS1o4Lu6itgmXKlV0c,1146
7
+ scanoss/__init__.py,sha256=Sre04UP925CNKzy9Agq2V3oSyx5Jx3X14ZW9gtmdE5A,1146
8
8
  scanoss/cli.py,sha256=9ELIAJy06g4KyvnALzPSQ_Rh1ypALbyQGGKrjb4sCOk,72615
9
9
  scanoss/components.py,sha256=b0R9DdKuXqyQiw5nZZwjQ6NJXBr1U9gyx1RI2FP9ozA,14511
10
10
  scanoss/constants.py,sha256=On8mQ-8ardVMHSJ7WOJqeTvGXIOWPLCgUanjE7Wk-wE,351
11
11
  scanoss/cryptography.py,sha256=Q39MOCscP-OFvrnPXaPOMFFkc8OKnf3mC3SgZYEtCog,9407
12
12
  scanoss/csvoutput.py,sha256=qNKRwcChSkgIwLm00kZiVX6iHVQUF4Apl-sMbzJ5Taw,10192
13
- scanoss/cyclonedx.py,sha256=UktDuqZUbXSggdt864Pg8ziTD7sdEQtLxfYL7vd_ZCE,12756
13
+ scanoss/cyclonedx.py,sha256=n3SVuHxiN1Oa-CaqAOtHsLTFefvXEjgJbpsKa0AcwDY,16267
14
14
  scanoss/file_filters.py,sha256=2DzyvSVR7We7U36UurtJj3cdQturUjDl8j3OIqmv4Pg,20638
15
15
  scanoss/filecount.py,sha256=RZjKQ6M5P_RQg0_PMD2tsRe5Z8f98ke0sxYVjPDN8iQ,6538
16
16
  scanoss/results.py,sha256=47ZXXuU2sDjYa5vhtbWTmikit9jHhA0rsYKwkvZFI5w,9252
17
17
  scanoss/scancodedeps.py,sha256=JbpoGW1POtPMmowzfwa4oh8sSBeeQCqaW9onvc4UFYM,11517
18
- scanoss/scanner.py,sha256=ZL8I8KtVyXgUMcl7Ccbip_Q1IlU9WTgI-mFtSpF1JWw,45223
18
+ scanoss/scanner.py,sha256=tS5yR6byhbVliSV0vTC7dkdX9XOhiTi8s9tCkDSObik,45397
19
19
  scanoss/scanoss_settings.py,sha256=393JnWLsEZhvMg5tPUGgxmqnBKp8AcLxYsDRbLP7aV4,10650
20
20
  scanoss/scanossapi.py,sha256=v4D9i9Impa82Enw-5hZ7KLlscDIpaILNbGOMj3MJXqs,13067
21
21
  scanoss/scanossbase.py,sha256=Dkpwxa8NH8XN1iRl03NM_Mkvby0JQ4qfvCiiUrJ5ul0,3163
22
- scanoss/scanossgrpc.py,sha256=B0rl676-B-ZxqXRp7blXnqbAGPC5rqLAQHG28NoC32E,30004
22
+ scanoss/scanossgrpc.py,sha256=uwAp9CzA_t7oMXYo7o81j8kVgn8qSeTjA4b1Jj8hoL0,30011
23
23
  scanoss/scanpostprocessor.py,sha256=-JsThlxrU70r92GHykTMERnicdd-6jmwNsE4PH0MN2o,11063
24
24
  scanoss/scantype.py,sha256=gFmyVmKQpHWogN2iCmMj032e_sZo4T92xS3_EH5B3Tc,1310
25
25
  scanoss/spdxlite.py,sha256=MQqFgQhIO-yrbRwEAQS77HmRgP5GDxff-2JYLVoceA0,28946
@@ -57,7 +57,7 @@ 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=MYvdFBxu-jVdZOEyHhyOpGsXpUjQK19aUZUWJivaIgU,40
60
+ scanoss/data/build_date.txt,sha256=iYCQ03ljoro3XW9RTUH04V18pc85cKHRTeyfyVL06BI,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
@@ -70,18 +70,18 @@ scanoss/inspection/policy_check.py,sha256=R9-7PxDHGzXCDVF8sWE3KcORgICDuZbx1-xvSo
70
70
  scanoss/inspection/undeclared_component.py,sha256=HGto8-ZBccrtczIARughG298Cwqb4k1BLCihkbmiFnk,11496
71
71
  scanoss/inspection/utils/license_utils.py,sha256=Zb6QLmVJb86lKCwZyBsmwakyAtY1SXa54kUyyKmWMqA,5093
72
72
  scanoss/scanners/__init__.py,sha256=D4C0lWLuNp8k_BjQZEc07WZcUgAvriVwQWOk063b0ZU,1122
73
- scanoss/scanners/container_scanner.py,sha256=leP4roes6B9B95F49mJ0P_F8WcKCQkvJgk9azWyJrjg,16294
73
+ scanoss/scanners/container_scanner.py,sha256=fOrb64owrstX7LnTuxiIan059YgLeKXeBS6g2QaCyq0,16346
74
74
  scanoss/scanners/folder_hasher.py,sha256=-qvTtMC0iPj7zS8nMSZZJyt9d62MeQIK0LcrNDkt7yc,12267
75
75
  scanoss/scanners/scanner_config.py,sha256=egG7cw3S2akU-D9M1aLE5jLrfz_c8e7_DIotMnnpM84,2601
76
- scanoss/scanners/scanner_hfh.py,sha256=CGTRzg9Epyyi7DCvQXVY91A8P0GGl8bzfr0zRCaM3XA,7906
76
+ scanoss/scanners/scanner_hfh.py,sha256=OvayCIq_a5iJwv7H7OCdB9K0vI9oxAz9UvgGfg7xrLU,8392
77
77
  scanoss/utils/__init__.py,sha256=0hjb5ktavp7utJzFhGMPImPaZiHWgilM2HwvTp5lXJE,1122
78
78
  scanoss/utils/abstract_presenter.py,sha256=teiDTxBj5jBMCk2T8i4l1BJPf_u4zBLWrtCTFHSSECM,3148
79
79
  scanoss/utils/crc64.py,sha256=TMrwQimSdE6imhFOUL7oAG6Kxu-8qMpGWMuMg8QpSVs,3169
80
80
  scanoss/utils/file.py,sha256=62cA9a17TU9ZvfA3FY5HY4-QOajJeSrc8S6xLA_f-3M,2980
81
81
  scanoss/utils/simhash.py,sha256=6iu8DOcecPAY36SZjCOzrrLMT9oIE7-gI6QuYwUQ7B0,5793
82
- scanoss-1.27.0.dist-info/licenses/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
83
- scanoss-1.27.0.dist-info/METADATA,sha256=TB02dYgadlHHeQhCDWJiSRDJxQ52lT10TuWFTdE6W1E,6060
84
- scanoss-1.27.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
- scanoss-1.27.0.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
86
- scanoss-1.27.0.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
87
- scanoss-1.27.0.dist-info/RECORD,,
82
+ scanoss-1.28.0.dist-info/licenses/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
83
+ scanoss-1.28.0.dist-info/METADATA,sha256=MCZLZyTbAL_542yYN9oJGDfDUlzUxaWRaGbOqE7030o,6060
84
+ scanoss-1.28.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
+ scanoss-1.28.0.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
86
+ scanoss-1.28.0.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
87
+ scanoss-1.28.0.dist-info/RECORD,,