scanoss 1.17.0__py3-none-any.whl → 1.17.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 @@
22
22
  THE SOFTWARE.
23
23
  """
24
24
 
25
- __version__ = "1.17.0"
25
+ __version__ = "1.17.2"
@@ -1 +1 @@
1
- date: 20241023122954, utime: 1729686594
1
+ date: 20241104160508, utime: 1730736308
@@ -69,8 +69,8 @@ class Copyleft(PolicyCheck):
69
69
  if len(components) > 0:
70
70
  details = { 'components': components }
71
71
  return {
72
- 'details': json.dumps(details, indent=2),
73
- 'summary': f'{len(components)} component(s) with copyleft licenses were found.'
72
+ 'details': f'{json.dumps(details, indent=2)}\n',
73
+ 'summary': f'{len(components)} component(s) with copyleft licenses were found.\n'
74
74
  }
75
75
 
76
76
  def _markdown(self, components: list) -> Dict[str,Any]:
@@ -96,8 +96,8 @@ class Copyleft(PolicyCheck):
96
96
  # End license loop
97
97
  # End component loop
98
98
  return {
99
- 'details': f'### Copyleft licenses\n{self.generate_table(headers,rows,centered_columns)}',
100
- 'summary' : f'{len(components)} component(s) with copyleft licenses were found.'
99
+ 'details': f'### Copyleft licenses\n{self.generate_table(headers,rows,centered_columns)}\n',
100
+ 'summary' : f'{len(components)} component(s) with copyleft licenses were found.\n'
101
101
  }
102
102
 
103
103
  def _filter_components_with_copyleft_licenses(self, components: list) -> list:
@@ -133,7 +133,8 @@ class PolicyCheck(ScanossBase):
133
133
  """
134
134
  pass
135
135
 
136
- def _append_component(self,components: Dict[str, Any], new_component: Dict[str, Any]) -> Dict[str, Any]:
136
+ def _append_component(self,components: Dict[str, Any], new_component: Dict[str, Any],
137
+ id: str, status: str) -> Dict[str, Any]:
137
138
  """
138
139
  Append a new component to the component's dictionary.
139
140
 
@@ -143,15 +144,25 @@ class PolicyCheck(ScanossBase):
143
144
 
144
145
  :param components: The existing dictionary of components
145
146
  :param new_component: The new component to be added or updated
147
+ :param id: The new component ID
148
+ :param status: The new component status
146
149
  :return: The updated components dictionary
147
150
  """
148
- component_key = f"{new_component['purl'][0]}@{new_component['version']}"
151
+
152
+ # Determine the component key and purl based on component type
153
+ if id in [ComponentID.FILE.value, ComponentID.SNIPPET.value]:
154
+ purl = new_component['purl'][0] # Take first purl for these component types
155
+ else:
156
+ purl = new_component['purl']
157
+
158
+ component_key = f"{purl}@{new_component['version']}"
149
159
  components[component_key] = {
150
- 'purl': new_component['purl'][0],
151
- 'version': new_component['version'],
152
- 'licenses': {},
153
- 'status': new_component['status'],
160
+ 'purl': purl,
161
+ 'version': new_component['version'],
162
+ 'licenses': {},
163
+ 'status': status,
154
164
  }
165
+
155
166
  if not new_component.get('licenses'):
156
167
  self.print_stderr(f'WARNING: Results missing licenses. Skipping.')
157
168
  return components
@@ -187,6 +198,10 @@ class PolicyCheck(ScanossBase):
187
198
  if not component_id:
188
199
  self.print_stderr(f'WARNING: Result missing id. Skipping.')
189
200
  continue
201
+ status = c.get('status')
202
+ if not component_id:
203
+ self.print_stderr(f'WARNING: Result missing status. Skipping.')
204
+ continue
190
205
  if component_id in [ComponentID.FILE.value, ComponentID.SNIPPET.value]:
191
206
  if not c.get('purl'):
192
207
  self.print_stderr(f'WARNING: Result missing purl. Skipping.')
@@ -200,9 +215,10 @@ class PolicyCheck(ScanossBase):
200
215
  component_key = f"{c['purl'][0]}@{c['version']}"
201
216
  # Initialize or update the component entry
202
217
  if component_key not in components:
203
- components = self._append_component(components, c)
218
+ components = self._append_component(components, c, component_id, status)
219
+
204
220
  if c['id'] == ComponentID.DEPENDENCY.value:
