2222 Exports SonarQube platform configuration as JSON
2323"""
2424import sys
25- import os
25+ from typing import TextIO
2626from threading import Thread , Lock
2727from queue import Queue
2828
7878
7979
8080_EXPORT_CALLS = {
81+ "platform" : [__JSON_KEY_PLATFORM , platform .basics ],
8182 options .WHAT_SETTINGS : [__JSON_KEY_SETTINGS , platform .export ],
8283 options .WHAT_RULES : [__JSON_KEY_RULES , rules .export ],
8384 options .WHAT_PROFILES : [__JSON_KEY_PROFILES , qualityprofiles .export ],
@@ -135,36 +136,6 @@ def __write_export(config: dict[str, str], file: str, format: str) -> None:
135136 print (utilities .json_dump (config ), file = fd )
136137
137138
138- def __remove_chars_at_end (file : str , nb_bytes : int ) -> None :
139- """Writes the configuration in file"""
140- with open (file , mode = "rb+" ) as fd :
141- fd .seek (- nb_bytes , os .SEEK_END )
142- fd .truncate ()
143-
144-
145- def __add_project_header (file : str ) -> None :
146- """Writes the configuration in file"""
147- with open (file , mode = "a" , encoding = "utf-8" ) as fd :
148- print (',\n "projects": {\n ' , file = fd )
149-
150-
151- def __add_project_footer (file : str ) -> None :
152- """Closes projects section"""
153- __remove_chars_at_end (file , 2 )
154- with open (file , mode = "a" , encoding = "utf-8" ) as fd :
155- print ("\n }\n }" , file = fd )
156-
157-
158- def write_project (project_json : dict [str , any ], file : str ) -> None :
159- """
160- writes a project JSON in a file
161- """
162- key = project_json .pop ("key" )
163- with _WRITE_LOCK :
164- with utilities .open_file (file , mode = "a" ) as fd :
165- print (f'"{ key } ": { utilities .json_dump (project_json )} ,' , file = fd )
166-
167-
168139def __convert_for_yaml (json_export : dict [str , any ]) -> dict [str , any ]:
169140 """Converts the default JSON produced by export to a modified version more suitable for YAML"""
170141 if "globalSettings" in json_export :
@@ -203,7 +174,8 @@ def __export_config_sync(endpoint: platform.Platform, what: list[str], **kwargs)
203174 utilities .exit_fatal (f"Project key(s) '{ ',' .join (non_existing_projects )} ' do(es) not exist" , errcodes .NO_SUCH_KEY )
204175 log .info ("Exporting configuration synchronously from %s" , kwargs [options .URL ])
205176 key_list = kwargs [options .KEYS ]
206- sq_settings = {__JSON_KEY_PLATFORM : endpoint .basics ()}
177+ what .append ("platform" )
178+ sq_settings = {}
207179 for what_item , call_data in _EXPORT_CALLS .items ():
208180 if what_item not in what :
209181 continue
@@ -214,38 +186,45 @@ def __export_config_sync(endpoint: platform.Platform, what: list[str], **kwargs)
214186 log .warning (e .message )
215187 except exceptions .ObjectNotFound as e :
216188 log .error (e .message )
217- sq_settings = utilities .remove_empties (sq_settings )
218- if not kwargs ["dontInlineLists" ]:
219- sq_settings = utilities .inline_lists (sq_settings , exceptions = ("conditions" ,))
189+ sq_settings = __prep_json_for_write (sq_settings , export_settings )
220190 __write_export (sq_settings , kwargs [options .REPORT_FILE ], kwargs [options .FORMAT ])
221191 log .info ("Synchronous export of configuration from %s completed" , kwargs ["url" ])
222192
223193
224- def write_objects (queue : Queue , fd , object_type : str , export_settings : types .ConfigSettings ) -> None :
194+ def __prep_json_for_write (json_data : types .ObjectJsonRepr , export_settings : types .ConfigSettings ) -> types .ObjectJsonRepr :
195+ """Cleans up the JSON before writing"""
196+ json_data = utilities .sort_lists (json_data )
197+ if not export_settings .get ("FULL_EXPORT" , False ):
198+ json_data = utilities .remove_empties (utilities .remove_nones (json_data ))
199+ if export_settings .get ("INLINE_LISTS" , True ):
200+ json_data = utilities .inline_lists (json_data , exceptions = ("conditions" ,))
201+ return json_data
202+
203+
204+ def write_objects (queue : Queue [types .ObjectJsonRepr ], fd : TextIO , object_type : str , export_settings : types .ConfigSettings ) -> None :
225205 """
226206 Thread to write projects in the JSON file
227207 """
228- done = False
229208 prefix = ""
230209 log .info ("Waiting %s to write..." , object_type )
231210 print (f'"{ object_type } ": ' + "{" , file = fd )
232- while not done :
211+ while True :
233212 obj_json = queue .get ()
234- done = obj_json is None
235- if not done :
236- if export_settings .get ("INLINE_LISTS" , True ):
237- obj_json = utilities .inline_lists (obj_json , exceptions = ("conditions" ,))
238- if object_type in ("projects" , "applications" , "portfolios" , "users" ):
239- if object_type == "users" :
240- key = obj_json .pop ("login" , None )
241- else :
242- key = obj_json .pop ("key" , None )
243- log .debug ("Writing %s key '%s'" , object_type [:- 1 ], key )
244- print (f'{ prefix } "{ key } ": { utilities .json_dump (obj_json )} ' , end = "" , file = fd )
213+ if obj_json is None :
214+ queue .task_done ()
215+ break
216+ obj_json = __prep_json_for_write (obj_json , export_settings )
217+ if object_type in ("projects" , "applications" , "portfolios" , "users" ):
218+ if object_type == "users" :
219+ key = obj_json .pop ("login" , None )
245220 else :
246- log .debug ("Writing %s" , object_type )
247- print (f"{ prefix } { utilities .json_dump (obj_json )[2 :- 1 ]} " , end = "" , file = fd )
248- prefix = ",\n "
221+ key = obj_json .pop ("key" , None )
222+ log .debug ("Writing %s key '%s'" , object_type [:- 1 ], key )
223+ print (f'{ prefix } "{ key } ": { utilities .json_dump (obj_json )} ' , end = "" , file = fd )
224+ else :
225+ log .debug ("Writing %s" , object_type )
226+ print (f"{ prefix } { utilities .json_dump (obj_json )[2 :- 1 ]} " , end = "" , file = fd )
227+ prefix = ",\n "
249228 queue .task_done ()
250229 print ("\n }" , file = fd , end = "" )
251230 log .info ("Writing %s complete" , object_type )
@@ -256,10 +235,9 @@ def __export_config_async(endpoint: platform.Platform, what: list[str], **kwargs
256235 file = kwargs [options .REPORT_FILE ]
257236 export_settings = {
258237 "INLINE_LISTS" : not kwargs ["dontInlineLists" ],
259- "EXPORT_DEFAULTS" : True ,
260- # "FULL_EXPORT": kwargs["fullExport"],
261- "FULL_EXPORT" : False ,
262- "MODE" : "MIGRATION" ,
238+ "EXPORT_DEFAULTS" : kwargs ["exportDefaults" ],
239+ "FULL_EXPORT" : kwargs ["fullExport" ],
240+ "MODE" : "CONFIG" ,
263241 "THREADS" : kwargs [options .NBR_THREADS ],
264242 "SKIP_ISSUES" : True ,
265243 }
@@ -270,7 +248,7 @@ def __export_config_async(endpoint: platform.Platform, what: list[str], **kwargs
270248
271249 log .info ("Exporting configuration from %s" , kwargs [options .URL ])
272250 key_list = kwargs [options .KEYS ]
273- sq_settings = { __JSON_KEY_PLATFORM : endpoint . basics ()}
251+ what . append ( "platform" )
274252 is_first = True
275253 q = Queue (maxsize = 0 )
276254 with utilities .open_file (file , mode = "w" ) as fd :
@@ -287,12 +265,12 @@ def __export_config_async(endpoint: platform.Platform, what: list[str], **kwargs
287265 worker .daemon = True
288266 worker .name = f"Write{ ndx [:1 ].upper ()} { ndx [1 :10 ]} "
289267 worker .start ()
290- sq_settings [ ndx ] = func (endpoint , export_settings = export_settings , key_list = key_list , write_q = q )
268+ func (endpoint , export_settings = export_settings , key_list = key_list , write_q = q )
291269 q .join ()
292270 except exceptions .UnsupportedOperation as e :
293271 log .warning (e .message )
294- sq_settings = utilities .remove_empties (sq_settings )
295272 print ("\n }" , file = fd )
273+ utilities .normalize_json_file (file , remove_empty = True , remove_none = True )
296274 log .info ("Exporting migration data from %s completed" , kwargs ["url" ])
297275
298276
0 commit comments