Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
* `getdependencies javascript` has an improved source code detection.
* Improve filtering in `bom filter`.
* Update to Poetry 2.1.4 including an update of `pyproject.toml`.
* Replace tomli by tomllib and drop support for Python <3.11.
* Replace tomli by tomllib and drop support for Python <=3.10.
* Support platform dependent binaries using PyInstaller.
* Dependency updates.
* `project prerequisites` now has a summary at the end of the output to show how many
components have been scanned and how many warnings and errors there are.

## 2.9.1

Expand Down
33 changes: 25 additions & 8 deletions capycli/project/check_prerequisites.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -------------------------------------------------------------------------------
# Copyright (c) 2019-24 Siemens
# Copyright (c) 2019-2025 Siemens
# All Rights Reserved.
# Author: [email protected]
#
Expand Down Expand Up @@ -113,33 +113,36 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
print_red("Error retrieving project details")
sys.exit(ResultCode.RESULT_ERROR_ACCESSING_SW360)

has_errors = False
count_errors = 0
count_warnings = 0
print_text(" Project name: " + project["name"] + ", " + project["version"])
print_text(" Clearing state: " + project.get("clearingState", "UNKNOWN"))

if not project.get("projectOwner", None):
print_yellow(" No project owner specified!")
has_errors = True
count_warnings += 1
else:
print_green(" Project owner: " + project.get("projectOwner", "UNKNOWN"))

if not project.get("projectResponsible", None):
print_yellow(" No project responsible specified!")
has_errors = True
count_warnings += 1
else:
print_green(
" Project responsible: "
+ project["projectResponsible"])

if len(project.get("securityResponsibles", [])) < 1:
print_yellow(" No security responsibles specified!")
count_warnings += 1
else:
print_green(
" Security responsible(s): "
+ self.list_to_string(project["securityResponsibles"]))

if not project.get("tag", None):
print_yellow(" No tag specified!")
count_warnings += 1
else:
print_green(" Tag: " + project.get("tag", "UNKNOWN"))

Expand All @@ -160,7 +163,7 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
release = self.client.get_release_by_url(href)
if not release:
print_red("Error accessign release " + href)
has_errors = True
count_errors += 1
continue

state = self.get_clearing_state(project, href)
Expand All @@ -169,13 +172,15 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:

if not release.get("sourceCodeDownloadurl", ""):
print_yellow(" No download URL specified!")
count_warnings += 1
else:
print_green(
" Download URL: " +
release["sourceCodeDownloadurl"])

if len(release.get("languages", [])) < 1:
print_yellow(" No programming language specified!")
count_warnings += 1
else:
print_green(
" Programming language: " +
Expand All @@ -189,7 +194,7 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
cx_comp, CycloneDxSupport.CDX_PROP_SW360ID) == release_id]
if len(bom_item) == 0:
print_red(" Item not in specified SBOM!")
has_errors = True
count_errors += 1
else:
assert len(bom_item) == 1
bom_sha1 = CycloneDxSupport.get_source_file_hash(bom_item[0])
Expand All @@ -202,12 +207,14 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
" Source " +
source_name +
" seems to be from Maven!")
count_warnings += 1
if bom_sha1:
if bom_sha1 != source_info.get("sha1", ""):
print_red(
" SHA1 for source " +
source_name +
" does not match!")
count_errors += 1
self.check_checkStatus(source_info)
else:
print_green(
Expand All @@ -218,9 +225,10 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
if len(source) != 1:
if state == "OPEN":
print(Fore.LIGHTRED_EX, end="")
has_errors = True
count_errors += 1
else:
print(Fore.LIGHTYELLOW_EX, end="")
count_warnings += 1
else:
print(Fore.LIGHTGREEN_EX, end="")
print(" ", len(source), "source file(s) available." + Fore.RESET)
Expand All @@ -229,6 +237,7 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
if (not ids) or (not ids):
print_yellow(
" No component management id (package-url, etc.) specified!")
count_warnings += 1
else:
print_green(" component management id: " + str(ids))

Expand All @@ -249,14 +258,22 @@ def check_project_prerequisites(self, id: str, sbom: Optional[Bom]) -> bool:
print_red(
" SBOM Item not in SW360 project: "
+ cx_comp.name + " " + cx_comp.version)
count_errors += 1
print_text(" Check finished.")
else:
print_yellow(" No SBOM specified, skipping release comparison!")

else:
print_text(" No linked releases")

return has_errors
print_text("\nSummary:")
print_text(" Total components: " + str(len(releases)))
if count_warnings > 0:
print_yellow(" Warnings: " + str(count_warnings))
if count_errors > 0:
print_red(" Errors: " + str(count_errors))

return count_errors > 0

def run(self, args: Any) -> None:
"""Main method()"""
Expand Down