From 64eddac3d6c53138cada30d9d65c02e37c742027 Mon Sep 17 00:00:00 2001 From: Olivier Korach Date: Mon, 3 Nov 2025 18:40:35 +0100 Subject: [PATCH 1/5] Remove calls to convert_for_yaml --- cli/config.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/cli/config.py b/cli/config.py index 04a80dc9..696a2ef3 100644 --- a/cli/config.py +++ b/cli/config.py @@ -64,16 +64,16 @@ } _EXPORT_CALLS = { - c.CONFIG_KEY_PLATFORM: [c.CONFIG_KEY_PLATFORM, platform.basics, platform.convert_for_yaml], - options.WHAT_SETTINGS: [c.CONFIG_KEY_SETTINGS, platform.export, platform.convert_for_yaml], - options.WHAT_RULES: [c.CONFIG_KEY_RULES, rules.export, rules.convert_for_yaml], - options.WHAT_PROFILES: [c.CONFIG_KEY_PROFILES, qualityprofiles.export, qualityprofiles.convert_for_yaml], - options.WHAT_GATES: [c.CONFIG_KEY_GATES, qualitygates.export, qualitygates.convert_for_yaml], - options.WHAT_PROJECTS: [c.CONFIG_KEY_PROJECTS, projects.export, projects.convert_for_yaml], - options.WHAT_APPS: [c.CONFIG_KEY_APPS, applications.export, applications.convert_for_yaml], - options.WHAT_PORTFOLIOS: [c.CONFIG_KEY_PORTFOLIOS, portfolios.export, portfolios.convert_for_yaml], - options.WHAT_USERS: [c.CONFIG_KEY_USERS, users.export, users.convert_for_yaml], - options.WHAT_GROUPS: [c.CONFIG_KEY_GROUPS, groups.export, groups.convert_for_yaml], + c.CONFIG_KEY_PLATFORM: [c.CONFIG_KEY_PLATFORM, platform.basics], + options.WHAT_SETTINGS: [c.CONFIG_KEY_SETTINGS, platform.export], + options.WHAT_RULES: [c.CONFIG_KEY_RULES, rules.export], + options.WHAT_PROFILES: [c.CONFIG_KEY_PROFILES, qualityprofiles.export], + options.WHAT_GATES: [c.CONFIG_KEY_GATES, qualitygates.export], + options.WHAT_PROJECTS: [c.CONFIG_KEY_PROJECTS, projects.export], + options.WHAT_APPS: [c.CONFIG_KEY_APPS, applications.export], + options.WHAT_PORTFOLIOS: [c.CONFIG_KEY_PORTFOLIOS, portfolios.export], + options.WHAT_USERS: [c.CONFIG_KEY_USERS, users.export], + options.WHAT_GROUPS: [c.CONFIG_KEY_GROUPS, groups.export], } WHAT_EVERYTHING = list(_EXPORT_CALLS.keys())[1:] @@ -150,22 +150,12 @@ def __normalize_file(file: str, format: str) -> bool: json_data = __normalize_json(json_data, remove_empty=False, remove_none=True) with utilities.open_file(file, mode="w") as fd: if format == "yaml": - print(yaml.dump(__convert_for_yaml(json_data), sort_keys=False), file=fd) + print(yaml.dump(json_data, sort_keys=False), file=fd) else: print(utilities.json_dump(json_data), file=fd) return True -def __convert_for_yaml(json_export: dict[str, any]) -> dict[str, any]: - """Converts the default JSON produced by export to a modified version more suitable for YAML""" - for what in WHAT_EVERYTHING: - for k in json_export: - if what.lower() == k.lower() or (what == "settings" and k == "globalSettings"): - yamlify_func = _EXPORT_CALLS[what][2] - json_export[k] = yamlify_func(json_export[k]) - return json_export - - def write_objects(queue: Queue[types.ObjectJsonRepr], fd: TextIO, object_type: str, export_settings: types.ConfigSettings) -> None: """ Thread to write projects in the JSON file From 9f21bbb3cf7120ac868b32475c7b682ae9f92066 Mon Sep 17 00:00:00 2001 From: Olivier Korach Date: Mon, 3 Nov 2025 18:40:51 +0100 Subject: [PATCH 2/5] Remove convert_for_yaml() --- sonar/applications.py | 13 ------------- sonar/groups.py | 5 ----- sonar/permissions/permissions.py | 9 --------- sonar/platform.py | 22 ---------------------- sonar/portfolios.py | 17 ----------------- sonar/projects.py | 9 --------- sonar/qualitygates.py | 5 ----- sonar/qualityprofiles.py | 11 ----------- sonar/rules.py | 6 ------ sonar/users.py | 5 ----- 10 files changed, 102 deletions(-) diff --git a/sonar/applications.py b/sonar/applications.py index 0380bae4..29ff4f6e 100644 --- a/sonar/applications.py +++ b/sonar/applications.py @@ -598,16 +598,3 @@ def search_by_name(endpoint: pf.Platform, name: str) -> dict[str, Application]: data[app.key] = app # return {app.key: app for app in Application.CACHE.values() if app.name == name} return data - - -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - new_json = util.dict_to_list(util.remove_nones(original_json), "key") - for app_json in new_json: - app_json["branches"] = util.dict_to_list(app_json["branches"], "name") - for b in app_json["branches"]: - if "projects" in b: - b["projects"] = [{"key": k, "branch": br} for k, br in b["projects"].items()] - if "permissions" in app_json: - app_json["permissions"] = permissions.convert_for_yaml(app_json["permissions"]) - return new_json diff --git a/sonar/groups.py b/sonar/groups.py index 4d77aa31..f35f7e7d 100644 --- a/sonar/groups.py +++ b/sonar/groups.py @@ -432,8 +432,3 @@ def exists(endpoint: pf.Platform, name: str) -> bool: :return: whether the group exists """ return Group.get_object(endpoint=endpoint, name=name) is not None - - -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - return util.dict_to_list(util.remove_nones(original_json), "name", "description") diff --git a/sonar/permissions/permissions.py b/sonar/permissions/permissions.py index 7aa1a58d..e10bcf7e 100644 --- a/sonar/permissions/permissions.py +++ b/sonar/permissions/permissions.py @@ -430,12 +430,3 @@ def black_list(perms: types.JsonPermissions, disallowed_perms: list[str]) -> typ for user_or_group, original_perms in sub_perms.items(): resulting_perms[perm_type][user_or_group] = [p for p in original_perms if p not in disallowed_perms] return resulting_perms - - -def convert_for_yaml(json_perms: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Converts permissions in a format that is more friendly for YAML""" - converted_perms = [] - for ptype in "groups", "users": - if ptype in json_perms: - converted_perms += utilities.dict_to_list(json_perms[ptype], ptype[:-1], "permissions") - return converted_perms diff --git a/sonar/platform.py b/sonar/platform.py index e83a1d33..d1fa62aa 100644 --- a/sonar/platform.py +++ b/sonar/platform.py @@ -942,28 +942,6 @@ def _check_for_retry(response: requests.models.Response) -> tuple[bool, str]: return False, None -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - original_json = util.remove_nones(original_json) - if "plugins" in original_json: - original_json["plugins"] = util.dict_to_list(original_json["plugins"], "key", "version") - if "languages" in original_json: - original_json["languages"] = util.dict_to_list(original_json["languages"], "language") - if "permissions" in original_json: - original_json["permissions"] = permissions.convert_for_yaml(original_json["permissions"]) - if "permissionTemplates" in original_json: - for tpl in original_json["permissionTemplates"].values(): - if "permissions" in tpl: - tpl["permissions"] = permissions.convert_for_yaml(tpl["permissions"]) - original_json["permissionTemplates"] = util.dict_to_list(original_json["permissionTemplates"], "name") - if "devopsIntegration" in original_json: - original_json["devopsIntegration"] = util.dict_to_list(original_json["devopsIntegration"], "name") - for key in ("analysisScope", "authentication", "generalSettings", "linters"): - if key in original_json: - original_json[key] = util.dict_to_list(original_json[key], "key", "value") - return original_json - - def export(endpoint: Platform, export_settings: types.ConfigSettings, **kwargs) -> types.ObjectJsonRepr: """Exports all or a list of projects configuration as dict diff --git a/sonar/portfolios.py b/sonar/portfolios.py index c0b90366..10a1aa07 100644 --- a/sonar/portfolios.py +++ b/sonar/portfolios.py @@ -847,23 +847,6 @@ def get_api_branch(branch: str) -> str: return branch if branch != c.DEFAULT_BRANCH else None -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - new_json = util.dict_to_list(util.remove_nones(original_json), "key") - for p_json in new_json: - try: - p_json["projects"] = [{"key": k, "branch": br} for k, br in p_json["projects"]["manual"].items()] - except KeyError: - pass - if "portfolios" in p_json: - p_json["portfolios"] = convert_for_yaml(p_json["portfolios"]) - if "applications" in p_json: - p_json["applications"] = [{"key": k, "branches": br} for k, br in p_json["applications"].items()] - if "permissions" in p_json: - p_json["permissions"] = perms.convert_for_yaml(p_json["permissions"]) - return new_json - - def clear_cache(endpoint: pf.Platform) -> None: """Clears the cache of an endpoint""" Portfolio.clear_cache(endpoint) diff --git a/sonar/projects.py b/sonar/projects.py index 5d480be5..4105b0c8 100644 --- a/sonar/projects.py +++ b/sonar/projects.py @@ -1707,12 +1707,3 @@ def convert_proj_for_yaml(proj_json: types.ObjectJsonRepr) -> types.ObjectJsonRe if "permissions" in proj_json: proj_json["permissions"] = perms.convert_for_yaml(proj_json["permissions"]) return proj_json - - -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - clean_json = util.remove_nones(original_json) - new_json = [] - for proj in util.dict_to_list(clean_json, "key"): - new_json.append(convert_proj_for_yaml(proj)) - return new_json diff --git a/sonar/qualitygates.py b/sonar/qualitygates.py index c919761e..1236d3de 100644 --- a/sonar/qualitygates.py +++ b/sonar/qualitygates.py @@ -561,8 +561,3 @@ def _decode_condition(cond: str) -> tuple[str, str, str]: def search_by_name(endpoint: pf.Platform, name: str) -> dict[str, QualityGate]: """Searches quality gates matching name""" return util.search_by_name(endpoint, name, QualityGate.API[c.LIST], "qualitygates") - - -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - return util.dict_to_list(util.remove_nones(original_json), "name") diff --git a/sonar/qualityprofiles.py b/sonar/qualityprofiles.py index 9ba66a50..6ab46c64 100644 --- a/sonar/qualityprofiles.py +++ b/sonar/qualityprofiles.py @@ -917,14 +917,3 @@ def convert_one_qp_yaml(qp: types.ObjectJsonRepr) -> types.ObjectJsonRepr: qp[_CHILDREN_KEY] = {k: convert_one_qp_yaml(q) for k, q in qp[_CHILDREN_KEY].items()} qp[_CHILDREN_KEY] = util.dict_to_list(qp[_CHILDREN_KEY], "name") return qp - - -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - new_json = {} - for lang, qp_list in util.remove_nones(original_json).items(): - new_json[lang] = {"profiles": util.dict_to_list(qp_list, "name")} - new_json = util.dict_to_list(new_json, "language") - for lang in new_json: - lang["profiles"] = [convert_one_qp_yaml(qp) for qp in lang["profiles"]] - return new_json diff --git a/sonar/rules.py b/sonar/rules.py index 1f3aba9f..dcb4bcf1 100644 --- a/sonar/rules.py +++ b/sonar/rules.py @@ -562,12 +562,6 @@ def convert_rule_list_for_yaml(rule_list: types.ObjectJsonRepr) -> list[types.Ob return utilities.dict_to_list(rule_list, "key", "severity") -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - clean_json = utilities.remove_nones(original_json) - return {category: convert_rule_list_for_yaml(clean_json[category]) for category in ("instantiated", "extended") if category in clean_json} - - def third_party(endpoint: platform.Platform) -> list[Rule]: """Returns the list of rules coming from 3rd party plugins""" return [r for r in get_list(endpoint=endpoint).values() if r.repo and r.repo not in SONAR_REPOS and not r.repo.startswith("external_")] diff --git a/sonar/users.py b/sonar/users.py index 6b01a212..3eeabd1f 100644 --- a/sonar/users.py +++ b/sonar/users.py @@ -561,11 +561,6 @@ def import_config(endpoint: pf.Platform, config_data: types.ObjectJsonRepr, key_ o.update(**data) -def convert_for_yaml(original_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - return util.dict_to_list(original_json, "login") - - def exists(endpoint: pf.Platform, login: str) -> bool: """ :param endpoint: reference to the SonarQube platform From f7802290b1650bead17ee45598134b196e7bb264 Mon Sep 17 00:00:00 2001 From: Olivier Korach Date: Mon, 3 Nov 2025 18:44:16 +0100 Subject: [PATCH 3/5] Remove forgotten call to convert_for_yaml() --- sonar/projects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar/projects.py b/sonar/projects.py index 4105b0c8..838c68a2 100644 --- a/sonar/projects.py +++ b/sonar/projects.py @@ -1705,5 +1705,5 @@ def convert_proj_for_yaml(proj_json: types.ObjectJsonRepr) -> types.ObjectJsonRe if "qualityProfiles" in proj_json: proj_json["qualityProfiles"] = util.dict_to_list(proj_json["qualityProfiles"], "language", "name") if "permissions" in proj_json: - proj_json["permissions"] = perms.convert_for_yaml(proj_json["permissions"]) + proj_json["permissions"] = convert_for_yaml(proj_json["permissions"]) return proj_json From a238278ecfd23dec4819e64a0627c37150067b40 Mon Sep 17 00:00:00 2001 From: Olivier Korach Date: Mon, 3 Nov 2025 18:45:00 +0100 Subject: [PATCH 4/5] Remove more convert_for_yaml() --- sonar/projects.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sonar/projects.py b/sonar/projects.py index 838c68a2..26bcce7e 100644 --- a/sonar/projects.py +++ b/sonar/projects.py @@ -1696,14 +1696,3 @@ def import_zips(endpoint: pf.Platform, project_list: list[str], threads: int = 2 log.info("%d/%d imports (%d%%) - Latest: %s - %s", i, nb_projects, int(i * 100 / nb_projects), proj_key, status) log.info("%s", ", ".join([f"{k}:{v}" for k, v in statuses_count.items()])) return statuses - - -def convert_proj_for_yaml(proj_json: types.ObjectJsonRepr) -> types.ObjectJsonRepr: - """Convert the original JSON defined for JSON export into a JSON format more adapted for YAML export""" - if "branches" in proj_json: - proj_json["branches"] = util.dict_to_list(proj_json["branches"], "name") - if "qualityProfiles" in proj_json: - proj_json["qualityProfiles"] = util.dict_to_list(proj_json["qualityProfiles"], "language", "name") - if "permissions" in proj_json: - proj_json["permissions"] = convert_for_yaml(proj_json["permissions"]) - return proj_json From 6c9a3901d37a895cfb5e8a4dbeeee5e113530276 Mon Sep 17 00:00:00 2001 From: Olivier Korach Date: Mon, 3 Nov 2025 18:46:14 +0100 Subject: [PATCH 5/5] Fix call_data unpacking --- cli/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/config.py b/cli/config.py index 696a2ef3..342beac0 100644 --- a/cli/config.py +++ b/cli/config.py @@ -224,7 +224,7 @@ def export_config(endpoint: platform.Platform, what: list[str], **kwargs) -> Non for what_item, call_data in _EXPORT_CALLS.items(): if what_item not in what: continue - ndx, func, _ = call_data + ndx, func = call_data if not is_first: print(",", file=fd) is_first = False