Skip to content

Commit 5001945

Browse files
committed
bug: SP-1715 Fixes Parsing of Dependency Field in Policy Checks
1 parent 4391efd commit 5001945

File tree

5 files changed

+95
-24
lines changed

5 files changed

+95
-24
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Added
1010
- Upcoming changes...
1111

12+
## [1.17.2] - 2024-10-29
13+
### Fixed
14+
- Fixed parsing of dependencies in Policy Checks
15+
1216
## [1.17.1] - 2024-10-24
1317
### Fixed
1418
- Fixed policy summary output
@@ -369,3 +373,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
369373
[1.16.0]: https://github.com/scanoss/scanoss.py/compare/v1.15.0...v1.16.0
370374
[1.17.0]: https://github.com/scanoss/scanoss.py/compare/v1.16.0...v1.17.0
371375
[1.17.1]: https://github.com/scanoss/scanoss.py/compare/v1.17.0...v1.17.1
376+
[1.17.2]: https://github.com/scanoss/scanoss.py/compare/v1.17.1...v1.17.2

src/scanoss/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
THE SOFTWARE.
2323
"""
2424

25-
__version__ = "1.17.1"
25+
__version__ = "1.17.2"

src/scanoss/inspection/policy_check.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ def _markdown(self, components: list) -> Dict[str, Any]:
133133
"""
134134
pass
135135

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]:
137138
"""
138139
Append a new component to the component's dictionary.
139140
@@ -143,15 +144,25 @@ def _append_component(self,components: Dict[str, Any], new_component: Dict[str,
143144
144145
:param components: The existing dictionary of components
145146
: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
146149
:return: The updated components dictionary
147150
"""
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']}"
149159
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,
154164
}
165+
155166
if not new_component.get('licenses'):
156167
self.print_stderr(f'WARNING: Results missing licenses. Skipping.')
157168
return components
@@ -187,6 +198,10 @@ def _get_components_from_results(self,results: Dict[str, Any]) -> list or None:
187198
if not component_id:
188199
self.print_stderr(f'WARNING: Result missing id. Skipping.')
189200
continue
201+
status = c.get('status')
202+
if not component_id:
203+
self.print_stderr(f'WARNING: Result missing status. Skipping.')
204+
continue
190205
if component_id in [ComponentID.FILE.value, ComponentID.SNIPPET.value]:
191206
if not c.get('purl'):
192207
self.print_stderr(f'WARNING: Result missing purl. Skipping.')
@@ -200,9 +215,10 @@ def _get_components_from_results(self,results: Dict[str, Any]) -> list or None:
200215
component_key = f"{c['purl'][0]}@{c['version']}"
201216
# Initialize or update the component entry
202217
if component_key not in components:
203-
components = self._append_component(components, c)
218+
components = self._append_component(components, c, component_id, status)
219+
204220
if c['id'] == ComponentID.DEPENDENCY.value:
205-
if c.get('dependency') is None:
221+
if c.get('dependencies') is None:
206222
continue
207223
for d in c['dependencies']:
208224
if not d.get('purl'):
@@ -214,9 +230,9 @@ def _get_components_from_results(self,results: Dict[str, Any]) -> list or None:
214230
if not d.get('version'):
215231
self.print_stderr(f'WARNING: Result missing version. Skipping.')
216232
continue
217-
component_key = f"{d['purl'][0]}@{d['version']}"
233+
component_key = f"{d['purl']}@{d['version']}"
218234
if component_key not in components:
219-
components = self._append_component(components, d)
235+
components = self._append_component(components, d, component_id, status)
220236
# End of dependencies loop
221237
# End if
222238
# End of component loop

tests/data/result.json

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,5 +415,39 @@
415415
"vendor": "scanoss",
416416
"version": "4.0.4"
417417
}
418-
]
418+
],
419+
"example_codebase/dependencies/package.json": [
420+
{
421+
"dependencies": [
422+
{
423+
"component": "@electron/rebuild",
424+
"licenses": [
425+
{
426+
"is_spdx_approved": true,
427+
"name": "MIT",
428+
"spdx_id": "MIT"
429+
}
430+
],
431+
"purl": "pkg:npm/%40electron/rebuild",
432+
"url": "https://www.npmjs.com/package/%40electron/rebuild",
433+
"version": "3.7.0"
434+
},
435+
{
436+
"component": "@emotion/react",
437+
"licenses": [
438+
{
439+
"is_spdx_approved": true,
440+
"name": "MIT",
441+
"spdx_id": "MIT"
442+
}
443+
],
444+
"purl": "pkg:npm/%40emotion/react",
445+
"url": "https://www.npmjs.com/package/%40emotion/react",
446+
"version": "11.13.3"
447+
}
448+
],
449+
"id": "dependency",
450+
"status": "pending"
451+
}
452+
]
419453
}

