Skip to content

Commit

Permalink
fix(project create): optimize release state handling on update
Browse files Browse the repository at this point in the history
Instead of storing all release states before project update and
restoring it in a big loop afterwards, SW360 REST API also allows to
pass full release information during release update.

We however don't keep the release states set in SW360, but use the
states provided in the SBOM.
  • Loading branch information
gernot-h committed Feb 5, 2025
1 parent adf95ce commit 6c3ac3d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 40 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
## UNRELEASED

* `project createbom` stores release relations (`CONTAINED`, `SIDE_BY_SIDE` etc.) as capycli:projectRelation
* fix slowdown/crash in `project update` for large projects (#121) introduced in 2.7.0

## 2.7.0

Expand Down
51 changes: 11 additions & 40 deletions capycli/project/create_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def __init__(self, onlyUpdateProject: bool = False) -> None:
self.project_mainline_state: str = ""

def bom_to_release_list(self, sbom: Bom) -> List[str]:
"""Creates a list with linked releases"""
linkedReleases = []
"""Creates a list with linked releases from the SBOM."""
linkedReleases = {}

for cx_comp in sbom.components:
rid = CycloneDxSupport.get_property_value(cx_comp, CycloneDxSupport.CDX_PROP_SW360ID)
Expand All @@ -45,31 +45,17 @@ def bom_to_release_list(self, sbom: Bom) -> List[str]:
+ ", " + str(cx_comp.version))
continue

linkedReleases.append(rid)
linkedReleases[rid] = {}

return linkedReleases

def get_release_project_mainline_states(self, project: Optional[Dict[str, Any]]) -> List[Dict[str, Any]]:
pms: List[Dict[str, Any]] = []
if not project:
return pms
mainlineState = CycloneDxSupport.get_property_value(cx_comp, CycloneDxSupport.CDX_PROP_PROJ_STATE)
if mainlineState:
linkedReleases[rid]["mainlineState"] = mainlineState
relation = CycloneDxSupport.get_property_value(cx_comp, CycloneDxSupport.CDX_PROP_PROJ_RELATION)
if relation:
# No typo. In project structure, it's "relation", while release update API uses "releaseRelation".
linkedReleases[rid]["releaseRelation"] = relation

if "linkedReleases" not in project:
return pms

for release in project["linkedReleases"]: # NOT ["sw360:releases"]
pms_release = release.get("release", "")
if not pms_release:
continue
pms_state = release.get("mainlineState", "OPEN")
pms_relation = release.get("relation", "UNKNOWN")
pms_entry: Dict[str, Any] = {}
pms_entry["release"] = pms_release
pms_entry["mainlineState"] = pms_state
pms_entry["new_relation"] = pms_relation
pms.append(pms_entry)

return pms
return linkedReleases

def update_project(self, project_id: str, project: Optional[Dict[str, Any]],
sbom: Bom, project_info: Dict[str, Any]) -> None:
Expand All @@ -79,7 +65,6 @@ def update_project(self, project_id: str, project: Optional[Dict[str, Any]],
sys.exit(ResultCode.RESULT_ERROR_ACCESSING_SW360)

data = self.bom_to_release_list(sbom)
pms = self.get_release_project_mainline_states(project)

ignore_update_elements = ["name", "version"]
# remove elements from list because they are handled separately
Expand Down Expand Up @@ -114,20 +99,6 @@ def update_project(self, project_id: str, project: Optional[Dict[str, Any]],
if not result2:
print_red(" Error updating project!")

if pms and project:
print_text(" Restoring original project mainline states...")
for pms_entry in pms:
update_release = False
for r in project.get("linkedReleases", []):
if r["release"] == pms_entry["release"]:
update_release = True
break

if update_release:
rid = self.client.get_id_from_href(pms_entry["release"])
self.client.update_project_release_relationship(
project_id, rid, pms_entry["mainlineState"], pms_entry["new_relation"], "")

except SW360Error as swex:
if swex.response is None:
print_red(" Unknown error: " + swex.message)
Expand Down

0 comments on commit 6c3ac3d

Please sign in to comment.