diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1b033f4..58632f3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,3 +11,7 @@ updates: ignore: - dependency-name: "actions/*" update-types: ["version-update:semver-patch"] + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/cetlvast.yml b/.github/workflows/cetlvast.yml index a8869dd..4c2321a 100644 --- a/.github/workflows/cetlvast.yml +++ b/.github/workflows/cetlvast.yml @@ -23,10 +23,10 @@ jobs: runs-on: ubuntu-latest container: ghcr.io/opencyphal/toolshed:ts24.4.3 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - name: Cache ext modules id: cetlvast-ext - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: cetlvast/build_external key: build-external-${{ hashFiles('**/cetlvast/cmake/modules/ExternalDependencies*.cmake.in') }}-${{ hashFiles('**/cetlvast/cmake/modules/patches/*.patch') }} @@ -52,9 +52,9 @@ jobs: toolchain: ["gcc-native-32", "clang-native"] standard: ["cpp-14", "cpp-17", "cpp-20", "cpp-23"] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - name: Cache ext modules - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: cetlvast/build_external key: build-external-${{ hashFiles('**/cetlvast/cmake/modules/ExternalDependencies*.cmake.in') }}-${{ hashFiles('**/cetlvast/cmake/modules/patches/*.patch') }} @@ -66,13 +66,11 @@ jobs: run: > cmake --workflow --preset workflow-${{ matrix.toolchain }}-${{ matrix.standard }}-offline - name: upload-artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.toolchain }}-${{ matrix.standard }}-amd64 path: | cetlvast/build/compile_commands.json - cetlvast/build/*/**/coverage.xml - cetlvast/build/*/**/*-sonarqube.xml cetlvast/build/*/**/gcovr_html/*.* if-no-files-found: error @@ -93,9 +91,9 @@ jobs: toolchain: ["gcc-native", "clang-native"] standard: ["cpp-14", "cpp-17", "cpp-20"] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - name: Cache ext modules - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: cetlvast/build_external key: build-external-${{ hashFiles('**/cetlvast/cmake/modules/ExternalDependencies*.cmake.in') }}-${{ hashFiles('**/cetlvast/cmake/modules/patches/*.patch') }} @@ -107,13 +105,11 @@ jobs: run: > cmake --workflow --preset workflow-${{ matrix.toolchain }}-${{ matrix.standard }}-offline - name: upload-artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.toolchain }}-${{ matrix.standard }}-arm64 path: | cetlvast/build/compile_commands.json - cetlvast/build/*/**/coverage.xml - cetlvast/build/*/**/*-sonarqube.xml cetlvast/build/*/**/gcovr_html/*.* if-no-files-found: error @@ -130,9 +126,9 @@ jobs: needs: - cache-warmup steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - name: Cache ext modules - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: cetlvast/build_external key: build-external-${{ hashFiles('**/cetlvast/cmake/modules/ExternalDependencies*.cmake.in') }}-${{ hashFiles('**/cetlvast/cmake/modules/patches/*.patch') }} @@ -145,57 +141,18 @@ jobs: run: ninja docs - name: Setup Pages if: ${{ github.event_name != 'pull_request' }} - uses: actions/configure-pages@v5 + uses: actions/configure-pages@v6 - name: Upload docs if: ${{ github.event_name != 'pull_request' }} - uses: actions/upload-pages-artifact@v4 + uses: actions/upload-pages-artifact@v5 with: path: "cetlvast/build/suites/docs/html/" - sonarqube: - if: > - (github.event_name == 'release' && !github.event.release.prerelease) || - github.event_name == 'workflow_dispatch' || - contains(github.event.head_commit.message, '#sonar') || - contains(github.ref, '/main') || - contains(github.ref, '/issue/') || - (github.event_name == 'pull_request') - needs: - - cache-warmup - runs-on: ubuntu-latest - container: ghcr.io/opencyphal/toolshed:ts24.4.3 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - steps: - - uses: actions/checkout@v5 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis by sonarqube. - - name: Cache ext modules - uses: actions/cache@v4 - with: - path: cetlvast/build_external - key: build-external-${{ hashFiles('**/cetlvast/cmake/modules/ExternalDependencies*.cmake.in') }}-${{ hashFiles('**/cetlvast/cmake/modules/patches/*.patch') }} - fail-on-cache-miss: true - - name: Check for SONAR_TOKEN - if: ${{ env.SONAR_TOKEN == '' && github.event_name == 'pull_request' }} - run: echo "::notice file=cetlvast.yml,line=188,col=8,endColumn=80,title=No-Sonar::SONAR_TOKEN is not available for pull requests from external repositories." - - name: Check for SONAR_TOKEN - if: ${{ env.SONAR_TOKEN == '' && github.event_name != 'pull_request' }} - run: echo "::error file=cetlvast.yml,line=191,col=8,endColumn=80,title=SONAR_TOKEN-missing::SONAR_TOKEN was empty or not found." - - name: Run build for sonar-scanner - if: ${{ env.SONAR_TOKEN != '' }} - working-directory: cetlvast - run: cmake --workflow --preset manual-coverage-gcc-native-cpp-14-offline - - name: SonarQube Scan - uses: SonarSource/sonarqube-scan-action@v5.3.1 - if: ${{ env.SONAR_TOKEN != '' }} deploy-docs: if: > (github.event_name == 'release' && !github.event.release.prerelease) || github.event_name == 'workflow_dispatch' needs: - - sonarqube - docs # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: @@ -213,4 +170,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 30236cb..cfc6c24 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -30,11 +30,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v7 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -51,7 +51,7 @@ jobs: # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - name: Cache ext modules - uses: actions/cache@v4 + uses: actions/cache@v6 id: cetlvast-ext with: path: cetlvast/build_external @@ -65,6 +65,6 @@ jobs: run: cmake --workflow --preset manual-simple-workflow-offline - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{matrix.language}}" diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 446b3a6..28f79e9 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,7 +7,6 @@ "xaver.clang-format", "vadimcn.vscode-lldb", "matepek.vscode-catch2-test-adapter", - "sonarsource.sonarlint-vscode", "llvm-vs-code-extensions.vscode-clangd" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index eef5a32..54531f5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,14 +32,6 @@ "pattern": "${workspaceFolder}/cetlvast/build/suites/benchmark/**/benchmark_*" } ], - "sonarlint.pathToCompileCommands": "${workspaceFolder}/cetlvast/build/compile_commands.json", - "sonarlint.connectedMode.project": { - "connectionId": "opencyphal", - "projectKey": "OpenCyphal_CETL" - }, - "sonarlint.analyzerProperties": { - "sonar.cfamily.reportingCppStandardOverride": "c++14" - }, "cSpell.allowCompoundWords": true, "cSpell.caseSensitive": false, "cSpell.customDictionaries": { diff --git a/.vscode/words-cetl.txt b/.vscode/words-cetl.txt index 81c4e7e..2d0ffb7 100644 --- a/.vscode/words-cetl.txt +++ b/.vscode/words-cetl.txt @@ -33,7 +33,6 @@ NOLINT NOLINTBEGIN NOLINTEND NOLINTNEXTLINE -NOSONAR NOTFOUND opencyphal Pavel @@ -42,8 +41,6 @@ pushd rbegin regen rend -sonarcloud -sonarqube ssep STREQUAL subpage diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c612991..069ecf9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -130,11 +130,10 @@ Often, however, you will want to run it on your branch before proposing the chan green and test coverage is adequate - to do that: - either target your PR to any `issue/NN_LABEL` branch, where `NN` is the issue number and `LABEL` is a small title giving context (like `issue/83_any`) - or add a hashtag with the name of the workflow you need to run to the head commit; -for example, making a commit with a message like `Add feature such and such #verification #docs #sonar` -will force the CI to execute jobs named `verification`, `docs`, and `sonar`. +for example, making a commit with a message like `Add feature such and such #verification #docs` +will force the CI to execute jobs named `verification` and `docs`. -Note that if the job you requested is dependent on other jobs that are not triggered, it will not run; -for example, if `sonar` requires `docs`, pushing a commit with `#sonar` alone will not make it run. +Note that if the job you requested is dependent on other jobs that are not triggered, it will not run. # IDE-specific notes diff --git a/README.md b/README.md index b5fbde6..21f82f2 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,6 @@ Cyphal Embedded Template Library [![CETLVaSt](https://github.com/OpenCyphal/CETL/actions/workflows/cetlvast.yml/badge.svg)](https://github.com/OpenCyphal/CETL/actions/workflows/cetlvast.yml) [![Open Bugs](https://img.shields.io/github/issues/OpenCyphal/CETL/bug?label=bugs&logo=github)](https://github.com/OpenCyphal/CETL/issues?q=is%3Aopen+is%3Aissue+label%3Abug) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=OpenCyphal_CETL&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=OpenCyphal_CETL) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=OpenCyphal_CETL&metric=coverage)](https://sonarcloud.io/summary/new_code?id=OpenCyphal_CETL) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=OpenCyphal_CETL&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=OpenCyphal_CETL) - - ## include The include directory contains the CETL headers all within a folder, "cetl". Types found under "cetl/pfXX" folders and diff --git a/cetlvast/CMakeLists.txt b/cetlvast/CMakeLists.txt index d09c509..5d54323 100644 --- a/cetlvast/CMakeLists.txt +++ b/cetlvast/CMakeLists.txt @@ -229,10 +229,8 @@ add_custom_target( unittest DEPENDS run_unittests - $<$:gcovr_sonarqube_report_for_unittest> $<$:gcovr_html_report_for_unittest> run_examples - $<$:gcovr_sonarqube_report_for_examples> $<$:gcovr_html_report_for_examples> run_compile_precheck_tests ) diff --git a/cetlvast/CMakePresets.json b/cetlvast/CMakePresets.json index e9fc889..950d500 100644 --- a/cetlvast/CMakePresets.json +++ b/cetlvast/CMakePresets.json @@ -496,10 +496,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1710,10 +1708,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1724,10 +1720,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1738,10 +1732,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1752,10 +1744,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1766,10 +1756,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1780,10 +1768,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1794,10 +1780,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1808,10 +1792,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1822,10 +1804,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1836,10 +1816,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1850,10 +1828,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1864,10 +1840,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1878,10 +1852,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1892,10 +1864,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1906,10 +1876,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1920,10 +1888,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1934,10 +1900,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1948,10 +1912,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1962,10 +1924,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1976,10 +1936,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -1990,10 +1948,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -2004,10 +1960,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -2018,10 +1972,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -2032,10 +1984,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -2046,10 +1996,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, { @@ -2060,10 +2008,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] } ], @@ -2101,7 +2047,7 @@ { "name": "manual-coverage-gcc-native-cpp-14-offline", "displayName": "gcc native cpp 14 offline (Coverage only).", - "description": "Hand-managed workflow for generating coverage data for sonarqube scans.", + "description": "Hand-managed workflow for generating local coverage reports.", "steps": [ { "type": "configure", @@ -3023,10 +2969,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, "preset-groups": { diff --git a/cetlvast/CMakePresetsVendorTemplate.json b/cetlvast/CMakePresetsVendorTemplate.json index 8624d36..720a95c 100644 --- a/cetlvast/CMakePresetsVendorTemplate.json +++ b/cetlvast/CMakePresetsVendorTemplate.json @@ -36,10 +36,8 @@ "build", "run_unittests", "gcovr_html_report_for_unittest", - "gcovr_sonarqube_report_for_unittest", "run_examples", - "gcovr_html_report_for_examples", - "gcovr_sonarqube_report_for_examples" + "gcovr_html_report_for_examples" ] }, "preset-groups": { diff --git a/cetlvast/cmake/bin/test_report_util.py b/cetlvast/cmake/bin/test_report_util.py deleted file mode 100755 index cca98d9..0000000 --- a/cetlvast/cmake/bin/test_report_util.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) OpenCyphal Development Team -# Copyright Amazon.com Inc. or its affiliates. -# SPDX-License-Identifier: MIT -# -""" - Translate a JUnit XML report into the SonarQube generic test execution format. - - Googletest can generate a JUnit XML report, but SonarQube does not support this format. - Use this script to convert the JUnit XML report into the SonarQube generic test execution - format to allow test results to be recorded in SonarQube. -""" -# cSpell: words testsuite testsuites quirksmode levelname - -import argparse -import logging -import os -import pathlib -import sys -import typing -import xml.etree.ElementTree as ET - -# +---------------------------------------------------------------------------+ - -def _junit_to_sonarqube_generic_execution_format(junit_report: pathlib.Path, test_executions: ET.Element, base_dir: typing.Optional[pathlib.Path] = None) -> None: - """Append junit testsuite data to sonarqube testExecutions data. - - Input Format: http://google.github.io/googletest/advanced.html#generating-an-xml-report - Output Format: https://docs.sonarqube.org/8.9/analyzing-source-code/generic-test-data/#generic-execution - - """ - sq_files: typing.Dict[str, ET.Element] = dict() - junit_xml = ET.parse(junit_report) - - testsuite_or_testsuites = junit_xml.getroot() - - if testsuite_or_testsuites.tag == "testsuite": - testsuites: typing.Iterable[ET.Element] = [testsuite_or_testsuites] - else: - testsuites = testsuite_or_testsuites.findall("testsuite") - - for testsuite in testsuites: - logging.info("junit2sonarqube: parsing junit testsuite: {} name=\"{}\" tests=\"{}\"" - .format(testsuite.tag, - testsuite.get("name"), - testsuite.get("tests"))) - - for testcase in testsuite: - - testcase_file = testcase.get("file") - if testcase_file is not None: - quirksmode = "gtest" - else: - quirksmode = "ctest" - testcase_file = testcase.get("classname") - if testcase_file is None: - logging.warning("junit2sonarqube: Unknown tag {} (skipping)".format(testcase.tag)) - continue - - testcase_name: str = testcase.get("name", "") - if (type_param := testcase.get("type_param", None)) != None: - # mypy is not able to parse assignment expressions, apparently. - testcase_name = testcase_name + " " + type_param # type: ignore - - logging.debug("junit2sonarqube: found testcase \"{}\" (quirks={})".format(testcase_name, quirksmode)) - - try: - sq_file = sq_files[testcase_file] - except KeyError: - # Make path relative to base_dir if provided - file_path = testcase_file - if base_dir is not None: - try: - rel_path = os.path.relpath(testcase_file, base_dir) - file_path = rel_path - except ValueError: - file_path = testcase_file - sq_file = ET.Element("file", attrib={"path": file_path}) - test_executions.append(sq_file) - sq_files[testcase_file] = sq_file - - sq_testcase_attrib: typing.Dict[str, str] = dict() - sq_testcase_attrib["name"] = testcase_name - test_duration = float(testcase.get("time", 0.0)) - sq_testcase_attrib["duration"] = str(int(test_duration)) - - sq_test_case = ET.Element("testCase", attrib=sq_testcase_attrib) - sq_file.append(sq_test_case) - - skipped: typing.Optional[ET.Element] = testcase.find("skipped") - if skipped is not None: - sq_skipped = ET.Element("skipped", attrib={"message": skipped.get("message", "").rstrip()}) - sq_skipped.text = skipped.text.rstrip() # type: ignore - sq_test_case.append(sq_skipped) - failures = testcase.findall("failure") - if failures is not None and len(failures) > 0: - sq_failure = ET.Element("failure", attrib={"message": "failed"}) - sq_test_case.append(sq_failure) - sq_failure_text = [] - for failure in failures: - for failure_line in failure.get("message", "").split("\n"): - sq_failure_text.append(failure_line) - sq_failure.set("message", sq_failure_text[0]) - if len(sq_failure_text) > 1: - sq_failure.text = "\n".join(sq_failure_text[1:]) - - -# +---------------------------------------------------------------------------+ - - -def _make_parser() -> argparse.ArgumentParser: - - parser = argparse.ArgumentParser( - description="Utility to convert junit-style test reports into the SonarQube generic test execution format.", - ) - - parser.add_argument("-p", - "--pattern", - default="*.xml", - help="Pattern to match for test suites to run. (default: %(default)s)") - parser.add_argument("-v", - "--verbose", - action="count", - default=0, - help="Increase logging verbosity. (default: %(default)s)") - parser.add_argument("output", - type=pathlib.Path, - help="Output file to write the test report to. (default: %(default)s)") - parser.add_argument("--dry-run", - action="store_true", - help="Do not write the test report to disk.") - parser.add_argument("-s", - "--stop-on-failure", - action="store_true", - help="Stop on first test failure.") - parser.add_argument("-i", - "--input", - action="append", - help="Input files to convert.") - parser.add_argument("-b", - "--base-dir", - type=pathlib.Path, - help="Base directory to make file paths relative to.") - return parser - - -# +---------------------------------------------------------------------------+ - - -def append(test_report: pathlib.Path, sq_report: ET.Element, base_dir: typing.Optional[pathlib.Path] = None) -> int: - try: - _junit_to_sonarqube_generic_execution_format(test_report, sq_report, base_dir) - return 0 - except ET.ParseError as err: - logging.warning("Failed to parse report {}: {}".format(test_report, err)) - return 1 - - -# +---------------------------------------------------------------------------+ - - -def main() -> int: - """ - Main method to execute when this package/script is invoked as a command. - """ - args = _make_parser().parse_args() - - logging_level = logging.WARN - - if args.verbose == 2: - logging_level = logging.INFO - elif args.verbose >= 3: - logging_level = logging.DEBUG - - logging.basicConfig(format="%(levelname)s: %(message)s", level=logging_level) - - if args.input is None: - logging.error("No input files specified.") - return 1 - - test_executions = ET.Element("testExecutions", attrib={"version": "1"}) - sq_report = ET.ElementTree(test_executions) - - if args.pattern is not None: - for test_report in pathlib.Path.cwd().glob(args.pattern): - if test_report.suffix == ".xml": - logging.info("Found report {}. Trying to combine into sonarqube report.".format(test_report)) - if append(test_report, sq_report.getroot(), args.base_dir) != 0 and args.stop_on_failure: - return 1 - - for test_report in args.input: - if append(test_report, sq_report.getroot(), args.base_dir) != 0 and args.stop_on_failure: - return 1 - - if args.dry_run: - logging.info("Would have written a test report for {} files to {}".format(len(test_executions.findall("file")), args.output)) - else: - logging.debug("About to write a test report for {} files to {}".format(len(test_executions.findall("file")), args.output)) - # ET.indent(sq_report) Not available in Python 3.8 - with open(args.output, "wb") as sq_report_file: - sq_report.write(sq_report_file, encoding="UTF-8") - - return 0 - - -# +---------------------------------------------------------------------------+ - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/cetlvast/cmake/modules/FindTestReport.cmake b/cetlvast/cmake/modules/FindTestReport.cmake deleted file mode 100644 index 33b3aa7..0000000 --- a/cetlvast/cmake/modules/FindTestReport.cmake +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (C) OpenCyphal Development Team -# Copyright Amazon.com Inc. or its affiliates. -# SPDX-License-Identifier: MIT -# - -# -# XML converter for junit test reports. -# - - -set(LOCAL_BIN_MODULE_PATHS ${CMAKE_MODULE_PATH}) -list(TRANSFORM LOCAL_BIN_MODULE_PATHS APPEND "/../bin") - -find_file(LOCAL_TEST_REPORT_UTILITY test_report_util.py - PATHS ${LOCAL_BIN_MODULE_PATHS} -) - -if (NOT LOCAL_TEST_REPORT_UTILITY STREQUAL "LOCAL_TEST_REPORT_UTILITY-NOTFOUND") - set(LOCAL_TEST_REPORT_UTILITY_FOUND TRUE) -endif() - -include(FindPackageHandleStandardArgs) - -find_package_handle_standard_args(TestReport - REQUIRED_VARS LOCAL_TEST_REPORT_UTILITY_FOUND -) - -# -# :function: define_junit_to_sonarqube_conversion_rule -# The target will be the OUTPUT file which is generated from the provided set -# of SOURCE_FILES. -# -# :param SOURCE_FILES list[path] - A list of files to convert and combine. -# :param OUTPUT path - The output file to write to. -# -function(define_junit_to_sonarqube_conversion_rule) - #+-[input]----------------------------------------------------------------+ - set(options "") - set(singleValueArgs OUTPUT BASEDIR) - set(multiValueArgs SOURCE_FILES) - cmake_parse_arguments(PARSE_ARGV 0 ARG "${options}" "${singleValueArgs}" "${multiValueArgs}") - - #+-[body]-----------------------------------------------------------------+ - set(LOCAL_ARG_LIST) - if (ARG_BASEDIR) - list(APPEND LOCAL_ARG_LIST "--base-dir" ${ARG_BASEDIR}) - endif() - foreach(LOCAL_INPUT_FILE ${ARG_SOURCE_FILES}) - list(APPEND LOCAL_ARG_LIST "-i") - list(APPEND LOCAL_ARG_LIST ${LOCAL_INPUT_FILE}) - endforeach() - add_custom_command(OUTPUT ${ARG_OUTPUT} - COMMAND ${LOCAL_TEST_REPORT_UTILITY} - ${LOCAL_ARG_LIST} - ${ARG_OUTPUT} - DEPENDS ${ARG_SOURCE_FILES} - VERBATIM - ) - -endfunction(define_junit_to_sonarqube_conversion_rule) diff --git a/cetlvast/cmake/modules/Findgcovr.cmake b/cetlvast/cmake/modules/Findgcovr.cmake index f4a4941..8ca1741 100644 --- a/cetlvast/cmake/modules/Findgcovr.cmake +++ b/cetlvast/cmake/modules/Findgcovr.cmake @@ -226,7 +226,7 @@ endfunction(define_gcovr_tracefile_target) # for the current directory. Be sure to call this only after all calls to define_gcovr_tracefile_target # have been made. # -# param: COVERAGE_REPORT_FORMATS - Supports html or sonarqube +# param: COVERAGE_REPORT_FORMATS - Supports html # param: ROOT_DIRECTORY string - The root directory of the source to be covered. # param: OUT_REPORT_INDICES list[string] - The name of a variable to set to a list of index files of the reports. # @@ -264,10 +264,6 @@ function (enable_coverage_report) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gcovr_html") list(APPEND LOCAL_FORMAT_ARGS "--html-details") list(APPEND LOCAL_FORMAT_ARGS "${LOCAL_REPORT_INDEX}") - elseif (LOCAL_REPORT_FORMAT STREQUAL "sonarqube") - set(LOCAL_REPORT_INDEX "coverage.xml") - list(APPEND LOCAL_FORMAT_ARGS "--cobertura") - list(APPEND LOCAL_FORMAT_ARGS "${LOCAL_REPORT_INDEX}") else() message(FATAL_ERROR "${LOCAL_REPORT_FORMAT} is not a supported coverage report format.") endif() diff --git a/cetlvast/suites/docs/examples/CMakeLists.txt b/cetlvast/suites/docs/examples/CMakeLists.txt index 5ae4216..248501d 100644 --- a/cetlvast/suites/docs/examples/CMakeLists.txt +++ b/cetlvast/suites/docs/examples/CMakeLists.txt @@ -67,21 +67,16 @@ add_custom_target( ${ALL_EXAMPLES} ) -define_junit_to_sonarqube_conversion_rule( - SOURCE_FILES ${ALL_EXAMPLE_RUNS} - OUTPUT "examples-sonarqube.xml" -) - add_custom_target( run_examples DEPENDS - "examples-sonarqube.xml" + ${ALL_EXAMPLE_RUNS} ) set_directory_properties(PROPERTIES IN_BUILD_TESTS "${ALL_EXAMPLE_RUNS}" ) -enable_coverage_report(COVERAGE_REPORT_FORMATS sonarqube html +enable_coverage_report(COVERAGE_REPORT_FORMATS html ROOT_DIRECTORY ${CETL_ROOT} ) diff --git a/cetlvast/suites/unittest/CMakeLists.txt b/cetlvast/suites/unittest/CMakeLists.txt index 757bef0..705de35 100644 --- a/cetlvast/suites/unittest/CMakeLists.txt +++ b/cetlvast/suites/unittest/CMakeLists.txt @@ -8,7 +8,6 @@ cmake_minimum_required(VERSION 3.22.0) project(cetlvast_unittest CXX) find_package(googletest REQUIRED) -find_package(TestReport REQUIRED) find_package(o1heap REQUIRED) find_package(gcovr) @@ -175,36 +174,17 @@ add_custom_target( ${ALL_TESTS_BUILD} ) -define_junit_to_sonarqube_conversion_rule( - SOURCE_FILES ${ALL_TESTS_RUN} - OUTPUT "unittest-sonarqube.xml" -) - add_custom_target( run_unittests DEPENDS - "unittest-sonarqube.xml" + ${ALL_TESTS_RUN} ) set_directory_properties(PROPERTIES IN_BUILD_TESTS "${ALL_TESTS_RUN}" ) -enable_coverage_report(COVERAGE_REPORT_FORMATS html sonarqube +enable_coverage_report(COVERAGE_REPORT_FORMATS html ROOT_DIRECTORY ${CETL_ROOT} OUT_REPORT_INDICES LOCAL_COVERAGE_REPORT_INDICES ) - - -# +---------------------------------------------------------------------------+ -# | SONARQUBE -# +---------------------------------------------------------------------------+ -# we need to build at least one source file to get sonarqube to look at the cetl -# headers. -add_executable(cetlvast_sonar - "sonar.cpp" -) - -target_link_libraries(cetlvast_sonar - PRIVATE cetl -) diff --git a/cetlvast/suites/unittest/sonar.cpp b/cetlvast/suites/unittest/sonar.cpp deleted file mode 100644 index aa81222..0000000 --- a/cetlvast/suites/unittest/sonar.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/// @file -/// Hack to get sonarqube to analyze cetl headers. -/// -/// @copyright -/// Copyright (C) OpenCyphal Development Team -/// Copyright Amazon.com Inc. or its affiliates. -/// SPDX-License-Identifier: MIT -/// - -#include "cetl/cetl.hpp" -#include "cetl/rtti.hpp" -#include "cetl/type_traits_ext.hpp" -#include "cetl/unbounded_variant.hpp" -#include "cetl/variable_length_array.hpp" -#include "cetl/visit_helpers.hpp" -#include "cetl/pmr/buffer_memory_resource_delegate.hpp" -#include "cetl/pmr/function.hpp" -#include "cetl/pmr/interface_ptr.hpp" -#include "cetl/pmr/memory.hpp" -#include "cetl/pf17/array_memory_resource.hpp" -#include "cetl/pf17/buffer_memory_resource.hpp" -#include "cetl/pf17/byte.hpp" -#include "cetl/pf17/memory_resource.hpp" -#include "cetl/pf17/optional.hpp" -#include "cetl/pf17/string_view.hpp" -#include "cetl/pf17/type_traits.hpp" -#include "cetl/pf17/utility.hpp" -#include "cetl/pf17/variant.hpp" -#include "cetl/pf17/sys/memory_resource.hpp" -#include "cetl/pf20/span.hpp" - -int main() -{ - return 0; -} diff --git a/include/cetl/cetl.hpp b/include/cetl/cetl.hpp index 40961d6..81d1ed6 100644 --- a/include/cetl/cetl.hpp +++ b/include/cetl/cetl.hpp @@ -100,18 +100,18 @@ /// and minor version. A patch version number change will only occur if library source code is changed. /// Documentation or test suite changes will not require a change to `cetl/cetl.hpp` and will not bump /// the patch version. -#define CETL_VERSION_PATCH 0 // NOSONAR cpp:5028 +#define CETL_VERSION_PATCH 0 /// @def CETL_VERSION_MINOR /// CETL minor version. /// Minor versions shall only add to CETL or modify it in a backwards compatible way. -#define CETL_VERSION_MINOR 5 // NOSONAR cpp:5028 +#define CETL_VERSION_MINOR 5 /// @def CETL_VERSION_MAJOR /// CETL Major version. /// New major versions shall be rare. No overarching guarantees are made about compatibility /// between major versions. -#define CETL_VERSION_MAJOR 1 // NOSONAR cpp:5028 +#define CETL_VERSION_MAJOR 1 /// @} @@ -130,15 +130,15 @@ /// in production code is strongly discouraged. /// #if defined NDEBUG && defined CETL_ENABLE_DEBUG_ASSERT -# undef CETL_ENABLE_DEBUG_ASSERT // NOSONAR cpp:s959 +# undef CETL_ENABLE_DEBUG_ASSERT #endif -// Intentional violation of Sonar: the assertions check macro cannot be replaced with a function definition. +// Intentional deviation: the assertions check macro cannot be replaced with a function definition. #if defined CETL_ENABLE_DEBUG_ASSERT && CETL_ENABLE_DEBUG_ASSERT # include -# define CETL_DEBUG_ASSERT(c, m) assert(((void) (m), (c))) // NOSONAR cpp:S960 +# define CETL_DEBUG_ASSERT(c, m) assert(((void) (m), (c))) #else -# define CETL_DEBUG_ASSERT(c, m) ((void) (m)) // NOSONAR cpp:S960 +# define CETL_DEBUG_ASSERT(c, m) ((void) (m)) #endif // Make the standard exceptions available only if exceptions are enabled. @@ -167,7 +167,7 @@ /// #include /// #endif /// ``` -#define CETL_CPP_STANDARD_14 201402L // NOSONAR cpp:5028 +#define CETL_CPP_STANDARD_14 201402L /// @def CETL_CPP_STANDARD_17 /// Provides the proper value to test against `__cplusplus` for c++14. @@ -177,7 +177,7 @@ /// #include /// #endif /// ``` -#define CETL_CPP_STANDARD_17 201703L // NOSONAR cpp:5028 +#define CETL_CPP_STANDARD_17 201703L /// @def CETL_CPP_STANDARD_20 /// Provides the proper value to test against `__cplusplus` for c++14. @@ -188,7 +188,7 @@ /// #include /// #endif /// ``` -#define CETL_CPP_STANDARD_20 202002L // NOSONAR cpp:5028 +#define CETL_CPP_STANDARD_20 202002L /// @} diff --git a/include/cetl/pf17/optional.hpp b/include/cetl/pf17/optional.hpp index a9feafc..1dc3fd3 100644 --- a/include/cetl/pf17/optional.hpp +++ b/include/cetl/pf17/optional.hpp @@ -90,7 +90,7 @@ struct base_destruction { if (m_engaged) { - new (std::addressof(m_value)) T(std::forward(other).m_value); // NOSONAR cpp:S984 + new (std::addressof(m_value)) T(std::forward(other).m_value); } } void reset() noexcept diff --git a/include/cetl/pf17/string_view.hpp b/include/cetl/pf17/string_view.hpp index ce2ca61..a79bcc5 100644 --- a/include/cetl/pf17/string_view.hpp +++ b/include/cetl/pf17/string_view.hpp @@ -56,20 +56,20 @@ class basic_string_view /// Constructs a view of the null-terminated character string pointed to by s, not including the terminating null /// character. /// - /// No lint and Sonar cpp:S1709 b/c this is an intentional implicit conversion. + /// No lint b/c this is an intentional implicit conversion. /// /// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - basic_string_view(const CharT* const str) // NOSONAR cpp:S1709 + basic_string_view(const CharT* const str) : data_{str} , size_{traits_type::length(str)} { } - /// No lint and Sonar cpp:S1709 b/c this is an intentional implicit conversion. + /// No lint b/c this is an intentional implicit conversion. /// /// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) template - basic_string_view(const std::basic_string& str) // NOSONAR cpp:S1709 + basic_string_view(const std::basic_string& str) : data_{str.data()} , size_{str.size()} { diff --git a/include/cetl/pmr/o1heap_memory_resource_delegate.hpp b/include/cetl/pmr/o1heap_memory_resource_delegate.hpp index c7b799e..0d1e518 100644 --- a/include/cetl/pmr/o1heap_memory_resource_delegate.hpp +++ b/include/cetl/pmr/o1heap_memory_resource_delegate.hpp @@ -38,10 +38,10 @@ struct O1HeapAlignedStorage static_assert(O1HEAP_ALIGNMENT >= alignof(std::max_align_t), "O1HEAP_ALIGNMENT is too small for this platform."); - struct alignas(alignment) type // NOSONAR cpp:5945 + struct alignas(alignment) type { - unsigned char data[arena_size]; // NOSONAR cpp:3646 - } storage[1]; // NOSONAR cpp:3646 + unsigned char data[arena_size]; + } storage[1]; }; class UnsynchronizedO1HeapMemoryResourceDelegate diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index 8547a52..0000000 --- a/sonar-project.properties +++ /dev/null @@ -1,28 +0,0 @@ -# SonarQube project configuration for CETL -sonar.organization=opencyphal -sonar.projectKey=OpenCyphal_CETL -sonar.projectName=CETLVaSt -sonar.verbose=true - -# C/C++ specific settings -sonar.cfamily.compile-commands=cetlvast/build/compile_commands.json -sonar.cfamily.cobertura.reportPaths=cetlvast/build/suites/unittest/coverage.xml -sonar.cfamily.ignoreHeaderComments=false -sonar.cfamily.reportingCppStandardOverride=c++14 - -# Test execution reports -sonar.testExecutionReportPaths=cetlvast/build/suites/unittest/unittest-sonarqube.xml - -# Source and test directories -sonar.sources=include,cetlvast/suites/unittest/sonar.cpp -sonar.tests=cetlvast/suites/unittest -sonar.test.inclusions=**/test_*.cpp - -# Coverage and duplication exclusions -sonar.coverage.exclusions=cetlvast/**/*,**/sonar.cpp -sonar.cpd.exclusions=cetlvast/**/*,**/sonar.cpp - -# Rule exclusions -sonar.issue.ignore.multicriteria=e1 -sonar.issue.ignore.multicriteria.e1.ruleKey=cpp:S994,cpp:S799 -sonar.issue.ignore.multicriteria.e1.resourceKey=**/*