@@ -132,6 +132,7 @@ class Setting(sqobject.SqObject):
132132 c .LIST : "settings/list_definitions" ,
133133 "NEW_CODE_GET" : "new_code_periods/show" ,
134134 "NEW_CODE_SET" : "new_code_periods/set" ,
135+ "MQR_MODE" : "v2/clean-code-policy/mode" ,
135136 }
136137
137138 def __init__ (self , endpoint : pf .Platform , key : str , component : object = None , data : types .ApiPayload = None ) -> None :
@@ -154,19 +155,7 @@ def read(cls, key: str, endpoint: pf.Platform, component: object = None) -> Sett
154155 o = Setting .CACHE .get (key , component , endpoint .local_url )
155156 if o :
156157 return o
157- if key == NEW_CODE_PERIOD and not endpoint .is_sonarcloud ():
158- params = get_component_params (component , name = "project" )
159- data = json .loads (endpoint .get (Setting .API ["NEW_CODE_GET" ], params = params ).text )
160- else :
161- if key == NEW_CODE_PERIOD :
162- key = "sonar.leak.period.type"
163- params = get_component_params (component )
164- params .update ({"keys" : key })
165- data = json .loads (endpoint .get (Setting .API [c .GET ], params = params , with_organization = (component is None )).text )["settings" ]
166- if not endpoint .is_sonarcloud () and len (data ) > 0 :
167- data = data [0 ]
168- else :
169- data = {"inherited" : True }
158+ data = get_settings_data (endpoint , key , component )
170159 return Setting .load (key = key , endpoint = endpoint , data = data , component = component )
171160
172161 @classmethod
@@ -214,6 +203,8 @@ def reload(self, data: types.ApiPayload) -> None:
214203 self .multi_valued = data .get ("multiValues" , False )
215204 if self .key == NEW_CODE_PERIOD :
216205 self .value = new_code_to_string (data )
206+ elif self .key == MQR_ENABLED :
207+ self .value = data .get ("mode" , "MQR" ) != "STANDARD_EXPERIENCE"
217208 elif self .key == COMPONENT_VISIBILITY :
218209 self .value = data .get ("visibility" , None )
219210 elif self .key == "sonar.login.message" :
@@ -226,6 +217,9 @@ def reload(self, data: types.ApiPayload) -> None:
226217 self .value = util .DEFAULT
227218 self .__reload_inheritance (data )
228219
220+ def refresh (self ) -> None :
221+ self .reload (get_settings_data (self .endpoint , self .key , self .component ))
222+
229223 def __hash__ (self ) -> int :
230224 """Returns object unique ID"""
231225 return hash ((self .key , self .component .key if self .component else None , self .base_url ()))
@@ -241,10 +235,17 @@ def set(self, value: any) -> bool:
241235 log .debug ("%s set to '%s'" , str (self ), str (value ))
242236 if not self .is_settable ():
243237 log .error ("Setting '%s' does not seem to be a settable setting, trying to set anyway..." , str (self ))
244- if value is None or value == "" or (self .key == "sonar.autodetect.ai.code" and value is True ):
245- return self .endpoint .reset_setting (self .key )
238+ return False
239+ if value is None or value == "" or (self .key == "sonar.autodetect.ai.code" and value is True and self .endpoint .version () < (2025 , 2 , 0 )):
240+ return self .reset ()
241+ if self .key == MQR_ENABLED :
242+ if ok := self .patch (Setting .API ["MQR_MODE" ], params = {"mode" : "STANDARD_EXPERIENCE" if not value else "MQR" }).ok :
243+ self .value = value
244+ return ok
246245 if self .key in (COMPONENT_VISIBILITY , PROJECT_DEFAULT_VISIBILITY ):
247- return set_visibility (endpoint = self .endpoint , component = self .component , visibility = value )
246+ if ok := set_visibility (endpoint = self .endpoint , component = self .component , visibility = value ):
247+ self .value = value
248+ return ok
248249
249250 # Hack: Up to 9.4 cobol settings are comma separated mono-valued, in 9.5+ they are multi-valued
250251 if self .endpoint .version () > (9 , 4 , 0 ) or not self .key .startswith ("sonar.cobol" ):
@@ -256,34 +257,21 @@ def set(self, value: any) -> bool:
256257 return False
257258
258259 log .debug ("Setting %s to value '%s'" , str (self ), str (value ))
259- params = {"key" : self .key , "component" : self .component .key if self .component else None }
260- untransformed_value = value
261- if isinstance (value , list ):
262- if isinstance (value [0 ], str ):
263- params ["values" ] = value
264- else :
265- params ["fieldValues" ] = [json .dumps (v ) for v in value ]
266- elif isinstance (value , bool ):
267- params ["value" ] = str (value ).lower ()
268- else :
269- pname = "values" if self .multi_valued else "value"
270- params [pname ] = value
260+ params = {"key" : self .key , "component" : self .component .key if self .component else None } | encode (self , value )
271261 try :
272- r = self .post (Setting .API [c .CREATE ], params = params )
273- self .value = untransformed_value
274- return r . ok
262+ if ok : = self .post (Setting .API [c .CREATE ], params = params ). ok :
263+ self .value = value
264+ return ok
275265 except (ConnectionError , RequestException ) as e :
276266 util .handle_error (e , f"setting setting '{ self .key } ' of { str (self .component )} " , catch_all = True )
277267 return False
278268
279269 def reset (self ) -> bool :
280270 log .info ("Resetting %s" , str (self ))
281- params = {"keys" : self .key }
282- if self .component :
283- params ["component" ] = self .component .key
271+ params = {"keys" : self .key } | {} if not self .component else {"component" : self .component .key }
284272 try :
285273 r = self .post ("settings/reset" , params = params )
286- self .value = None
274+ self .refresh ()
287275 return r .ok
288276 except (ConnectionError , RequestException ) as e :
289277 util .handle_error (e , f"resetting setting '{ self .key } ' of { str (self .component )} " , catch_all = True )
@@ -443,7 +431,7 @@ def get_bulk(
443431 o = get_new_code_period (endpoint , component )
444432 settings_dict [o .key ] = o
445433 VALID_SETTINGS .update (set (settings_dict .keys ()))
446- VALID_SETTINGS .update ({"sonar.scm.provider" })
434+ VALID_SETTINGS .update ({"sonar.scm.provider" , MQR_ENABLED })
447435 return settings_dict
448436
449437
@@ -562,6 +550,17 @@ def decode(setting_key: str, setting_value: any) -> any:
562550 return setting_value
563551
564552
553+ def encode (setting : Setting , setting_value : any ) -> dict [str , str ]:
554+ """Encodes the params to pass to api/settings/set according to setting value type"""
555+ if isinstance (setting_value , list ):
556+ params = {"values" : setting_value } if isinstance (setting_value [0 ], str ) else {"fieldValues" : [json .dumps (v ) for v in setting_value ]}
557+ elif isinstance (setting_value , bool ):
558+ params = {"value" : str (setting_value ).lower ()}
559+ else :
560+ params = {"values" if setting .multi_valued else "value" : setting_value }
561+ return params
562+
563+
565564def reset_setting (endpoint : pf .Platform , setting_key : str , project : Optional [object ] = None ) -> bool :
566565 """Resets a setting to its default"""
567566 return get_object (endpoint = endpoint , key = setting_key , component = project ).reset ()
@@ -575,3 +574,25 @@ def get_component_params(component: object, name: str = "component") -> types.Ap
575574 return {name : component .project .key , "branch" : component .key }
576575 else :
577576 return {name : component .key }
577+
578+
579+ def get_settings_data (endpoint : pf .Platform , key : str , component : Optional [object ]) -> types .ApiPayload :
580+ """Reads a setting data with different API depending on setting key
581+ :return: The returned API data"""
582+
583+ if key == NEW_CODE_PERIOD and not endpoint .is_sonarcloud ():
584+ params = get_component_params (component , name = "project" )
585+ data = json .loads (endpoint .get (Setting .API ["NEW_CODE_GET" ], params = params ).text )
586+ elif key == MQR_ENABLED :
587+ data = json .loads (endpoint .get (Setting .API ["MQR_MODE" ]).text )
588+ else :
589+ if key == NEW_CODE_PERIOD :
590+ key = "sonar.leak.period.type"
591+ params = get_component_params (component )
592+ params .update ({"keys" : key })
593+ data = json .loads (endpoint .get (Setting .API [c .GET ], params = params , with_organization = (component is None )).text )["settings" ]
594+ if not endpoint .is_sonarcloud () and len (data ) > 0 :
595+ data = data [0 ]
596+ else :
597+ data = {"inherited" : True }
598+ return data
0 commit comments