@@ -33,9 +33,9 @@ def __init__(self, onlyUpdateProject: bool = False) -> None:
3333 self .onlyUpdateProject = onlyUpdateProject
3434 self .project_mainline_state : str = ""
3535
36- def bom_to_release_list (self , sbom : Bom ) -> List [str ]:
37- """Creates a list with linked releases"""
38- linkedReleases = []
36+ def bom_to_release_list (self , sbom : Bom ) -> Dict [str , Any ]:
37+ """Creates a list with linked releases from the SBOM. """
38+ linkedReleases : Dict [ str , Any ] = {}
3939
4040 for cx_comp in sbom .components :
4141 rid = CycloneDxSupport .get_property_value (cx_comp , CycloneDxSupport .CDX_PROP_SW360ID )
@@ -45,31 +45,39 @@ def bom_to_release_list(self, sbom: Bom) -> List[str]:
4545 + ", " + str (cx_comp .version ))
4646 continue
4747
48- linkedReleases .append (rid )
48+ linkedReleases [rid ] = {}
49+
50+ mainlineState = CycloneDxSupport .get_property_value (cx_comp , CycloneDxSupport .CDX_PROP_PROJ_STATE )
51+ if mainlineState :
52+ linkedReleases [rid ]["mainlineState" ] = mainlineState
53+ relation = CycloneDxSupport .get_property_value (cx_comp , CycloneDxSupport .CDX_PROP_PROJ_RELATION )
54+ if relation :
55+ # No typo. In project structure, it's "relation", while release update API uses "releaseRelation".
56+ linkedReleases [rid ]["releaseRelation" ] = relation
4957
5058 return linkedReleases
5159
52- def get_release_project_mainline_states (self , project : Optional [Dict [str , Any ]]) -> List [Dict [str , Any ]]:
53- pms : List [Dict [str , Any ]] = []
60+ def merge_project_mainline_states (self , data : Dict [str , Any ], project : Optional [Dict [str , Any ]]) -> None :
5461 if not project :
55- return pms
62+ return
5663
5764 if "linkedReleases" not in project :
58- return pms
65+ return
5966
6067 for release in project ["linkedReleases" ]: # NOT ["sw360:releases"]
6168 pms_release = release .get ("release" , "" )
6269 if not pms_release :
6370 continue
71+ pms_release = self .client .get_id_from_href (pms_release )
72+ if pms_release not in data :
73+ continue
6474 pms_state = release .get ("mainlineState" , "OPEN" )
6575 pms_relation = release .get ("relation" , "UNKNOWN" )
66- pms_entry : Dict [str , Any ] = {}
67- pms_entry ["release" ] = pms_release
68- pms_entry ["mainlineState" ] = pms_state
69- pms_entry ["new_relation" ] = pms_relation
70- pms .append (pms_entry )
7176
72- return pms
77+ if "mainlineState" not in data [pms_release ]:
78+ data [pms_release ]["mainlineState" ] = pms_state
79+ if "releaseRelation" not in data [pms_release ]:
80+ data [pms_release ]["releaseRelation" ] = pms_relation
7381
7482 def update_project (self , project_id : str , project : Optional [Dict [str , Any ]],
7583 sbom : Bom , project_info : Dict [str , Any ]) -> None :
@@ -79,7 +87,7 @@ def update_project(self, project_id: str, project: Optional[Dict[str, Any]],
7987 sys .exit (ResultCode .RESULT_ERROR_ACCESSING_SW360 )
8088
8189 data = self .bom_to_release_list (sbom )
82- pms = self .get_release_project_mainline_states ( project )
90+ self .merge_project_mainline_states ( data , project )
8391
8492 ignore_update_elements = ["name" , "version" ]
8593 # remove elements from list because they are handled separately
@@ -90,13 +98,17 @@ def update_project(self, project_id: str, project: Optional[Dict[str, Any]],
9098 try :
9199 print_text (" " + str (len (data )) + " releases in SBOM" )
92100
101+ update_mode = self .onlyUpdateProject
93102 if project and "_embedded" in project and "sw360:releases" in project ["_embedded" ]:
94103 print_text (
95104 " " + str (len (project ["_embedded" ]["sw360:releases" ])) +
96105 " releases in project before update" )
106+ else :
107+ # Workaround for SW360 API bug: add releases will hang forever for empty projects
108+ update_mode = False
97109
98110 # note: type in sw360python, 1.4.0 is wrong - we are using the correct one!
99- result = self .client .update_project_releases (data , project_id , add = self . onlyUpdateProject ) # type: ignore
111+ result = self .client .update_project_releases (data , project_id , add = update_mode ) # type: ignore
100112 if not result :
101113 print_red (" Error updating project releases!" )
102114 project = self .client .get_project (project_id )
@@ -114,20 +126,6 @@ def update_project(self, project_id: str, project: Optional[Dict[str, Any]],
114126 if not result2 :
115127 print_red (" Error updating project!" )
116128
117- if pms and project :
118- print_text (" Restoring original project mainline states..." )
119- for pms_entry in pms :
120- update_release = False
121- for r in project .get ("linkedReleases" , []):
122- if r ["release" ] == pms_entry ["release" ]:
123- update_release = True
124- break
125-
126- if update_release :
127- rid = self .client .get_id_from_href (pms_entry ["release" ])
128- self .client .update_project_release_relationship (
129- project_id , rid , pms_entry ["mainlineState" ], pms_entry ["new_relation" ], "" )
130-
131129 except SW360Error as swex :
132130 if swex .response is None :
133131 print_red (" Unknown error: " + swex .message )
0 commit comments