tests/policy-inspect-test.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def test_copyleft_policy_explicit(self):
110110
copyleft = Copyleft(filepath=input_file_name, format_type='json', explicit='MIT')
111111
status, results = copyleft.run()
112112
details = json.loads(results['details'])
113-
self.assertEqual(len(details['components']), 1)
113+
self.assertEqual(len(details['components']), 3)
114114
self.assertEqual(status,0)
115115

116116
"""
@@ -138,8 +138,10 @@ def test_copyleft_policy_markdown(self):
138138
status, results = copyleft.run()
139139
expected_detail_output = ('### Copyleft licenses \n | Component | Version | License | URL | Copyleft |\n'
140140
' | - | :-: | - | - | :-: |\n'
141-
' | pkg:github/scanoss/engine | 4.0.4 | MIT | https://spdx.org/licenses/MIT.html | YES | ')
142-
expected_summary_output = '1 component(s) with copyleft licenses were found.\n'
141+
'| pkg:github/scanoss/engine | 4.0.4 | MIT | https://spdx.org/licenses/MIT.html | YES | \n'
142+
' | pkg:npm/%40electron/rebuild | 3.7.0 | MIT | https://spdx.org/licenses/MIT.html | YES |\n'
143+
'| pkg:npm/%40emotion/react | 11.13.3 | MIT | https://spdx.org/licenses/MIT.html | YES | \n')
144+
expected_summary_output = '3 component(s) with copyleft licenses were found.\n'
143145
self.assertEqual(re.sub(r'\s|\\(?!`)|\\(?=`)', '', results['details']),
144146
re.sub(r'\s|\\(?!`)|\\(?=`)', '', expected_detail_output))
145147
self.assertEqual(results['summary'], expected_summary_output)
@@ -167,7 +169,7 @@ def test_undeclared_policy(self):
167169
status, results = undeclared.run()
168170
details = json.loads(results['details'])
169171
summary = results['summary']
170-
expected_summary_output = """3 undeclared component(s) were found.
172+
expected_summary_output = """5 undeclared component(s) were found.
171173
Add the following snippet into your `sbom.json` file
172174
```json
173175
[
@@ -176,10 +178,16 @@ def test_undeclared_policy(self):
176178
},
177179
{
178180
"purl": "pkg:github/scanoss/wfp"
181+
},
182+
{
183+
"purl": "pkg:npm/%40electron/rebuild"
184+
},
185+
{
186+
"purl": "pkg:npm/%40emotion/react"
179187
}
180188
]```
181189
"""
182-
self.assertEqual(len(details['components']), 3)
190+
self.assertEqual(len(details['components']), 5)
183191
self.assertEqual(re.sub(r'\s|\\(?!`)|\\(?=`)', '', summary), re.sub(r'\s|\\(?!`)|\\(?=`)',
184192
'', expected_summary_output))
185193
self.assertEqual(status, 0)
@@ -200,18 +208,26 @@ def test_undeclared_policy_markdown(self):
200208
| - | - | - |
201209
| pkg:github/scanoss/scanner.c | 1.3.3 | BSD-2-Clause - GPL-2.0-only |
202210
| pkg:github/scanoss/scanner.c | 1.1.4 | GPL-2.0-only |
203-
| pkg:github/scanoss/wfp | 6afc1f6 | Zlib - GPL-2.0-only | """
211+
| pkg:github/scanoss/wfp | 6afc1f6 | Zlib - GPL-2.0-only |
212+
| pkg:npm/%40electron/rebuild | 3.7.0 | MIT |
213+
| pkg:npm/%40emotion/react | 11.13.3 | MIT | """
204214

205-
expected_summary_output = """3 undeclared component(s) were found.
215+
expected_summary_output = """5 undeclared component(s) were found.
206216
Add the following snippet into your `sbom.json` file
207217
```json
208218
[
209219
{
210-
"purl": "pkg:github/scanoss/scanner.c"
211-
},
212-
{
213-
"purl": "pkg:github/scanoss/wfp"
214-
}
220+
"purl": "pkg:github/scanoss/scanner.c"
221+
},
222+
{
223+
"purl": "pkg:github/scanoss/wfp"
224+
},
225+
{
226+
"purl": "pkg:npm/%40electron/rebuild"
227+
},
228+
{
229+
"purl": "pkg:npm/%40emotion/react"
230+
}
215231
]```
216232
"""
217233
self.assertEqual(status, 0)

0 commit comments

Comments
 (0)