Skip to content

Commit 78f6686

Browse files
committed
Refactoring issue filters per search
1 parent 7d2208e commit 78f6686

File tree

1 file changed

+46
-50
lines changed

1 file changed

+46
-50
lines changed

sonar/issues.py

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@
4343
COMPONENT_FILTER_OLD = "componentKeys"
4444
COMPONENT_FILTER = "components"
4545

46+
OLD_STATUS = "resolutions"
47+
NEW_STATUS = "issueStatuses"
48+
49+
OLD_FP = "FALSE-POSITIVE"
50+
NEW_FP = "FALSE_POSITIVE"
51+
4652
_SEARCH_CRITERIAS = (
4753
COMPONENT_FILTER_OLD,
4854
COMPONENT_FILTER,
@@ -77,18 +83,17 @@
7783
"author",
7884
"issues",
7985
"languages",
80-
"resolutions",
86+
OLD_STATUS,
8187
"resolved",
8288
"rules",
8389
"scopes",
8490
# 10.2 new filter
8591
"impactSeverities",
8692
# 10.4 new filter
87-
"issueStatuses",
93+
NEW_STATUS,
8894
)
8995

9096
_FILTERS_10_2_REMAPPING = {"severities": "impactSeverities"}
91-
_FILTERS_10_4_REMAPPING = {"statuses": "issueStatuses"}
9297

9398
TYPES = ("BUG", "VULNERABILITY", "CODE_SMELL")
9499
SEVERITIES = ("BLOCKER", "CRITICAL", "MAJOR", "MINOR", "INFO")
@@ -102,7 +107,7 @@
102107
"impactSoftwareQualities": IMPACT_SOFTWARE_QUALITIES,
103108
"impactSeverities": IMPACT_SEVERITIES,
104109
"statuses": STATUSES,
105-
"resolutions": RESOLUTIONS,
110+
OLD_STATUS: RESOLUTIONS,
106111
}
107112

