Skip to content

Commit 5699bb4

Browse files
committed
feat(project CreateBom): ignore rejected attachments
This unfortunately requires retrieving attachment info for each attachment.
1 parent 297d2a1 commit 5699bb4

File tree

3 files changed

+103
-33
lines changed

3 files changed

+103
-33
lines changed

ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
## NEXT
99

10+
* `project createbom` will not add rejected attachments to SBOM
1011
* `project createbom` adds CLI and report information to SBOM
1112
* new command `bom downloadattachments` to download CLI and report attachments
1213
* `bom map`: The options `--dbx` and `-all` were replaced by `--matchmode`.

capycli/project/create_bom.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,16 @@ def create_project_bom(self, project: Dict[str, Any], create_controlfile: bool)
107107
if at_type not in CaPyCliBom.FILE_COMMENTS:
108108
continue
109109
comment = CaPyCliBom.FILE_COMMENTS[at_type]
110+
at_data = self.client.get_attachment_by_url(attachment["_links"]["self"]["href"])
111+
if at_data.get("checkStatus") == "REJECTED":
112+
print_yellow(" WARNING: ignoring REJECTED attachment",
113+
attachment["filename"])
114+
continue
110115
if at_type in ("SOURCE", "SOURCE_SELF", "BINARY", "BINARY_SELF"):
111116
ext_ref_type = ExternalReferenceType.DISTRIBUTION
112117
else:
113118
ext_ref_type = ExternalReferenceType.OTHER
114119
if create_controlfile:
115-
at_data = self.client.get_attachment_by_url(attachment["_links"]["self"]["href"])
116-
117120
at_details = {
118121
"ComponentName": " ".join((release["name"], release["version"])),
119122
"Sw360Id": sw360_id,

tests/test_create_bom.py

Lines changed: 97 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def test_create_bom_multiple_purls(self, capsys: Any) -> None:
150150
content_type="application/json",
151151
adding_headers={"Authorization": "Token " + self.MYTOKEN},
152152
)
153-
153+
self.add_project_attachment_responses()
154154
cdx_components, _ = sut.create_project_bom(self.get_project_for_test(),
155155
create_controlfile=False)
156156
captured = capsys.readouterr()
@@ -217,6 +217,86 @@ def add_project_releases_responses(self):
217217
)
218218
return release
219219

220+
def add_project_attachment_responses(self):
221+
responses.add(
222+
method=responses.GET,
223+
url=self.MYURL + "resource/api/attachments/r001a002",
224+
body="""
225+
{
226+
"filename": "wheel-0.38.4.zip",
227+
"attachmentType": "SOURCE"
228+
}""",
229+
status=200,
230+
content_type="application/json",
231+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
232+
)
233+
responses.add(
234+
method=responses.GET,
235+
url=self.MYURL + "resource/api/attachments/r001a001",
236+
body="""
237+
{
238+
"filename": "CLIXML_wheel-0.38.4.xml",
239+
"sha1": "ccd9f1ed2f59c46ff3f0139c05bfd76f83fd9851",
240+
"attachmentType": "COMPONENT_LICENSE_INFO_XML"
241+
}""",
242+
status=200,
243+
content_type="application/json",
244+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
245+
)
246+
247+
responses.add(
248+
method=responses.GET,
249+
url=self.MYURL + "resource/api/attachments/r002a001",
250+
body="""
251+
{
252+
"filename": "clipython-1.3.0.zip",
253+
"attachmentType": "SOURCE"
254+
}""",
255+
status=200,
256+
content_type="application/json",
257+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
258+
)
259+
responses.add(
260+
method=responses.GET,
261+
url=self.MYURL + "resource/api/attachments/r002a002",
262+
body="""
263+
{
264+
"filename": "CLIXML_clipython-1.3.0.xml",
265+
"sha1": "dd4c38387c6811dba67d837af7742d84e61e20de",
266+
"attachmentType": "COMPONENT_LICENSE_INFO_XML",
267+
"checkedBy": "[email protected]",
268+
"checkStatus": "ACCEPTED",
269+
"createdBy": "[email protected]"
270+
}""",
271+
status=200,
272+
content_type="application/json",
273+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
274+
)
275+
responses.add(
276+
method=responses.GET,
277+
url=self.MYURL + "resource/api/attachments/r002a003",
278+
body="""
279+
{
280+
"filename": "clipython-repacked-for-fun.zip",
281+
"attachmentType": "SOURCE_SELF"
282+
}""",
283+
status=200,
284+
content_type="application/json",
285+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
286+
)
287+
responses.add(
288+
method=responses.GET,
289+
url=self.MYURL + "resource/api/attachments/r002a004",
290+
body="""
291+
{
292+
"filename": "clipython-1.3.0.docx",
293+
"attachmentType": "CLEARING_REPORT"
294+
}""",
295+
status=200,
296+
content_type="application/json",
297+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
298+
)
299+
220300
@responses.activate
221301
def test_project_by_id(self) -> None:
222302
sut = CreateBom()
@@ -225,6 +305,7 @@ def test_project_by_id(self) -> None:
225305
sut.login(token=TestBasePytest.MYTOKEN, url=TestBasePytest.MYURL)
226306

