Skip to content

Commit

Permalink
ci: Use CodeChecker as static analysis tool
Browse files Browse the repository at this point in the history
CodeChecker combines multiple static code analysis tools including
`clang-sa`. It also provides the possibility to check against a baseline
to report only newly introduced issues.
Moreover it is simpler to use.
It could eventually replace `clang-sa` completely in the pipeline.
  • Loading branch information
LukasWoodtli committed Nov 14, 2024
1 parent e2ce38b commit a0cf35f
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 2 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/codechecker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Clang Static Analyzer

on: [push, pull_request]

jobs:
clang_static_analyzer:
runs-on: ubuntu-24.04

steps:
- name: Checkout code including full history and submodules
uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- name: Install CodeChecker
run: |
sudo apt-get update
sudo apt-get install clang-tools-18 cmake cppcheck libcunit1-dev ninja-build unzip wget
pip3 install codechecker
- name: Run CodeChecker
run: |
run: tools/ci/run_ci.sh --run-build --run-code-checker --code-checker diff
- name: Upload CodeChecker reports
uses: actions/upload-artifact@v1
with:
name: CodeChecker Reports
path: build-wakaama/codechecker_report
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ Wakaama provides a simple CLI library. It can be enabled with:
- Unit testing: CUnit

On Ubuntu 20.04, used in CI, the dependencies can be installed as such:
- `apt install build-essential clang-format clang-format-14 clang-tools-14 cmake gcovr git libcunit1-dev ninja-build python3-pip`
- `apt install build-essential clang-format clang-format-14 clang-tools-14 cmake cppcheck gcovr git libcunit1-dev ninja-build python3-pip`
- `pip3 install -r tools/requirements-compliance.txt`

For macOS the development dependencies can be installed as such:

`brew install automake clang-format cmake cunit gcc gitlint gnu-getopt make ninja`
`brew install automake clang-format cmake cppcheck cunit gcc gitlint gnu-getopt make ninja`

### Code formatting
#### C
Expand Down
28 changes: 28 additions & 0 deletions doc/code_checker.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Static Code analysis with CodeChecker

Wakaama uses [`CodeChecker`](https://codechecker.readthedocs.io/) for static code analysis.

It's possible to run `CodeChecker` in two different modes: `full` and `diff`

In `full` mode all found issues are reported. In `diff` mode only new issues are shown.

The `diff` mode compares found issues with a 'base line' and shows only newly found issues.

## Running `CodeChecker`

The `CodeChecker` is run as part of the CI GitHub Actions. But it can be run manually:

To show new issues:
```
tools/ci/run_ci.sh --run-build --run-code-checker --code-checker diff
```

To show *all* issues:
```
tools/ci/run_ci.sh --run-build --run-code-checker --code-checker full
```

Create new 'base line':
```
tools/ci/run_ci.sh --run-build --run-code-checker --code-checker baseline
```
69 changes: 69 additions & 0 deletions tools/ci/run_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ OPT_SONARQUBE=""
OPT_SOURCE_DIRECTORY="${REPO_ROOT_DIR}"
OPT_BUILD_DIRECTORY="build-wakaama"
OPT_TEST_COVERAGE_REPORT=""
OPT_CODE_CHECKER="full"
OPT_VERBOSE=0
OPT_WRAPPER_CMD=""
RUN_BUILD=0
Expand All @@ -41,6 +42,7 @@ RUN_GITLINT=0
RUN_GIT_BLAME_IGNORE=0
RUN_TESTS=0
RUN_DOXYGEN=0
RUN_CODE_CHECKER=0

HELP_MSG="usage: ${SCRIPT_NAME} <OPTIONS>...
Runs build and test steps in CI.
Expand Down Expand Up @@ -72,6 +74,9 @@ Options:
(WRAPPER: path to build-wrapper)
--test-coverage REPORT Enable code coverage measurement, output REPORT
(REPORT: xml html text none)
--code-checker ACTION Run the CodeChecker code analyzer to create a baseline,
do a full check or a PR check (show just difference to baseline)
(TYPE: full, diff, baseline)
-v, --verbose Verbose output
-a, --all Run all steps required for a MR
-h, --help Display this help and exit
Expand All @@ -85,6 +90,7 @@ Available steps (executed by --all):
--run-build Build all targets
--run-tests Execute tests (works only for top level project)
--run-doxygen Build the Doxygen documentation of the code
--run-code-checker Run the CodeChecker code analyzer
"

function usage() {
Expand Down Expand Up @@ -228,6 +234,43 @@ function run_doxygen() {
GIT_REVISION=$(git rev-parse @) WORKING_DIR=$(pwd) DOXYGEN_OUT_DIR=build-wakaama/doxygen \
doxygen doc/doxygen/Doxyfile
}

function run_code_checker() {
readonly config_file="${REPO_ROOT_DIR}/tools/code_checker/config.json"
readonly ignore_file="${REPO_ROOT_DIR}/tools/code_checker/ignore.txt"
readonly baseline_file="${REPO_ROOT_DIR}/tools/code_checker/reports.baseline"
readonly code_checker_result_dir="build-wakaama/code_checker_result/"
readonly code_checker_report="build-wakaama/code_checker_report/"

CodeChecker check --logfile build-wakaama/compile_commands.json \
--config "$config_file" \
--ignore "$ignore_file" \
--output $code_checker_result_dir \
|| true # Currently failing with found issues


if [ "${OPT_CODE_CHECKER}" = "diff" ]; then
CodeChecker cmd diff -b "$baseline_file" \
-n $code_checker_result_dir \
--new
else
if [ "${OPT_CODE_CHECKER}" = "baseline" ]; then
output_format="baseline"
output_location="$baseline_file"
else
output_format="html"
output_location="$code_checker_report"
fi

CodeChecker parse -e "$output_format" \
-o "$output_location" \
--config "$config_file" \
--ignore "$ignore_file" \
--trim-path-prefix="${REPO_ROOT_DIR}" \
"$code_checker_result_dir"
fi
}

# Parse Options

if [[ "$OSTYPE" == "darwin"* ]]; then
Expand Down Expand Up @@ -259,12 +302,14 @@ if ! PARSED_OPTS=$($getopt -o vah \
-l run-git-blame-ignore \
-l run-tests \
-l run-doxygen \
-l run-code-checker \
-l sanitizer: \
-l scan-build: \
-l sonarqube: \
-l source-directory: \
-l build-directory: \
-l test-coverage: \
-l code-checker: \
-l verbose \
--name "${SCRIPT_NAME}" -- "$@");
then
Expand Down Expand Up @@ -327,6 +372,12 @@ while true; do
RUN_DOXYGEN=1
shift
;;
--run-code-checker)
RUN_CODE_CHECKER=1
# Analyzing works only when code gets actually built
RUN_CLEAN=1
shift
;;
--sanitizer)
OPT_SANITIZER=$2
shift 2
Expand Down Expand Up @@ -355,6 +406,10 @@ while true; do
OPT_TEST_COVERAGE_REPORT=$2
shift 2
;;
--code-checker)
OPT_CODE_CHECKER=$2
shift 2
;;
--)
shift
break
Expand Down Expand Up @@ -410,6 +465,11 @@ if [ -n "${OPT_SCAN_BUILD}" ] && [ -n "${OPT_SONARQUBE}" ]; then
exit 1
fi

