From ad2fe8f3ec86697dbd7445f7dde00ec75124ba42 Mon Sep 17 00:00:00 2001 From: Olivier Korach Date: Sun, 2 Nov 2025 21:24:00 +0100 Subject: [PATCH] Export users as list --- cli/config.py | 32 +++++++++++++++++++++++--------- sonar/users.py | 11 +++++------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/cli/config.py b/cli/config.py index 3bf5ea3b..12b15dbb 100644 --- a/cli/config.py +++ b/cli/config.py @@ -124,11 +124,15 @@ def __parse_args(desc: str) -> object: def __normalize_json(json_data: dict[str, any], remove_empty: bool = True, remove_none: bool = True) -> dict[str, any]: """Sorts a JSON file and optionally remove empty and none values""" + SORT_FIELDS = {"users": "login"} log.info("Normalizing JSON - remove empty = %s, remove nones = %s", str(remove_empty), str(remove_none)) json_data = utilities.clean_data(json_data, remove_none=remove_none, remove_empty=remove_empty) json_data = utilities.order_keys(json_data, *_SECTIONS_ORDER) for key in [k for k in _SECTIONS_TO_SORT if k in json_data]: - json_data[key] = {k: json_data[key][k] for k in sorted(json_data[key])} + if isinstance(json_data[key], dict): + json_data[key] = {k: json_data[key][k] for k in sorted(json_data[key])} + else: + json_data[key] = utilities.sort_list_by_key(json_data[key], SORT_FIELDS.get(key, "key")) return json_data @@ -169,7 +173,16 @@ def write_objects(queue: Queue[types.ObjectJsonRepr], fd: TextIO, object_type: s done = False prefix = "" log.info("Waiting %s to write...", object_type) - print(f'"{object_type}": ' + "{", file=fd) + objects_exported_as_lists = ("projects", "applications", "users", "portfolios") + objects_exported_as_whole = ("qualityGates", "groups") + log.info("Waiting %s to write...", object_type) + if object_type in objects_exported_as_lists: + start, stop = ("[", "]") + elif object_type in objects_exported_as_whole: + start, stop = ("", "") + else: + start, stop = ("{", "}") + print(f'"{object_type}": ' + start, file=fd) while not done: obj_json = queue.get() if not (done := obj_json is utilities.WRITE_END): @@ -177,19 +190,20 @@ def write_objects(queue: Queue[types.ObjectJsonRepr], fd: TextIO, object_type: s obj_json = __prep_json_for_write(obj_json, {**export_settings, EXPORT_EMPTY: True}) else: obj_json = __prep_json_for_write(obj_json, export_settings) - if object_type in ("projects", "applications", "portfolios", "users"): - if object_type == "users": - key = obj_json.pop("login", None) - else: - key = obj_json.pop("key", None) - log.debug("Writing %s key '%s'", object_type[:-1], key) + key = "" if isinstance(obj_json, list) else obj_json.get("key", obj_json.get("login", obj_json.get("name", "unknown"))) + log.debug("Writing %s key '%s'", object_type[:-1], key) + if object_type in objects_exported_as_lists: + print(f"{prefix}{utilities.json_dump(obj_json)}", end="", file=fd) + elif object_type in objects_exported_as_whole: + print(f"{prefix}{utilities.json_dump(obj_json)}", end="", file=fd) + elif object_type in ("applications", "portfolios", "users"): print(f'{prefix}"{key}": {utilities.json_dump(obj_json)}', end="", file=fd) else: log.debug("Writing %s", object_type) print(f"{prefix}{utilities.json_dump(obj_json)[2:-1]}", end="", file=fd) prefix = ",\n" queue.task_done() - print("\n}", file=fd, end="") + print("\n" + stop, file=fd, end="") log.info("Writing %s complete", object_type) diff --git a/sonar/users.py b/sonar/users.py index 67b2ad55..6b01a212 100644 --- a/sonar/users.py +++ b/sonar/users.py @@ -483,13 +483,12 @@ def export(endpoint: pf.Platform, export_settings: types.ConfigSettings, **kwarg """ log.info("Exporting users") write_q = kwargs.get("write_q", None) - u_list = {} - for u_login, u_obj in sorted(search(endpoint=endpoint).items()): - u_list[u_login] = u_obj.to_json(export_settings) + u_list = [] + for _, u_obj in sorted(search(endpoint=endpoint).items()): + u_data = u_obj.to_json(export_settings) + u_list.append(u_data) if write_q: - write_q.put(u_list[u_login]) - else: - u_list[u_login].pop("login", None) + write_q.put(u_data) write_q and write_q.put(util.WRITE_END) return u_list