205
- if c.get('dependency') is None:
221
+ if c.get('dependencies') is None:
206
222
  continue
207
223
  for d in c['dependencies']:
208
224
  if not d.get('purl'):
@@ -214,9 +230,9 @@ class PolicyCheck(ScanossBase):
214
230
  if not d.get('version'):
215
231
  self.print_stderr(f'WARNING: Result missing version. Skipping.')
216
232
  continue
217
- component_key = f"{d['purl'][0]}@{d['version']}"
233
+ component_key = f"{d['purl']}@{d['version']}"
218
234
  if component_key not in components:
219
- components = self._append_component(components, d)
235
+ components = self._append_component(components, d, component_id, status)
220
236
  # End of dependencies loop
221
237
  # End if
222
238
  # End of component loop
@@ -78,8 +78,8 @@ class UndeclaredComponent(PolicyCheck):
78
78
  """
79
79
  summary = f'{len(components)} undeclared component(s) were found.\n'
80
80
  if len(components) > 0:
81
- summary += (f' Add the following snippet into your `sbom.json` file \n'
82
- f' ```json \n {json.dumps(self._generate_sbom_file(components), indent=2)} ``` \n ')
81
+ summary += (f'Add the following snippet into your `sbom.json` file\n'
82
+ f'\n```json\n{json.dumps(self._generate_sbom_file(components), indent=2)}\n```\n')
83
83
  return summary
84
84
 
85
85
  def _json(self, components: list) -> Dict[str, Any]:
@@ -93,7 +93,7 @@ class UndeclaredComponent(PolicyCheck):
93
93
  if len(components) > 0:
94
94
  details = {'components': components}
95
95
  return {
96
- 'details': json.dumps(details, indent=2),
96
+ 'details': f'{json.dumps(details, indent=2)}\n',
97
97
  'summary': self._get_summary(components),
98
98
  }
99
99
 
@@ -111,24 +111,30 @@ class UndeclaredComponent(PolicyCheck):
111
111
  licenses = " - ".join(lic.get('spdxid', 'Unknown') for lic in component['licenses'])
112
112
  rows.append([component['purl'], component['version'], licenses])
113
113
  return {
114
- 'details': f'### Undeclared components\n{self.generate_table(headers,rows)}',
114
+ 'details': f'### Undeclared components\n{self.generate_table(headers,rows)}\n',
115
115
  'summary': self._get_summary(components),
116
116
  }
117
117
 
118
- def _generate_sbom_file(self, components: list) -> list:
118
+ def _generate_sbom_file(self, components: list) -> dict[str, list[dict[str, str]]]:
119
119
  """
120
120
  Generate a list of PURLs for the SBOM file.
121
121
 
122
122
  :param components: List of undeclared components
123
- :return: List of dictionaries containing PURLs
123
+ :return: SBOM Dictionary with components
124
124
  """
125
- sbom = {}
125
+
126
+ unique_components = {}
126
127
  if components is None:
127
128
  self.print_stderr(f'WARNING: No components provided!')
128
129
  else:
129
130
  for component in components:
130
- sbom[component['purl']] = { 'purl': component['purl'] }
131
- return list(sbom.values())
131
+ unique_components[component['purl']] = { 'purl': component['purl'] }
132
+
133
+ sbom = {
134
+ 'components': list(unique_components.values())
135
+ }
136
+
137
+ return sbom
132
138
 
133
139
  def run(self):
134
140
  """