if [ "${RUN_CODE_CHECKER}" = "1" ] && [ -n "${OPT_SONARQUBE}" ]; then
echo "--sonarqube and --code-checker can not be enabled at the same time"
exit 1
fi

if [ -n "${OPT_SONARQUBE}" ]; then
OPT_TEST_COVERAGE_REPORT="${OPT_TEST_COVERAGE_REPORT:-none}"
OPT_WRAPPER_CMD="${OPT_SONARQUBE} \
Expand All @@ -430,6 +490,10 @@ if [ -n "${OPT_SCAN_BUILD}" ]; then
--exclude examples/shared/tinydtls"
fi

if [ "${RUN_CODE_CHECKER}" = "1" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug"
fi

# Run Steps

if [ "${RUN_GITLINT}" -eq 1 ]; then
Expand Down Expand Up @@ -463,3 +527,8 @@ fi
if [ "${RUN_DOXYGEN}" -eq 1 ]; then
run_doxygen
fi

if [ "${RUN_CODE_CHECKER}" = "1" ]; then
run_code_checker
fi

12 changes: 12 additions & 0 deletions tools/code_checker/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"analyze": [
"--disable=cplusplus",
"--disable=cppcheck-exceptDeallocThrow",
"--disable=cppcheck-exceptThrowInDestructor",
"--disable=cppcheck-leakUnsafeArgAlloc",
"--disable=cppcheck-rethrowNoCurrentException",
"--disable=cppcheck-thisSubtraction",
"--disable=cppcheck-throwInNoexceptFunction",
"--clean"
]
}
2 changes: 2 additions & 0 deletions tools/code_checker/ignore.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-*/examples/shared/tinydtls/*
-*/tests/*
30 changes: 30 additions & 0 deletions tools/code_checker/reports.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
044f5b0eff4745c2bf6364813afd33ed
0ea7931b69e8b3234c564f1c2d97f2e3
1d23d25836c787b32f1e2a64bc4ceed0
1ea9912faf6e4f215ad5a6d25ecfc03c
26048fdcff9c36d589077b346f71e33e
2c54e9cc5a9990f3117bbd259578b516
33f934a71b0c12292a083efd2adabae9
3bef48a5f28f0375149d867be4030080
45df5602f4966deb9b705703b3753e0f
4ba84444bec0ad2c1a3cba7fc7b0c3cf
60caf3b05164653289c877317425738a
6bd4c519d9e63f4a53451f429e10152c
6cfd057ffacc065fc770c622a2801f0b
7bcc83d8b030eac413624485f514009c
7e8dcf5879ee7613d0f2f88e0965a290
980102c730b942fde3d5d200dd25b7a9
9a834ddd93d8270abe7e78b95ab11a11
a7bc6b73d1f9731b3a8f04be1b38f08b
a88646fb05690e1bf9d276146e382ce9
b51ace258f9a9331a53701858f2cb6a3
be24877e5af3c3d3308a586aa6f6707d
c964129b59f0e66d6b41d688931d6787
cc1891f9815f83294fce7f6bc888bcdc
d3e2a589356bb70b9a30f970b2db06f8
dc553bb37462545017cf8d6c8d7fe833
dea66b9a29663430abdde592542f1b6b
e363b18b83d5b78d9317b8af69cee913
e4997fe34bc4c71cf912721907a2cd4a
eab1cfe928d38fd5c590c9662b18f46a
ee8ba227407ff351d78e4c2acbbd03ab

0 comments on commit a0cf35f

Please sign in to comment.