def __violation(self, violation: Element, namespaces: Namespaces, models: ModelFilePaths, severities: list[str]) -> Optional[Entity]: """Return the violation as entity.""" location = violation.find("./ns:location", namespaces) if not location: raise SourceCollectorException( f"OJAudit violation {violation} has no location element") severity = violation.findtext("./ns:values/ns:value", default="", namespaces=namespaces) if severities and severity not in severities: return None message = violation.findtext("ns:message", default="", namespaces=namespaces) line_number = violation.findtext(".//ns:line-number", namespaces=namespaces) column_offset = violation.findtext(".//ns:column-offset", namespaces=namespaces) model = models[location.get("model", "")] component = f"{model}:{line_number}:{column_offset}" key = sha1_hash(f"{message}:{component}") entity = Entity(key=key, severity=severity, message=message, component=component) if entity["key"] in self.violation_counts: self.violation_counts[entity["key"]] += 1 return None # Ignore duplicate violation self.violation_counts[entity["key"]] = 1 return entity
async def __repository_id(self) -> str: """Return the repository id belonging to the repository.""" api_url = str(await super()._api_url()) repository = self._parameter("repository") or urllib.parse.unquote(api_url.rsplit("/", 1)[-1]) repositories_url = URL(f"{api_url}/_apis/git/repositories?api-version=4.1") repositories = (await (await super()._get_source_responses(repositories_url))[0].json())["value"] matching_repositories = [r for r in repositories if repository in (r["name"], r["id"])] if not matching_repositories: raise SourceCollectorException(f"Repository '{repository}' not found") return str(matching_repositories[0]["id"])
async def _parse_value(self, responses: SourceResponses) -> Value: """Override to parse the scalability breaking point from the responses.""" trend_breaks = [] for response in responses: breaking_point = int((await self._soup(response)).find( id="trendbreak_scalability").string) if breaking_point == 100: raise SourceCollectorException( "No performance scalability breaking point occurred (breaking point is at 100%, expected < 100%)" ) trend_breaks.append(breaking_point) return str(min(trend_breaks))
async def _get_source_responses(self, *urls: URL) -> SourceResponses: """Extend to check the component exists before getting data about it.""" # SonarQube sometimes gives results (e.g. zero violations) even if the component does not exist, so we # check whether the component specified by the user actually exists before getting the data. url = await SourceCollector._api_url(self) component = self._parameter("component") show_component_url = URL(f"{url}/api/components/show?component={component}") response = (await super()._get_source_responses(show_component_url))[0] json = await response.json() if "errors" in json: raise SourceCollectorException(json["errors"][0]["msg"]) return await super()._get_source_responses(*urls)
async def _get_reports(self, response: Response) -> list[dict[str, Any]]: """Get the relevant reports from the reports response.""" report_titles_or_ids = set(self._parameter("reports")) reports = list((await response.json())["reports"]) reports = ( [report for report in reports if (report_titles_or_ids & {report["title"], report["report_uuid"]})] if report_titles_or_ids else reports ) if not reports: message = "No reports found" + (f" with title or id {report_titles_or_ids}" if report_titles_or_ids else "") raise SourceCollectorException(message) return reports
async def __board_id(self, api_url: URL) -> str: """Return the board id.""" last = False start_at = 0 boards: list[JiraVelocity.Board] = [] while not last: url = URL(f"{api_url}/rest/agile/1.0/board?startAt={start_at}") response = (await super()._get_source_responses(url))[0] json = await response.json() boards.extend(json["values"]) start_at += json["maxResults"] last = json["isLast"] board_name_or_id = str(self._parameter("board")).lower() matching_boards = [ b for b in boards if board_name_or_id in (str(b["id"]), b["name"].lower().strip()) ] if not matching_boards: message = f"Could not find a Jira board with id or name '{board_name_or_id}' at {api_url}" raise SourceCollectorException(message) return str(matching_boards[0]["id"])