@@ -0,0 +1,23 @@
1
+ def generate_table(headers, rows, centered_columns=None):
2
+ """
3
+ Generate Markdown table
4
+ :param headers: List of headers
5
+ :param rows: Rows
6
+ :param centered_columns: List with centered columns
7
+ """
8
+ COL_SEP = ' | '
9
+ centered_column_set = set(centered_columns or [])
10
+ def create_separator(header, index):
11
+ if centered_columns is None:
12
+ return '-'
13
+ return ':-:' if index in centered_column_set else '-'
14
+
15
+ row_separator = COL_SEP + COL_SEP.join(
16
+ create_separator(header, index) for index, header in enumerate(headers)
17
+ ) + COL_SEP
18
+
19
+ table_rows = [COL_SEP + COL_SEP.join(headers) + COL_SEP]
20
+ table_rows.append(row_separator)
21
+ table_rows.extend(COL_SEP + COL_SEP.join(row) + COL_SEP for row in rows)
22
+
23
+ return '\n'.join(table_rows)
@@ -0,0 +1,79 @@
1
+ from enum import Enum
2
+ from typing import Dict, Any
3
+
4
+ from scanoss.inspection.utils.license_utils import license_util
5
+
6
+
7
+ class ComponentID(Enum):
8
+ FILE = "file"
9
+ SNIPPET = "snippet"
10
+ DEPENDENCY = "dependency"
11
+
12
+
13
+ def _append_component(components: Dict[str, Any], new_component: Dict[str, Any]) -> Dict[str, Any]:
14
+ """
15
+ Append a new component to the components dictionary.
16
+
17
+ This function creates a new entry in the components dictionary for the given component,
18
+ or updates an existing entry if the component already exists. It also processes the
19
+ licenses associated with the component.
20
+
21
+ :param components: The existing dictionary of components
22
+ :param new_component: The new component to be added or updated
23
+ :return: The updated components dictionary
24
+ """
25
+ component_key = f"{new_component['purl'][0]}@{new_component['version']}"
26
+ components[component_key] = {
27
+ 'purl': new_component['purl'][0],
28
+ 'version': new_component['version'],
29
+ 'licenses': {},
30
+ 'status': new_component['status'],
31
+ }
32
+
33
+ # Process licenses for this component
34
+ for l in new_component['licenses']:
35
+ spdxid = l['name']
36
+ components[component_key]['licenses'][spdxid] = {
37
+ 'spdxid': spdxid,
38
+ 'copyleft': license_util.is_copyleft(spdxid),
39
+ 'url': l.get('url')
40
+ }
41
+
42
+ return components
43
+
44
+
45
+ def get_components(results: Dict[str, Any]) -> list:
46
+ """
47
+ Process the results dictionary to extract and format component information.
48
+
49
+ This function iterates through the results dictionary, identifying components from
50
+ different sources (files, snippets, and dependencies). It consolidates this information
51
+ into a list of unique components, each with its associated licenses and other details.
52
+
53
+ :param results: A dictionary containing the raw results of a component scan
54
+ :return: A list of dictionaries, each representing a unique component with its details
55
+ """
56
+ components = {}
57
+ for component in results.values():
58
+ for c in component:
59
+ if c['id'] in [ComponentID.FILE.value, ComponentID.SNIPPET.value]:
60
+ component_key = f"{c['purl'][0]}@{c['version']}"
61
+
62
+ # Initialize or update the component entry
63
+ if component_key not in components:
64
+ components = _append_component(components, c)
65
+
66
+ if c['id'] == ComponentID.DEPENDENCY.value:
67
+ for d in c['dependencies']:
68
+ component_key = f"{d['purl'][0]}@{d['version']}"
69
+
70
+ if component_key not in components:
71
+ components = _append_component(components, d)
72
+ # End of for loop
73
+ # End if
74
+ # End if
75
+ results = list(components.values())
76
+ for component in results:
77
+ component['licenses'] = list(component['licenses'].values())
78
+
79
+ return results
@@ -1,30 +1,30 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
3
-
4
- Copyright (c) 2024, SCANOSS
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the 'Software'), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2024, SCANOSS
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the 'Software'), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
23
  """
24
24
 
25
25
  import json
26
26
  from pathlib import Path
27
- from typing import Dict, List, TypedDict
27
+ from typing import List, TypedDict
28
28
 
29
29
  from .scanossbase import ScanossBase
30
30
 
@@ -123,7 +123,12 @@ class ScanossSettings(ScanossBase):
123
123
  list: If using SBOM.json
124
124
  """
125
125
  if self.settings_file_type == "legacy":
126
- return self.data.get("components", [])
126
+ if isinstance(self.data, list):
127
+ return self.data
128
+ elif isinstance(self.data, dict) and self.data.get("components"):
129
+ return self.data.get("components")
130
+ else:
131
+ return []
127
132
  return self.data.get("bom", {})
128
133
 
129
134
  def get_bom_include(self) -> List[BomEntry]:
