| #!/usr/bin/env bash |
| # Copyright 2021 The Verible Authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| set -u |
| TMPDIR="${TMPDIR:-/tmp}" |
| |
| readonly PARALLEL_COUNT=$(nproc) |
| readonly FILES_PER_INVOCATION=5 |
| |
| readonly CLANG_TIDY_SEEN_CACHE=${TMPDIR}/clang-tidy-hashes.cache |
| touch ${CLANG_TIDY_SEEN_CACHE} # Just in case it is not there yet |
| |
| readonly FILES_TO_PROCESS=${TMPDIR}/clang-tidy-files.list |
| readonly TIDY_OUT=${TMPDIR}/clang-tidy-verible.out |
| |
| # Use clang-tidy-11 if available as it still checks for |
| # google-runtime-references, non-const references - which is the |
| # preferred style in this project. |
| # If not, increase version until we find some that is available. |
| # (from old to new, as newer ones might have warnings not yet |
| # anticipated in the clang-tidy configuration). |
| CLANG_TIDY=clang-tidy |
| for version in 11 12 13 14 ; do |
| if command -v clang-tidy-${version}; then |
| CLANG_TIDY=clang-tidy-${version} |
| break |
| fi |
| done |
| hash ${CLANG_TIDY} || exit 2 # make sure it is installed. |
| |
| echo ::group::Build compilation database |
| |
| time $(dirname $0)/make-compilation-db.sh |
| |
| readonly EXEC_ROOT=$(bazel info execution_root) |
| |
| # The compdb doesn't include tests currently, so we exclude all test files |
| # for now. |
| # Also, exclude kythe for now, as it is somehwat noisy and should be |
| # addressed separately. |
| # |
| # We create a hash of each file content to only have to look at new files. |
| # (TODO: could the tidy result be different if an include content changes ? |
| # Then we have to do g++ -E (using compilation database knowing about -I etc.) |
| # or combine hashes of all mentioned #includes that are also in our list) |
| # Make need to re-run file dependent on clang-tidy configuration, WORKSPACE |
| # and of course file content. |
| for f in $(find . -name "*.cc" -and -not -name "*test*.cc" \ |
| -or -name "*.h" -and -not -name "*test*.h" \ |
| | grep -v "verilog/tools/kythe" \ |
| | grep -v "verilog/tools/ls/vscode" \ |
| ) ; do |
| (echo $CLANG_TIDY ; cat .clang-tidy WORKSPACE $f) | md5sum | sed "s|-|$f|g" |
| done | sort > ${CLANG_TIDY_SEEN_CACHE}.new |
| |
| join -v2 ${CLANG_TIDY_SEEN_CACHE} ${CLANG_TIDY_SEEN_CACHE}.new \ |
| | awk '{print $2}' | sort > ${FILES_TO_PROCESS} |
| |
| echo "::group::$(wc -l < ${FILES_TO_PROCESS}) files to process" |
| cat ${FILES_TO_PROCESS} |
| echo "::endgroup::" |
| |
| if [ -s ${FILES_TO_PROCESS} ]; then |
| echo "::group::Run ${PARALLEL_COUNT} parallel invocations of ${CLANG_TIDY} in chunks of ${FILES_PER_INVOCATION} files." |
| |
| cat ${FILES_TO_PROCESS} \ |
| | xargs -P${PARALLEL_COUNT} -n ${FILES_PER_INVOCATION} -- \ |
| ${CLANG_TIDY} --quiet 2>/dev/null \ |
| | sed "s|$EXEC_ROOT/||g" > ${TIDY_OUT} |
| |
| cat ${TIDY_OUT} |
| echo "::endgroup::" |
| |
| echo ::group::Summary |
| sed 's|\(.*\)\(\[[a-zA-Z.-]*\]$\)|\2|p;d' < ${TIDY_OUT} | sort | uniq -c | sort -n |
| |
| echo "::endgroup::" |
| |
| if [ -s ${TIDY_OUT} ]; then |
| echo "::error::There were clang-tidy warnings. Please fix" |
| exit 1 |
| fi |
| else |
| echo "Skipping clang-tidy run: nothing to do" |
| fi |
| |
| # No complaints. We can cache this list now as baseline for next time. |
| cp ${CLANG_TIDY_SEEN_CACHE}.new ${CLANG_TIDY_SEEN_CACHE} |
| |
| echo "No clang-tidy complaints.😎" |
| exit 0 |