Skip to content

Commit

Permalink
fix(project CreateBom): decode multiple purls and warn user
Browse files Browse the repository at this point in the history
Fix #36
  • Loading branch information
gernot-h committed Aug 21, 2023
1 parent d9b4a84 commit 8cecd12
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
5 changes: 3 additions & 2 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
* Be more resilient about missing metadata in CycloneDX SBOMs.
* The `-o` parameter of the command `project GetLicenseInfo` is now optional.
But you still need this output when you want to create a Readme.
* `project createbom` add purl, source and repository url from SW360 if available
* `project createbom` add purls, source and repository url from SW360 if available.
If multiple purls are found, a warning is printed asking user to manually edit SBOM.
* `project createbom` add SW360 source and binary attachments as external reference to SBOM.
* `project createbom` adds SW360 project name, version and description to SBOM.

Expand All @@ -27,7 +28,7 @@
* `bom map` will report matches by name, but different version **only** if `-all` has been specified.
The original idea of CaPyCLI was to report as many potential matches as possible and to let the user
decide which match to take by editing the SBOM. But it seems that many users did not read the documentation
and the expectations were different. Therefore the default behavior has been changed.
and the expectations were different. Therefore the default behavior has been changed.
The original behavior of versions prior to 2.x can be enabled via the `-all` switch.

## 2.0.0.dev (2023-05-19)
Expand Down
7 changes: 7 additions & 0 deletions capycli/project/create_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import capycli.common.script_base
from capycli import get_logger
from capycli.common.capycli_bom_support import CaPyCliBom, CycloneDxSupport, SbomCreator
from capycli.common.purl_utils import PurlUtils
from capycli.common.print import print_red, print_text, print_yellow
from capycli.main.result_codes import ResultCode

Expand Down Expand Up @@ -59,6 +60,12 @@ def create_project_bom(self, project) -> list:
# try another id name
purl = self.get_external_id("purl", release_details)

purl = PurlUtils.parse_purls_from_external_id(purl)
if len(purl) > 1:
print_yellow(" Multiple purls added for", release["name"], release["version"])
print_yellow(" You must remove all but one in your SBOM!")
purl = " ".join(purl)

if purl:
rel_item = Component(name=release["name"], version=release["version"], purl=purl, bom_ref=purl)
else:
Expand Down
38 changes: 38 additions & 0 deletions tests/test_create_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,44 @@ def test_project_not_found(self) -> None:
except SystemExit as ex:
self.assertEqual(ResultCode.RESULT_ERROR_ACCESSING_SW360, ex.code)

@responses.activate
def test_create_bom_multiple_purls(self):
sut = CreateBom()

self.add_login_response()
sut.login(token=TestBase.MYTOKEN, url=TestBase.MYURL)

# the first release
responses.add(
responses.GET,
url=self.MYURL + "resource/api/releases/r001",
json=self.get_release_wheel_for_test(),
status=200,
content_type="application/json",
adding_headers={"Authorization": "Token " + self.MYTOKEN},
)

# the second release
release = self.get_release_cli_for_test()
# use a specific purl
release["externalIds"]["package-url"] = "[\"pkg:deb/debian/cli-support@1.3-1\",\"pkg:pypi/cli-support@1.3\"]"
responses.add(
responses.GET,
url=self.MYURL + "resource/api/releases/r002",
json=release,
status=200,
content_type="application/json",
adding_headers={"Authorization": "Token " + self.MYTOKEN},
)

out = self.capture_stdout(sut.create_project_bom, self.get_project_for_test())
self.assertIn("Multiple purls added", out)

# TODO self.capture_stdout doesn't allow us to get return value,
# so re-run test. See also https://github.com/sw360/capycli/issues/39
cdx_components = sut.create_project_bom(self.get_project_for_test())
self.assertEqual(cdx_components[0].purl, "pkg:deb/debian/cli-support@1.3-1 pkg:pypi/cli-support@1.3")

@responses.activate
def test_project_by_id(self):
sut = CreateBom()
Expand Down

0 comments on commit 8cecd12

Please sign in to comment.