scanoss/spdxlite.py CHANGED
@@ -180,7 +180,7 @@ class SpdxLite:
180
180
  data = {
181
181
  'spdxVersion': 'SPDX-2.2',
182
182
  'dataLicense': 'CC0-1.0',
183
- 'SPDXID': f'SPDXRef-{md5hex}',
183
+ 'SPDXID': f'SPDXRef-DOCUMENT',
184
184
  'name': 'SCANOSS-SBOM',
185
185
  'creationInfo': {
186
186
  'created': now.strftime('%Y-%m-%dT%H:%M:%SZ'),
@@ -214,6 +214,8 @@ class SpdxLite:
214
214
  comp_name = comp.get('component')
215
215
  comp_ver = comp.get('version')
216
216
  purl_ver = f'{purl}@{comp_ver}'
217
+ vendor = comp.get('vendor', 'NOASSERTION')
218
+ supplier = f"Organization: {vendor}" if vendor != 'NOASSERTION' else vendor
217
219
  purl_hash = hashlib.md5(f'{purl_ver}'.encode('utf-8')).hexdigest()
218
220
  purl_spdx = f'SPDXRef-{purl_hash}'
219
221
  data['documentDescribes'].append(purl_spdx)
@@ -227,6 +229,7 @@ class SpdxLite:
227
229
  'licenseConcluded': 'NOASSERTION',
228
230
  'filesAnalyzed': False,
229
231
  'copyrightText': 'NOASSERTION',
232
+ 'supplier': supplier,
230
233
  'externalRefs': [{
231
234
  'referenceCategory': 'PACKAGE-MANAGER',
232
235
  'referenceLocator': purl_ver,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scanoss
3
- Version: 1.17.0
3
+ Version: 1.17.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=a83GwGA7nr4Ahj8O8Dfo2DL11QhPNCHOrmNkzWYHX4c,1163
7
+ scanoss/__init__.py,sha256=aru_CeXo9ujcKEUaT1zaTFbIBCn_pJNsNzmB2T4ewwU,1163
8
8
  scanoss/cli.py,sha256=6NlNf1PHlaWNpsDhXFXvrwdLUFiCHbPypj4eFl4rJ5U,50665
9
9
  scanoss/components.py,sha256=ZHZ1KA69shxOASZK7USD9yPTITpAc_RXL5q5zpDK23o,12590
10
10
  scanoss/csvoutput.py,sha256=hBwr_Fc6mBdOdXgyQcdFrockYH-PJ0jblowlExJ6OPg,9925
@@ -13,13 +13,13 @@ scanoss/filecount.py,sha256=o7xb6m387ucnsU4H1OXGzf_AdWsudhAHe49T8uX4Ieo,6660
13
13
  scanoss/results.py,sha256=7G33QAYYI9qI61TCzXjSLYXMmg5CDtZS5e2QhnQfE74,9883
14
14
  scanoss/scancodedeps.py,sha256=_9d7MAV20-FrET7mF7gW-BZiz2eHrtwudgrEcSX0oZQ,11321
15
15
  scanoss/scanner.py,sha256=Boxk0A-AuS0DMB4UYArU0PWZ0yJlK4v1YgdeVnKmJck,52023
16
- scanoss/scanoss_settings.py,sha256=NpNZ2aCpRG2EqfJc9_BK6SnODqkOwVBEq3u-9s0KxPI,5986
16
+ scanoss/scanoss_settings.py,sha256=QOpBDfu6vYL-K3WxkujPbXWwut1BHWpN2mJTm7yMD9c,6162
17
17
  scanoss/scanossapi.py,sha256=TJxPctr-0DTn_26LfM__OAMfntaXzvheFTbdmU-5pnM,11953
18
18
  scanoss/scanossbase.py,sha256=zMDRCLbrcoRvYEKQRuZXnBiVY4_Vsplmg_APbB65oaU,3084
19
19
  scanoss/scanossgrpc.py,sha256=ythZkr6F0P0hl_KPYoHkos_IL97TxLKeYfAouX_CUnM,20491
20
20
  scanoss/scanpostprocessor.py,sha256=tfQk6GBmW1Yd2rqHHp6QKiYVdmTkBAcpoE4HHN__oKo,5899
21
21
  scanoss/scantype.py,sha256=R2-ExLGOrYxaJFtIK2AEo2caD0XrN1zpF5q1qT9Zsyc,1326
22
- scanoss/spdxlite.py,sha256=ZRcqMHutagRLX1GY7mqrzCsZernTVi5mCp6QZtGoZfY,15646
22
+ scanoss/spdxlite.py,sha256=REChAWV-6qhp16jc4X2lMb1v7VvYiDH5nN9VDV3fDaQ,15828
23
23
  scanoss/threadeddependencies.py,sha256=sOIAjiPTmxybKz2yhT4-ixXBeC4K8UQVq6JQj4e8mLc,9906
24
24
  scanoss/threadedscanning.py,sha256=T0tL8W1IEX_hLY5ksrAl_iQqtxT_KbyDhTDHo6a7xFE,9387
25
25
  scanoss/winnowing.py,sha256=HzMWRYh1XB4so71br-DUPpV6OlmymDfsnU-EOCCObJM,18734
@@ -50,17 +50,19 @@ scanoss/api/vulnerabilities/__init__.py,sha256=FLQtiDiv85Q1Chk-sJ9ky9WOV1mulZhEK
50
50
  scanoss/api/vulnerabilities/v2/__init__.py,sha256=FLQtiDiv85Q1Chk-sJ9ky9WOV1mulZhEKjiBihlwiaM,1139
51
51
  scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py,sha256=CFhF80av8tenGvn9AIsGEtRJPuV2dC_syA5JLZb2lDw,5464
52
52
  scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py,sha256=HlS4k4Zmx6RIAqaO9I96jD-eyF5yU6Xx04pVm7pdqOg,6864
53
- scanoss/data/build_date.txt,sha256=hUuGeBON89UGobFjKWWy0nZ8jWZcTyyZv2hfAXA5eac,40
53
+ scanoss/data/build_date.txt,sha256=oPE2N3MmwjrcnboSRBZJnf0DruUMcoSRdYculyX05aA,40
54
54
  scanoss/data/spdx-exceptions.json,sha256=s7UTYxC7jqQXr11YBlIWYCNwN6lRDFTR33Y8rpN_dA4,17953
55
55
  scanoss/data/spdx-licenses.json,sha256=A6Z0q82gaTLtnopBfzeIVZjJFxkdRW1g2TuumQc-lII,228794
56
56
  scanoss/inspection/__init__.py,sha256=z62680zKq4OmBOugSODvgpSwdsloZL7bvcaMbnx3xgU,1139
57
- scanoss/inspection/copyleft.py,sha256=K_4qIxdCDJUmV_adyatUPdQyTbXiXbjGYddJJVGYT-s,6568
58
- scanoss/inspection/policy_check.py,sha256=lbbHhdcLGWgRKKahX_ljqZmMgztHStGkFZltSHjPT8Y,14156
59
- scanoss/inspection/undeclared_component.py,sha256=vXLEktqPOfG0UKVi25w_EMS33tn3dtBXZUoySgq8OwA,6727
57
+ scanoss/inspection/copyleft.py,sha256=B150gqqEvXZXq5toYtmNCKY7M0WkooBUWYiIeu48aek,6581
58
+ scanoss/inspection/policy_check.py,sha256=r4qvY8j5Vz8FflVL1xZxkd7ufX_wLh5ocna6MoTkPWg,14775
59
+ scanoss/inspection/undeclared_component.py,sha256=XUxNz6iaAoeLPPT4XnfeQlvOv-2thmf1MxP3KRmegQE,6853
60
60
  scanoss/inspection/utils/license_utils.py,sha256=iln0414t-cfmVktmAd7ANK7oOqpfRUvwRwIgrj-6GJA,5098
61
- scanoss-1.17.0.dist-info/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
62
- scanoss-1.17.0.dist-info/METADATA,sha256=uQrzxUqJUoxojlk4xIhpUdYm89WnxmATnnusmCAeCTE,5936
63
- scanoss-1.17.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
64
- scanoss-1.17.0.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
65
- scanoss-1.17.0.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
66
- scanoss-1.17.0.dist-info/RECORD,,
61
+ scanoss/inspection/utils/markdown_utils.py,sha256=hCa7rqBvtRoAziz3wj0gbpUOrPJIEi3pTvIUrsZf6qc,808
62
+ scanoss/inspection/utils/result_utils.py,sha256=OJRFznK4WCBMNvgX9kTus5WI5eTKjTXp_kWya7ixCyQ,2938
63
+ scanoss-1.17.2.dist-info/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
64
+ scanoss-1.17.2.dist-info/METADATA,sha256=xdt4go57mXTL7fodzNRcOSC7ywmvFHTW-Hs6F5SWoGc,5936
65
+ scanoss-1.17.2.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
66
+ scanoss-1.17.2.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
67
+ scanoss-1.17.2.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
68
+ scanoss-1.17.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5