Commit a41e87b2 authored by David Frank's avatar David Frank Committed by Tobias Lasser
Browse files

Improve output style of CI scripts, use clang-format --dry-run

The clang-format test script now relies on clang-format's (now) in-build
functionality to check for wrong formatting instead of actually
performing or committing the formated changes and then reverting them.
From a perceived behaviour standpoint nothing has changed, it should now
only be more convenient to use the script, as it doesn't require a
clean git state anymore.

Further, all formatting and linting scripts run only on the changed
files rather than on the whole codebase. Plus they have some nicer
looking output :^)
parent 5d7b95cc
Pipeline #524819 passed with stages
in 34 minutes and 14 seconds
repos:
- repo: local
hooks:
- id: clang-format-ci
name: Check if C++-like files are formatted such that CI will be happy
entry: bash tools/ci_scripts/clang-format-test.sh
stages: [ commit ]
language: system
- id: doxygen-tag-lint-ci
name: Check that Doxygen tags use the @ instead of \, such that CI will be happy
entry: bash tools/ci_scripts/check-comment-style.sh
stages: [ commit ]
language: system
- id: cmake-lint-ci
name: Check linting for CMake files, such that CI will be happy
entry: bash tools/ci_scripts/cmake-lint-test.sh
stages: [ commit ]
language: system
- id: lint-commit
name: Lint commit message to ensure commit messages are nicely formatted
entry: bash tools/ci_scripts/commit-msg-test.sh
stages: [ commit-msg ]
language: system
......@@ -115,3 +115,12 @@ make test_coverage
```
and then the results should be available at `build/test_coverage/index.html`. You can compare your
local results to [the latest master coverage results](https://ciip.in.tum.de/elsacoverage/).
## pre-commit
There is also a basic `.pre-commit-config.yaml` file to install pre-commit hooks using
[pre-commit](https://pre-commit.com/). You are highly encouraged to install the pre-commits
with `pre-commit install` such that they are run before each commit.
None of the commit hooks will change anything in your commit, they mearly check and error if
something is wrong.
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Retrieve list of cpp-files that were changed in source branch with respect to master (target branch)
target_branch="master"
filelist=($(git diff origin/${target_branch} --name-only | egrep ".+\.(h|cpp|hpp|cu|cuh)"))
filelist=($(git diff origin/${target_branch} --name-only | egrep ".+\.(h|hpp|cuh)"))
if [[ "${#filelist[@]}" -eq "0" ]]; then
echo "--> No relevant files changed compared to $target_branch branch, all good!"
echo -e "[${GREEN}OK${NC}]: No C++-like headers to check"
exit 0
else
echo "--> Found ${#filelist[@]} relevant files, which changed compared to $target_branch branch"
fi
# This list is obviously incomplete but should be fine for now and at least help us a little bit!
# This should have very few false negatives and I prefer that.
grepoutput=$(grep --color=always -re '\s\* \\\(brief\|author\|param\|tparam\|warning\|return\|returns\|file\|throw\)\(\[[a-z]\+\]\)\?\s\+' elsa/)
if [[ $(printf "%s" "$grepoutput" | wc -l) -gt 0 ]]; then
echo -e "\e[33mWarning:\e[0m Found files that use backslash instead of at for doxygen tags"
echo "--> Replace for a single file: \`sed -i -e 's/\\\\<tok>/@<tok>/g' file\`"
echo "--> Replace all with 'find elsa -type f \( -iname \*.h -o -iname \*.cpp -o -iname \*.hpp -o -iname \*.cuh -o -iname \*.cu \) \\
if [[ $grepoutput ]] || [[ $(printf "%s" "$grepoutput" | wc -l) -gt 0 ]]; then
echo -e "[${RED}FAIL${NC}]: Found files that use backslash instead of at for doxygen tags"
echo "$grepoutput"
echo ""
echo -e "[${BLUE}INFO${NC}]: Replace for a single file: \`sed -i -e 's/\\\\<tok>/@<tok>/g' file\`"
echo -e "[${BLUE}INFO${NC}]: Replace all with 'find elsa -type f \( -iname \*.h -o -iname \*.cpp -o -iname \*.hpp -o -iname \*.cuh -o -iname \*.cu \) \\
-exec sed -i -e 's/\\\\brief/@brief/g' -e 's/\\\\author/@author/g' \\
-e 's/\\\\param/@param/g' -e 's/\\\\tparam/@tparam/g' -e 's/\\\\warning/@warning/g' \\
-e 's/\\\\return/@return/g' -e 's/\\\\returns/@returns/g' -e 's/\\\\file/@file/g' \\
-e 's/\\\\throw/@throw/g' {} \\;'"
echo "--> or 'fd -e h -e cpp -e cu -e cuh -x sed -i -e 's/\\\\brief/@brief/g' \\
echo -e "[${BLUE}INFO${NC}]: or 'fd -e h -e cpp -e cu -e cuh -x sed -i -e 's/\\\\brief/@brief/g' \\
-e 's/\\\\author/@author/g' -e 's/\\\\param/@param/g' -e 's/\\\\tparam/@tparam/g' \\
-e 's/\\\\warning/@warning/g' -e 's/\\\\return/@return/g' -e 's/\\\\returns/@returns/g' \\
-e 's/\\\\file/@file/g' -e 's/\\\\throw/@throw/g''"
echo -e "--> \e[33mBe aware that this can also be a false negative\e[0m"
echo ""
echo "Problematic places:"
echo "$grepoutput"
echo ""
echo "Please check the above, if there are any doxygen tags you can replace"
echo -e "[${ORANGE}WARNING${NC}]: Be aware that this can also be a false negative"
exit 1
else
echo -e "\e[32mEverything is perfect!\e[0m"
echo -e "[${GREEN}OK${NC}]: Excellent. All tags use the correct styling"
fi
#!/bin/bash
# Format all C++-like files with clang-format
# Determine the applied differences with git,
# Check for all C++-like files if they need formatting. Only consider files, which
# are different from master. clang-format version 10 is required
# return 1 when changes had to be made, so the CI step fails.
# set exit on error
set -e
# check that we are in a clean state in order to prevent accidential changes
git status --untracked-files=no
if [ ! -z "$(git status --untracked-files=no --porcelain)" ]; then
echo "Script must be applied on a clean git state"
exit 1
fi
echo
RED='\033[0;31m'
BLUE='\033[0;34m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# preference list
clang_format_tool_candiates=(clang-format-10 clang-format)
for candidate in ${clang_format_tool_candiates[@]}; do
if command -v "$candidate" >/dev/null; then
echo "Formatting check with $candidate --version:"
$candidate --version
clang_format_tool=$candidate
break
clang_format_version=10
clang_format_tool_candiates=(clang-format-$clang_format_version clang-format)
# files=("${(@f)$(git ls-files -- '*.cpp')}")
files=($(git diff origin/master --name-only | egrep ".+\.(h|hpp|cpp|cu|cuh)$"))
if (( ${#files[@]} )); then
clang_format_tool=false
# Check all possible candidates
for candidate in ${clang_format_tool_candiates[@]}; do
if command -v "$candidate" >/dev/null 2>&1 && "$candidate" --version | grep -qF ' 10.'; then
clang_format_tool=$candidate
break
fi
done
# Check that it's really set
if [ $clang_format_tool = false ]; then
echo -e "[${RED}FAIL${NC}]: clang-format-10 is not available, but C++ files need linting! Please install clang-format-10."
exit 1
fi
done
if [[ -z "$clang_format_tool" ]]; then
echo "$clang_format_tool not correctly installed"
exit 1
fi
echo
# run clang-format
format_call="find elsa/ benchmarks/ examples/ -regextype egrep -regex '.+\.(h|hpp|cpp|cu|cuh)$' | xargs $clang_format_tool -i -style=file"
eval "$format_call"
# check if something was modified
notcorrectlist=`git status --porcelain | grep '^ M' | cut -c4-`
# if nothing changed ok
if [[ -z $notcorrectlist ]]; then
echo "Excellent. You passed the formatting check!"
exit 0;
echo -e "[${BLUE}INFO${NC}]: Formatting check with: `$clang_format_tool --version`"
echo -e "[${BLUE}INFO${NC}]: Running '$clang_format_tool --dry-run -Werror -style=file' on files..."
# Dry run clang-format with -Werror set
if ! "$clang_format_tool" --dry-run -Werror -style=file "${files[@]}"; then
echo -e "[${RED}FAIL${NC}]: Ups, something isn't correct with the formatting, please check above errors"
echo -e "[${BLUE}INFO${NC}]: From the root directory you can also run:"
echo "find elsa/ benchmarks/ examples/ | egrep \".+\.(h|hpp|cpp|cu|cuh)$\" | xargs $clang_format_tool -style=file"
exit 1
else
echo "The following files have clang-format problems:"
git diff --stat $notcorrectlist
echo "Inside the repo, please run"
echo
echo "$format_call"
echo
echo "to solve the issue."
# cleanup changes in git
git reset HEAD --hard
echo -e "[${GREEN}OK${NC}]: Excellent. Formatting check passed"
fi
else
echo -e "[${GREEN}OK${NC}]: No C++-like files to check"
fi
exit 1
......@@ -3,47 +3,35 @@
# Format all CMake-like files with cmake-format
# Determine the applied differences with git,
# return 1 when changes had to be made, so the CI step fails.
# set exit on error
set -e
# preference list
cmake_lint_tool_candiates=(cmake-lint)
for candidate in ${cmake_lint_tool_candiates[@]}; do
if command -v "$candidate" >/dev/null; then
echo "Linting check with $candidate --version:"
$candidate --version
cmake_lint_tool=$candidate
break
fi
done
if [[ -z "$cmake_lint_tool" ]]; then
echo "$cmake_lint_tool not correctly installed"
exit 1
fi
echo
# run cmake-lint
lint_call="find elsa benchmarks examples tools cmake -name '*.cmake' -o -name 'CMakeLists.txt' | xargs $cmake_lint_tool -l error"
exit_code=0
eval $lint_call || exit_code=$?
# if exit code 0, all is good
if [[ $exit_code -eq 0 ]]; then
echo "Excellent. You passed the linting check!"
exit 0;
else
echo
echo "The above files have cmake-lint problems"
echo "Inside the repo, please run"
echo
echo "$lint_call"
echo
echo "to see the issue. Please check the output"
fi
exit 1
RED='\033[0;31m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
files=($(git diff origin/master --name-only | egrep ".+(CMakeLists.txt|\.cmake(\.in)?)$"))
if (( ${#files[@]} )); then
cmake_lint_tool=false
if command -v "cmake-lint" >/dev/null 2>&1; then
cmake_lint_tool=cmake-lint
else
echo -e "[${RED}FAIL${NC}]: cmake-lint is not available, but CMake files need linting! Please install cmake-format"
exit 1
fi
echo -e "[${BLUE}INFO${NC}]: Formatting check with: `$cmake_lint_tool --version`"
echo -e "[${BLUE}INFO${NC}]: Running '$cmake_lint_tool -l error' on files..."
if ! "$cmake_lint_tool" -l error "${files[@]}"; then
echo -e "[${RED}FAIL${NC}]: Ups, something isn't correct with the formatting, please check above errors"
echo -e "[${BLUE}INFO${NC}]: From the root directory you can also run:"
echo "find elsa benchmarks examples tools cmake -name '*.cmake' -o -name 'CMakeLists.txt' | xargs $cmake_lint_tool -l error"
exit 1
else
echo -e "[${GREEN}OK${NC}]: Excellent. Formatting check passed"
fi
else
echo -e "[${GREEN}OK${NC}]: No CMake files to check"
fi
#!/usr/bin/env bash
# Small script to check that the commit message follows some clean formatting
# The following checks are in place:
# * Line length max 72 characters
# * Empty line after commit title
# * Commit title doesn't end with a period
# The script expects the Commit message file as the first (and only) argument.
# This script is adapted from https://github.com/SerenityOS/serenity/blob/master/Meta/lint-commit.sh
# by the GitHub user IdanHo as part of the SerenityOS project.
RED='\033[0;31m'
NC='\033[0m' # No Color
if [ -z "$1" ]; then
echo -e "[${RED}FAIL${NC}]: Pass commit message file as first argument";
exit 1
fi
# the file containing the commit message is passed as the first argument
commit_file="$1"
commit_message=$(cat "$commit_file")
error() {
echo -e "[${RED}FAIL${NC}]: $1";
echo "$commit_message"
exit 1
}
# fail if the commit message contains windows style line breaks (carriage returns)
if grep -q -U $'\x0D' "$commit_file"; then
error "Commit message contains CRLF line breaks (only unix-style LF linebreaks are allowed)"
fi
commentchar=$(git config --get core.commentChar)
re="^$commentchar -* >[0-9] -*\$"
line_number=0
while read -r line; do
# Somehow I need to make sure to not run till the diff...
[[ "$line" =~ $re ]] && break
# ignore comment lines
[[ "$line" =~ ^$commentchar.* ]] && continue
((line_number += 1))
line_length=${#line}
if [[ $line_number -eq 1 ]] && [[ "$line" =~ \.$ ]]; then
error "Commit title ends in a period"
fi
if [[ $line_number -eq 2 ]] && [[ "$line" ]]; then
error "The line after the commit message header should be empty"
fi
if [[ $line_length -gt 72 ]]; then
error "Commit message lines are too long (maximum allowed is 72 characters)"
fi
done <"$commit_file"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment