2323
2424"""
2525from __future__ import annotations
26+ import math
2627import json
2728
2829from datetime import datetime
@@ -104,9 +105,9 @@ def get_subcomponents(self, strategy: str = "children", with_issues: bool = Fals
104105 "metricKeys" : "bugs,vulnerabilities,code_smells,security_hotspots" ,
105106 }
106107 data = json .loads (self .get ("measures/component_tree" , params = parms ).text )
107- nb_comp = data [ "paging" ][ "total" ]
108+ nb_comp = utilities . nbr_total_elements ( data )
108109 log .debug ("Found %d subcomponents to %s" , nb_comp , str (self ))
109- nb_pages = (nb_comp + 500 - 1 ) // 500
110+ nb_pages = math . ceil (nb_comp / 500 )
110111 comp_list = {}
111112 parms ["ps" ] = 500
112113 for page in range (nb_pages ):
@@ -126,29 +127,35 @@ def get_subcomponents(self, strategy: str = "children", with_issues: bool = Fals
126127
127128 def get_issues (self , filters : types .ApiParams = None ) -> dict [str , object ]:
128129 """Returns list of issues for a component, optionally on branches or/and PRs"""
129- from sonar .issues import component_filter , search_all
130+ from sonar .issues import search_all
130131
131132 log .info ("Searching issues for %s with filters %s" , str (self ), str (filters ))
132- params = utilities . replace_keys ( _ALT_COMPONENTS , component_filter ( self .endpoint ), self . search_params () )
133+ params = self .search_params ()
133134 if filters is not None :
134135 params .update (filters )
135136 params ["additionalFields" ] = "comments"
136137 issue_list = search_all (endpoint = self .endpoint , params = params )
137138 self .nbr_issues = len (issue_list )
138139 return issue_list
139140
140- def count_third_party_issues (self , filters : types .ApiParams = None ) -> dict [str , int ]:
141- """Returns list of issues for a component, optionally on branches or/and PRs """
142- from sonar .issues import component_filter , count_by_rule
141+ def count_specific_rules_issues (self , ruleset : list [ str ] , filters : types .ApiParams = None ) -> dict [str , int ]:
142+ """Returns the count of issues of a component for a given ruleset """
143+ from sonar .issues import count_by_rule
143144
144- third_party_rules = rules .third_party (self .endpoint )
145- params = utilities .replace_keys (_ALT_COMPONENTS , component_filter (self .endpoint ), self .search_params ())
145+ params = self .search_params ()
146146 if filters is not None :
147147 params .update (filters )
148148 params ["facets" ] = "rules"
149- params ["rules" ] = [r .key for r in third_party_rules ]
150- issues_count = {k : v for k , v in count_by_rule (endpoint = self .endpoint , ** params ).items () if v > 0 }
151- return issues_count
149+ params ["rules" ] = [r .key for r in ruleset ]
150+ return {k : v for k , v in count_by_rule (endpoint = self .endpoint , ** params ).items () if v > 0 }
151+
152+ def count_third_party_issues (self , filters : types .ApiParams = None ) -> dict [str , int ]:
153+ """Returns the count of issues of a component corresponding to 3rd party rules"""
154+ return self .count_specific_rules_issues (ruleset = rules .third_party (self .endpoint ), filters = filters )
155+
156+ def count_instantiated_rules_issues (self , filters : types .ApiParams = None ) -> dict [str , int ]:
157+ """Returns the count of issues of a component corresponding to instantiated rules"""
158+ return self .count_specific_rules_issues (ruleset = rules .instantiated (self .endpoint ), filters = filters )
152159
153160 def get_hotspots (self , filters : types .ApiParams = None ) -> dict [str , object ]:
154161 """Returns list of hotspots for a component, optionally on branches or/and PRs"""
@@ -160,6 +167,35 @@ def get_hotspots(self, filters: types.ApiParams = None) -> dict[str, object]:
160167 params .update (filters )
161168 return search (endpoint = self .endpoint , filters = params )
162169
170+ def migration_export (self ) -> dict [str , any ]:
171+ from sonar .issues import count as issue_count
172+ from sonar .hotspots import count as hotspot_count
173+
174+ json_data = {"lastAnalysis" : utilities .date_to_string (self .last_analysis ())}
175+ lang_distrib = self .get_measure ("ncloc_language_distribution" )
176+ loc_distrib = {}
177+ if lang_distrib :
178+ loc_distrib = {m .split ("=" )[0 ]: int (m .split ("=" )[1 ]) for m in lang_distrib .split (";" )}
179+ loc_distrib ["total" ] = self .loc ()
180+ json_data ["ncloc" ] = loc_distrib
181+ tpissues = self .count_third_party_issues ()
182+ inst_issues = self .count_instantiated_rules_issues ()
183+ params = self .search_params ()
184+ json_data ["issues" ] = {
185+ "thirdParty" : tpissues if len (tpissues ) > 0 else 0 ,
186+ "instantiatedRules" : inst_issues if len (inst_issues ) > 0 else 0 ,
187+ "falsePositives" : issue_count (self .endpoint , issueStatuses = ["FALSE_POSITIVE" ], ** params ),
188+ }
189+ status = "accepted" if self .endpoint .version () >= (10 , 2 , 0 ) else "wontFix"
190+ json_data ["issues" ][status ] = issue_count (self .endpoint , issueStatuses = [status .upper ()], ** params )
191+ json_data ["hotspots" ] = {
192+ "acknowledged" : hotspot_count (self .endpoint , resolution = ["ACKNOWLEDGED" ], ** params ),
193+ "safe" : hotspot_count (self .endpoint , resolution = ["SAFE" ], ** params ),
194+ "fixed" : hotspot_count (self .endpoint , resolution = ["FIXED" ], ** params ),
195+ }
196+ log .debug ("%s has these notable issues %s" , str (self ), str (json_data ["issues" ]))
197+ return json_data
198+
163199 def get_measures (self , metrics_list : types .KeyList ) -> dict [str , any ]:
164200 """Retrieves a project list of measures
165201
0 commit comments