Skip to content

Commit

Permalink
Merge pull request okorach#1231 from okorach:sonar-config-fixes
Browse files Browse the repository at this point in the history
sonar-config fixes
  • Loading branch information
okorach authored Jul 29, 2024
2 parents 5be6e33 + 0d55698 commit 22fc49b
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 22 deletions.
10 changes: 7 additions & 3 deletions sonar/app_branches.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def __init__(self, app: App, name: str, project_branches: list[Branch], is_main:
super().__init__(endpoint=app.endpoint, key=f"{app.key} BRANCH {name}")
self.concerned_object = app
self.name = name
self.is_main = is_main
self._is_main = is_main
self._project_branches = project_branches
self._last_analysis = None
log.debug("Created object %s with uuid %s id %x", str(self), self.uuid(), id(self))
Expand Down Expand Up @@ -124,6 +124,10 @@ def load(cls, app: App, branch_data: dict[str, str]) -> ApplicationBranch:
def __str__(self) -> str:
return f"application '{self.concerned_object.key}' branch '{self.name}'"

def is_main(self) -> bool:
"""Returns whether app branch is main"""
return self._is_main

def projects_branches(self) -> list[Branch]:
"""
:return: The list of project branches included in the application branch
Expand All @@ -137,7 +141,7 @@ def delete(self) -> bool:
:return: Whether the delete succeeded
:rtype: bool
"""
if self.is_main:
if self.is_main():
log.warning("Can't delete main %s, simply delete the application for that", str(self))
return False
return sq.delete_object(self, APIS["delete"], self.search_params(), _OBJECTS)
Expand All @@ -155,7 +159,7 @@ def export(self) -> dict[str, str]:
"""
log.info("Exporting %s", str(self))
jsondata = {"projects": {b.concerned_object.key: b.name for b in self._project_branches}}
if self.is_main:
if self.is_main():
jsondata["isMain"] = True
return jsondata

Expand Down
5 changes: 3 additions & 2 deletions sonar/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,15 @@ def branch_exists(self, branch_name: str) -> bool:
:return: Whether the Application branch exists
:rtype: bool
"""
return branch_name in [b.name for b in self.branches()]
return branch_name in self.branches()

def branch_is_main(self, branch: str) -> bool:
"""
:return: Whether the Application branch is the main branch
:rtype: bool
"""
return branch in self.branches() and self._branches[branch]["isMain"]
br = self.branches()
return branch in br and br[branch].is_main()

def set_branch(self, branch_name: str, branch_data: dict[str, str]) -> Application:
"""Creates or updates an Application branch with a set of project branches
Expand Down
6 changes: 5 additions & 1 deletion sonar/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def load(cls, endpoint: pf.Platform, data: dict[str, str]) -> Group:
:return: The group object
:rtype: Group or None
"""
return cls(name=data["name"], endpoint=endpoint, data=data)
return cls(endpoint=endpoint, name=data["name"], data=data)

def __str__(self) -> str:
"""
Expand All @@ -111,6 +111,10 @@ def __str__(self) -> str:
"""
return f"group '{self.name}'"

def uuid(self) -> str:
"""Returns object unique ID in its class"""
return sq.uuid(self.name, self.endpoint.url)

def is_default(self) -> bool:
"""
:return: whether the group is a default group (sonar-users only for now) or not
Expand Down
2 changes: 1 addition & 1 deletion sonar/permissions/permission_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def __str__(self) -> str:

def uuid(self) -> str:
"""Returns object unique id"""
sqobject.uuid(self.name.lower(), self.endpoint.url)
return sqobject.uuid(self.name.lower(), self.endpoint.url)

def is_default_for(self, qualifier: str) -> bool:
"""Returns whether a template is the default for a type of qualifier"""
Expand Down
6 changes: 5 additions & 1 deletion sonar/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,11 @@ def import_config(endpoint: pf.Platform, config_data: dict[str, str], key_list:
try:
o = Project.get_object(endpoint, key)
except exceptions.ObjectNotFound:
o = Project.create(endpoint, key, data["name"])
try:
o = Project.create(endpoint, key, data["name"])
except exceptions.ObjectAlreadyExists as e:
log.warning("Can't create project with key '%s', %s", key, e.message)
continue
o.update(data)
i += 1
if i % 20 == 0 or i == nb_projects:
Expand Down
2 changes: 1 addition & 1 deletion sonar/qualitygates.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def load(cls, endpoint: pf.Platform, data: dict[str, str]) -> QualityGate:
# SonarQube 10 compatibility: "id" field dropped, replaced by "name"
o = _OBJECTS.get(sq.uuid(data["name"], endpoint.url), None)
if not o:
o = cls(data["name"], endpoint, data=data)
o = cls(endpoint, data["name"], data=data)
o._json = data
return o

Expand Down
10 changes: 7 additions & 3 deletions sonar/qualityprofiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,12 @@ def __import_thread(queue: Queue) -> None:
"""Callback function for multithreaded QP import"""
while not queue.empty():
(name, lang, endpoint, qp_data) = queue.get()
o = get_object(endpoint=endpoint, name=name, language=lang)
if o is None:
try:
o = get_object(endpoint=endpoint, name=name, language=lang)
except exceptions.ObjectNotFound:
if qp_data.get("isBuiltIn", False):
log.warning("Can't import built-in quality profile '%s' because it is not present on target platform", name)
queue.task_done()
o = QualityProfile.create(endpoint=endpoint, name=name, language=lang)
log.info("Importing quality profile '%s' of language '%s'", name, lang)
o.update(qp_data, queue)
Expand All @@ -669,7 +673,7 @@ def import_config(endpoint: pf.Platform, config_data: dict[str, str], threads: i
get_list(endpoint=endpoint)
for lang, lang_data in config_data["qualityProfiles"].items():
if not languages.exists(endpoint=endpoint, language=lang):
log.warning("Language '%s' does not exist, quality profile '%s' import skipped", lang, name)
log.warning("Language '%s' does not exist, quality profiles import skipped for this language", lang)
continue
for name, qp_data in lang_data.items():
q.put((name, lang, endpoint, qp_data))
Expand Down
6 changes: 3 additions & 3 deletions sonar/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def get_object(cls, endpoint: platform.Platform, key: str) -> Rule:
def create(cls, endpoint: platform.Platform, key: str, **kwargs) -> Union[None, Rule]:
"""Creates a rule object"""
params = kwargs.copy()
(_, params["custom_key"]) = key.split(":")
(_, params["customKey"]) = key.split(":")
log.debug("Creating rule key '%s'", key)
if not endpoint.post(_CREATE_API, params=params).ok:
return None
Expand Down Expand Up @@ -114,11 +114,11 @@ def instantiate(cls, endpoint: platform.Platform, key: str, template_key: str, d
return Rule.create(
key=key,
endpoint=endpoint,
template_key=template_key,
templateKey=template_key,
name=data.get("name", key),
severity=data.get("severity", "MAJOR"),
params=rule_params,
markdown_description=data.get("description", "NO DESCRIPTION"),
markdownDescription=data.get("description", "NO DESCRIPTION"),
)

def __str__(self) -> str:
Expand Down
28 changes: 22 additions & 6 deletions sonar/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import re
import json
from typing import Union

from requests.exceptions import HTTPError
import sonar.logging as log
import sonar.platform as pf

Expand Down Expand Up @@ -235,6 +235,11 @@ def set(self, value: any) -> bool:
if self.endpoint.version() > (9, 4, 0) or not self.key.startswith("sonar.cobol"):
value = decode(self.key, value)

# With SonarQube 10.x you can't set the github URL
if re.match(r"^sonar\.auth\.(.*)Url$", self.key) and self.endpoint.version() >= (10, 0, 0):
log.warning("GitHub URL (%s) cannot be set, skipping this setting", self.key)
return False

log.debug("Setting %s to value '%s'", str(self), str(value))
params = {"key": self.key, "component": self.component.key if self.component else None}
if isinstance(value, list):
Expand Down Expand Up @@ -338,7 +343,10 @@ def category(self) -> tuple[str, str]:

def get_object(endpoint: pf.Platform, key: str, component: object = None) -> Setting:
"""Returns a Setting object from its key and, optionally, component"""
return _OBJECTS.get(uuid(key, component, endpoint.url), None)
uid = uuid(key, component, endpoint.url)
if uid not in _OBJECTS:
get_all(endpoint, component)
return _OBJECTS.get(uid, None)


def __get_settings(endpoint: pf.Platform, data: dict[str, str], component: object = None) -> dict[str, Setting]:
Expand Down Expand Up @@ -463,11 +471,19 @@ def set_visibility(endpoint: pf.Platform, visibility: str, component: object = N
log.debug("Setting setting '%s' to value '%s'", PROJECT_DEFAULT_VISIBILITY, str(visibility))
return endpoint.post("projects/update_default_visibility", params={"projectVisibility": visibility}).ok


def set_setting(endpoint: pf.Platform, key: str, value: any, component: object = None) -> None:
def set_setting(endpoint: pf.Platform, key: str, value: any, component: object = None) -> bool:
"""Sets a setting to a particular value"""
get_object(endpoint=endpoint, key=key, component=component).set(value)

s = get_object(endpoint=endpoint, key=key, component=component)
if not s:
log.warning("Setting %s does not exist on target platform, it cannot be set")
return False
else:
try:
s.set(value)
return True
except HTTPError:
log.warning("Setting %s does not exist on target platform, it cannot be set", key)
return False

def decode(setting_key: str, setting_value: any) -> any:
"""Decodes a setting"""
Expand Down
2 changes: 1 addition & 1 deletion sonar/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@
"""

PACKAGE_VERSION = "3.2.1"
PACKAGE_VERSION = "3.2.2"

0 comments on commit 22fc49b

Please sign in to comment.