diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..930d78ff --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 +--- +Checks: "*, \ + -abseil-*, \ + -cert-env33-c, \ + -cert-err58-cpp, \ + -clang-diagnostic-padded, \ + -clang-analyzer-deadcode.DeadStores, \ + -cppcoreguidelines-avoid-magic-numbers, \ + -cppcoreguidelines-pro-bounds-constant-array-index, \ + -cppcoreguidelines-pro-bounds-pointer-arithmetic, \ + -cppcoreguidelines-pro-type-reinterpret-cast, \ + -cppcoreguidelines-no-malloc, \ + -cppcoreguidelines-owning-memory, \ + -cppcoreguidelines-macro-usage, \ + -cppcoreguidelines-pro-type-vararg, \ + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, \ + -fuchsia-overloaded-operator, \ + -fuchsia-default-arguments, \ + -fuchsia-multiple-inheritance, \ + -fuchsia-default-arguments-calls, \ + -fuchsia-trailing-return, \ + -fuchsia-default-arguments-declarations, \ + -fuchsia-statically-constructed-objects, \ + -google-runtime-references, \ + -google-runtime-int, \ + -google-explicit-constructor, \ + -hicpp-no-malloc, \ + -hicpp-vararg, \ + -hicpp-invalid-access-moved, \ + -hicpp-no-array-decay, \ + -hicpp-signed-bitwise, \ + -llvm-header-guard, \ + -modernize-use-trailing-return-type, \ + -misc-definitions-in-headers, \ + -misc-unused-alias-decls, \ + -modernize-concat-nested-namespaces, \ + -modernize-raw-string-literal, \ + -readability-magic-numbers" +HeaderFilterRegex: "" +... \ No newline at end of file diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index c1b14dac..aaf345f3 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -7,9 +7,22 @@ on: branches: [main] jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Check License Header + uses: apache/skywalking-eyes/header@0.4.0 + with: + header: + license: + spdx-id: Apache-2.0 + - name: Check CMake files + run: find . \( -name '*.cmake' -o -name 'CMakeLists.txt' \) -exec cmake-format $* {} + + - name: Clan-tidy + run: python3 ./scripts/run-clang-tidy.py "." "build" "third_party,scripts,docker,cmake_modules" "h,hpp,cc,cpp" build: runs-on: ubuntu-latest - + steps: - uses: actions/checkout@v3 with: diff --git a/scripts/run-clang-tidy.py b/scripts/run-clang-tidy.py new file mode 100644 index 00000000..600721d9 --- /dev/null +++ b/scripts/run-clang-tidy.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: Apache-2.0 + +# Run clang-tidy recursively and parallel on directory +# Usage: run-clang-tidy sourcedir builddir excludedirs extensions +# extensions and excludedirs are specified as comma-separated +# string without dot, e.g. 'c,cpp' +# e.g. run-clang-tidy . build test,other c,cpp file + +import os, sys, subprocess, multiprocessing +manager = multiprocessing.Manager() +failedfiles = manager.list() + +# Get absolute current path and remove trailing seperators +currentdir = os.path.realpath(os.getcwd()).rstrip(os.sep) +print("Arguments: " + str(sys.argv)) +# Get absolute source dir after removing leading and trailing seperators from input. +sourcedir = currentdir + sys.argv[1].lstrip(os.sep).rstrip(os.sep) +print("Source directory: " + sourcedir) +builddir = sourcedir + os.sep + sys.argv[2].rstrip(os.sep) +print("Build directory: " + builddir) +# If exclude dirs is not empty, split it into a tuple +excludedirs = () +if sys.argv[3]: + excludedirs = tuple([(sourcedir + os.sep + s).rstrip(os.sep) for s in sys.argv[3].split(',')]) +# If the build directory is not the same as the source directory, exclude it +if not sourcedir == builddir: + excludedirs = excludedirs + (builddir,) +print("Exclude directories: " + str(excludedirs)) +# Split extensions into a tuple +extensions = tuple([("." + s) for s in sys.argv[4].split(',')]) +print("Extensions: " + str(extensions)) + +def runclangtidy(filepath): + print("Checking: " + filepath) + proc = subprocess.Popen("clang-tidy --quiet -p=" + builddir + " " + filepath, shell=True) + if proc.wait() != 0: + failedfiles.append(filepath) + +def collectfiles(dir, exclude, exts): + collectedfiles = [] + for root, dirs, files in os.walk(dir): + for file in files: + filepath = root + os.sep + file + if (len(exclude) == 0 or not filepath.startswith(exclude)) and filepath.endswith(exts): + collectedfiles.append(filepath) + return collectedfiles + +# Define the pool AFTER the global variables and subprocess function because WTF python +# See: https://stackoverflow.com/questions/41385708/multiprocessing-example-giving-attributeerror +pool = multiprocessing.Pool() +pool.map(runclangtidy, collectfiles(sourcedir, excludedirs, extensions)) +pool.close() +pool.join() +if len(failedfiles) > 0: + print("Errors in " + len(failedfiles) + " files") + sys.exit(1) +print("No errors found") +sys.exit(0) \ No newline at end of file diff --git a/scripts/setup-ubuntu.sh b/scripts/setup-ubuntu.sh index 16e74f7c..3bf5f5cc 100755 --- a/scripts/setup-ubuntu.sh +++ b/scripts/setup-ubuntu.sh @@ -18,6 +18,7 @@ sudo --preserve-env apt install -y \ cmake \ ccache \ ninja-build \ + clang-tidy \ checkinstall \ git \ wget \