108113
_TOO_MANY_ISSUES_MSG = "Too many issues, recursing..."
@@ -336,7 +341,7 @@ def is_wont_fix(self) -> bool:
336341
:return: Whether the issue is won't fix
337342
:rtype: bool
338343
"""
339-
return self.resolution == "WONT-FIX"
344+
return self.resolution == "WONTFIX"
340345

341346
def is_accepted(self) -> bool:
342347
"""
@@ -350,7 +355,7 @@ def is_false_positive(self) -> bool:
350355
:return: Whether the issue is a false positive
351356
:rtype: bool
352357
"""
353-
return self.resolution == "FALSE-POSITIVE"
358+
return self.resolution in ("FALSE-POSITIVE", "FALSE_POSITIVE")
354359

355360
def strictly_identical_to(self, another_finding: Issue, ignore_component: bool = False) -> bool:
356361
"""
@@ -447,7 +452,7 @@ def __apply_event(self, event: str, settings: ConfigSettings) -> bool:
447452
else:
448453
self.reopen()
449454
# self.add_comment(f"Issue re-open {origin}", settings[SYNC_ADD_COMMENTS])
450-
elif event_type == "FALSE-POSITIVE":
455+
elif event_type in ("FALSE-POSITIVE", "FALSE_POSITIVE"):
451456
self.mark_as_false_positive()
452457
# self.add_comment(f"False positive {origin}", settings[SYNC_ADD_COMMENTS])
453458
elif event_type == "WONT-FIX":
@@ -747,8 +752,6 @@ def search(endpoint: pf.Platform, params: ApiParams = None, raise_error: bool =
747752
filters = pre_search_filters(endpoint=endpoint, params=params)
748753
# if endpoint.version() >= (10, 2, 0):
749754
# new_params = util.dict_remap_and_stringify(new_params, _FILTERS_10_2_REMAPPING)
750-
if endpoint.version() >= (10, 4, 0):
751-
filters = _change_filters_for_10_4(filters)
752755

753756
log.debug("Search filters = %s", str(filters))
754757
if not filters:
@@ -822,11 +825,10 @@ def count(endpoint: pf.Platform, **kwargs) -> int:
822825
params = {} if not kwargs else kwargs.copy()
823826
params["ps"] = 1
824827
try:
825-
log.debug("Count params = %s", str(params))
826828
nbr_issues = len(search(endpoint=endpoint, params=params))
827829
except TooManyIssuesError as e:
828830
nbr_issues = e.nbr_issues
829-
log.debug("Issue search %s would return %d issues", str(kwargs), nbr_issues)
831+
log.debug("Count issues with filters %s returned %d issues", str(kwargs), nbr_issues)
830832
return nbr_issues
831833

832834

@@ -852,7 +854,7 @@ def count_by_rule(endpoint: pf.Platform, **kwargs) -> dict[str, int]:
852854
if d["val"] not in rulecount:
853855
rulecount[d["val"]] = 0
854856
rulecount[d["val"]] += d["count"]
855-
log.debug("Rule counts = %s", util.json_dump(rulecount))
857+
# log.debug("Rule counts = %s", util.json_dump(rulecount))
856858
return rulecount
857859

858860

@@ -868,42 +870,36 @@ def pre_search_filters(endpoint: pf.Platform, params: ApiParams) -> ApiParams:
868870
"""Returns the filtered list of params that are allowed for api/issue/search"""
869871
if not params:
870872
return {}
871-
filters = util.dict_subset(util.remove_nones(params.copy()), _SEARCH_CRITERIAS)
872-
if endpoint.version() >= (10, 2, 0):
873-
if COMPONENT_FILTER_OLD in filters:
874-
filters[COMPONENT_FILTER] = filters.pop(COMPONENT_FILTER_OLD)
875-
if "types" in filters:
876-
__MAP = {"BUG": "RELIABILITY", "CODE_SMELL": "MAINTAINABILITY", "VULNERABILITY": "SECURITY", "SECURITY_HOTSPOT": "SECURITY"}
877-
filters["impactSoftwareQualities"] = [__MAP[t] for t in filters.pop("types")]
878-
if len(filters["impactSoftwareQualities"]) == 0:
879-
filters.pop("impactSoftwareQualities")
880-
if "severities" in filters:
881-
__MAP = {"BLOCKER": "HIGH", "CRITICAL": "HIGH", "MAJOR": "MEDIUM", "MINOR": "LOW", "INFO": "LOW"}
882-
filters["impactSeverities"] = [__MAP[t] for t in filters.pop("severities")]
883-
if len(filters["impactSeverities"]) == 0:
884-
filters.pop("impactSeverities")
885-
for k, v in FILTERS_MAP.items():
886-
if k in filters:
887-
filters[k] = util.allowed_values_string(filters[k], v)
888-
if filters.get("languages", None) is not None:
889-
filters["languages"] = util.list_to_csv(filters["languages"])
890-
873+
log.debug("Sanitizing issue search filters %s", str(params))
874+
version = endpoint.version()
875+
filters = util.dict_remap(original_dict=params.copy(), remapping={"project": COMPONENT_FILTER})
876+
filters = util.dict_subset(util.remove_nones(filters), _SEARCH_CRITERIAS)
877+
if version < (10, 2, 0):
878+
# Starting from 10.2 - "componentKeys" was renamed "components"
879+
filters = util.dict_remap(original_dict=filters, remapping={COMPONENT_FILTER: COMPONENT_FILTER_OLD})
880+
else:
881+
# Starting from 10.2 - Issue types were replaced by software qualities, and severities replaced by impacts
882+
__MAP = {"BUG": "RELIABILITY", "CODE_SMELL": "MAINTAINABILITY", "VULNERABILITY": "SECURITY", "SECURITY_HOTSPOT": "SECURITY"}
883+
filters["impactSoftwareQualities"] = util.list_re_value(filters.pop("types", None), __MAP)
884+
if len(filters["impactSoftwareQualities"]) == 0:
885+
filters.pop("impactSoftwareQualities")
886+
__MAP = {"BLOCKER": "HIGH", "CRITICAL": "HIGH", "MAJOR": "MEDIUM", "MINOR": "LOW", "INFO": "LOW"}
887+
filters["impactSeverities"] = util.list_re_value(filters.pop("severities", None), __MAP)
888+
if len(filters["impactSeverities"]) == 0:
889+
filters.pop("impactSeverities")
890+
891+
if version < (10, 4, 0):
892+
log.debug("Sanitizing issue search filters - fixing resolutions")
893+
filters = util.dict_remap(original_dict=filters, remapping={NEW_STATUS: OLD_STATUS})
894+
if OLD_STATUS in filters:
895+
filters[OLD_STATUS] = util.list_re_value(filters[OLD_STATUS], mapping={NEW_FP: OLD_FP})
896+
else:
897+
# Starting from 10.4 - "resolutions" was renamed "issuesStatuses", "FALSE-POSITIVE" was renamed "FALSE_POSITIVE"
898+
filters = util.dict_remap(original_dict=filters, remapping={OLD_STATUS: NEW_STATUS})
899+
if NEW_STATUS in filters:
900+
filters[NEW_STATUS] = util.list_re_value(filters[NEW_STATUS], mapping={OLD_FP: NEW_FP})
901+
902+
filters = {k: util.allowed_values_string(v, FILTERS_MAP[k]) if k in FILTERS_MAP else v for k, v in filters.items()}
903+
filters = {k: util.list_to_csv(v) for k, v in filters.items() if v}
904+
log.debug("Sanitized issue search filters %s", str(filters))
891905
return filters
892-
893-
894-
def _change_filters_for_10_4(filters: ApiParams) -> ApiParams:
895-
"""Adjust filters for new 10.4 issues/search API parameters"""
896-
if not filters:
897-
return None
898-
new_filters = util.dict_remap(filters.copy(), _FILTERS_10_4_REMAPPING)
899-
statuses = []
900-
for f in "resolutions", "issueStatuses":
901-
if f in new_filters:
902-
statuses += util.csv_to_list(new_filters[f])
903-
new_filters.pop("resolutions", None)
904-
if len(statuses) > 0:
905-
if "FALSE-POSITIVE" in statuses:
906-
statuses.remove("FALSE-POSITIVE")
907-
statuses.append("FALSE_POSITIVE")
908-
new_filters["issueStatuses"] = util.list_to_csv(statuses)
909-
return new_filters

0 commit comments

Comments
 (0)