227307
release = self.add_project_releases_responses()
308+
self.add_project_attachment_responses()
228309
project = self.get_project_for_test()
229310

230311
cdx_bom, _ = sut.create_project_cdx_bom("p001", create_controlfile=False)
@@ -288,37 +369,8 @@ def test_project_by_id_controlfile(self):
288369
sut.login(token=TestBasePytest.MYTOKEN, url=TestBasePytest.MYURL)
289370

290371
self.add_project_releases_responses()
372+
self.add_project_attachment_responses()
291373

292-
# attachment info
293-
responses.add(
294-
method=responses.GET,
295-
url=self.MYURL + "resource/api/attachments/r001a001",
296-
body="""
297-
{
298-
"filename": "CLIXML_wheel-0.38.4.xml",
299-
"sha1": "ccd9f1ed2f59c46ff3f0139c05bfd76f83fd9851",
300-
"attachmentType": "COMPONENT_LICENSE_INFO_XML"
301-
}""",
302-
status=200,
303-
content_type="application/json",
304-
adding_headers={"Authorization": "Token " + self.MYTOKEN},
305-
)
306-
responses.add(
307-
method=responses.GET,
308-
url=self.MYURL + "resource/api/attachments/r002a002",
309-
body="""
310-
{
311-
"filename": "CLIXML_clipython-1.3.0.xml",
312-
"sha1": "dd4c38387c6811dba67d837af7742d84e61e20de",
313-
"attachmentType": "COMPONENT_LICENSE_INFO_XML",
314-
"checkedBy": "[email protected]",
315-
"checkStatus": "ACCEPTED",
316-
"createdBy": "[email protected]"
317-
}""",
318-
status=200,
319-
content_type="application/json",
320-
adding_headers={"Authorization": "Token " + self.MYTOKEN},
321-
)
322374
responses.add(
323375
method=responses.GET,
324376
url=self.MYURL + "resource/api/attachments/r002a004",
@@ -428,6 +480,7 @@ def test_project_show_by_name(self) -> None:
428480
content_type="application/json",
429481
adding_headers={"Authorization": "Token " + self.MYTOKEN},
430482
)
483+
self.add_project_attachment_responses()
431484

432485
self.delete_file(self.OUTPUTFILE)
433486
out = self.capture_stdout(sut.run, args)
@@ -467,6 +520,7 @@ def test_create_project_bom_release_error(self):
467520
content_type="application/json",
468521
adding_headers={"Authorization": "Token " + self.MYTOKEN},
469522
)
523+
self.add_project_attachment_responses()
470524
with pytest.raises(SystemExit):
471525
bom, _ = sut.create_project_bom(self.get_project_for_test(), create_controlfile=False)
472526

@@ -493,6 +547,18 @@ def test_create_project_bom_controlfile_attachment_error(self):
493547
content_type="application/json",
494548
adding_headers={"Authorization": "Token " + self.MYTOKEN},
495549
)
550+
responses.add(
551+
method=responses.GET,
552+
url=self.MYURL + "resource/api/attachments/r002a001",
553+
body="""
554+
{
555+
"filename": "clipython-1.3.0.zip",
556+
"attachmentType": "COMPONENT_LICENSE_INFO_XML"
557+
}""",
558+
status=200,
559+
content_type="application/json",
560+
adding_headers={"Authorization": "Token " + self.MYTOKEN},
561+
)
496562
responses.add(
497563
method=responses.GET,
498564
url=self.MYURL + "resource/api/attachments/r002a002",

0 commit comments

Comments
 (0)