From 2eb84d9ef7397e3aa0299aadc0bd0d918e08e231 Mon Sep 17 00:00:00 2001
From: Alberto Nidasio <alberto.nidasio@skywarder.eu>
Date: Sun, 2 Oct 2022 09:28:15 +0200
Subject: [PATCH] [SBS][Linter] Updated cppcheck and copyright output
---
sbs | 140 +++++++++++++++++++++++-----------------------
scripts/linter.py | 94 +++++++++++++++----------------
2 files changed, 116 insertions(+), 118 deletions(-)
diff --git a/sbs b/sbs
index 5dce172a4..5cecc767b 100755
--- a/sbs
+++ b/sbs
@@ -52,7 +52,7 @@ init_dirs() {
find_deps() {
ohai "Find dependencies"
-
+
command -v cmake > /dev/null 2>&1 && found_cmake=true
command -v arm-miosix-eabi-g++ > /dev/null 2>&1 && found_miosixgpp=true
command -v ccache > /dev/null 2>&1 && found_ccache=true
@@ -63,7 +63,7 @@ find_deps() {
command -v clang-format > /dev/null 2>&1 && found_clangformat=true
command -v st-flash > /dev/null 2>&1 && found_stflash=true
command -v ST-LINK_CLI.exe > /dev/null 2>&1 && found_stlink=true
-
+
printf "Found CMake: "; [ "$found_cmake" = true ] && echo "yes" || echo "no"
printf "Found arm-miosix-eabi-g++: "; [ "$found_miosixgpp" = true ] && echo "yes" || echo "no"
printf "Found Ccache: "; [ "$found_ccache" = true ] && echo "yes" || echo "no"
@@ -73,8 +73,8 @@ find_deps() {
printf "Found clang-tidy: "; [ "$found_clangtidy" = true ] && echo "yes" || echo "no"
printf "Found clang-format: "; [ "$found_clangformat" = true ] && echo "yes" || echo "no"
printf "Found flasher: "; [ "$found_stflash" = true ] && echo "st-flash" \
- || { [ "$found_stlink" = true ] && echo "st-link" || echo "no"; }
-
+ || { [ "$found_stlink" = true ] && echo "st-link" || echo "no"; }
+
[ "$found_cmake" = true ] || { echo "Error: CMake must be installed"; return 1; }
[ "$found_miosixgpp" = true ] || { echo "Error: arm-miosix-eabi-g++ must be installed"; return 1; }
}
@@ -83,51 +83,51 @@ find_deps() {
# See: https://gitlab.kitware.com/cmake/cmake/-/issues/20212
cmake_disable_excluded_tests() {
declare build_dir="$1"
-
+
[ ! -f "$build_dir/$CTEST_FILENAME" ] || sed -i.bak 's/^subdirs/# subdirs/' "$build_dir/$CTEST_FILENAME"
}
configure() {
declare build_dir="$1"
-
+
ohai "Configure"
-
+
[ -f "$toolchain_file" ] || { echo "Error: CMake Toolchain File for Miosix was not found"; return 1; }
-
+
declare -a defs=(-DCMAKE_EXPORT_COMPILE_COMMANDS=ON)
defs+=(-DCMAKE_C_FLAGS=-fdiagnostics-color=always -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always)
[ "$config_host" = false ] && defs+=(-DCMAKE_TOOLCHAIN_FILE="$toolchain_file" -DBUILD_TESTING=OFF)
[ "$found_ccache" = true ] && defs+=(-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache)
[ "$config_debug" = true ] && defs+=(-DCMAKE_BUILD_TYPE=Debug) || defs+=(-DCMAKE_BUILD_TYPE=Release)
[ "$config_verbose" = true ] && defs+=(-DCMAKE_VERBOSE_MAKEFILE=ON)
-
+
declare gen
[ "$found_ninja" = true ] && gen=-GNinja || gen=-G"Unix Makefiles"
-
+
cmake -B"$build_dir" "${defs[@]}" "$gen" "$source_dir" || return
-
+
{ [ "$config_debug" = true ] && touch "$build_dir/$DEBUG_FILENAME"; } || rm -f "$build_dir/$DEBUG_FILENAME"
{ [ "$config_verbose" = true ] && touch "$build_dir/$VERBOSE_FILENAME"; } || rm -f "$build_dir/$VERBOSE_FILENAME"
}
check_configured() {
declare build_dir="$1"
-
+
declare to_reconfigure=false
if [ ! -d "$build_dir" ]; then
to_reconfigure=true
- elif [ ! -f "$build_dir/$CMAKE_FILENAME" ]; then
+ elif [ ! -f "$build_dir/$CMAKE_FILENAME" ]; then
rm -rf "$build_dir"
to_reconfigure=true
else
[ -f "$build_dir/$DEBUG_FILENAME" ] && found_debug=true || found_debug=false
[ -f "$build_dir/$VERBOSE_FILENAME" ] && found_verbose=true || found_verbose=false
if [ "$config_debug" != "$found_debug" ] \
- || [ "$config_verbose" != "$found_verbose" ]; then
+ || [ "$config_verbose" != "$found_verbose" ]; then
to_reconfigure=true
fi
fi
-
+
if [ "$to_reconfigure" = true ]; then
configure "$build_dir"
fi
@@ -136,36 +136,36 @@ check_configured() {
build() {
declare build_dir="$1"
declare target="$2"
-
+
check_configured "$build_dir" || return
-
+
ohai "Build"
-
+
declare -a opts
get_build_opts opts
-
+
cmake --build "$build_dir" "${opts[@]}" --target "$target"
}
build_all() {
declare build_dir="$build_default_dir"
-
+
build "$build_dir" all
}
clean() {
declare build_desc="$1"
declare build_dir="$2"
-
+
ohai "Clean ($build_desc)"
-
+
if [ -f "$build_dir/$CMAKE_FILENAME" ]; then
declare -a opts
get_build_opts opts
-
+
cmake --build "$build_dir" "${opts[@]}" --target clean
fi
-
+
echo "Removing build folder..."
rm -rf "$build_dir"
}
@@ -178,16 +178,16 @@ clean_all() {
flash() {
declare target="$1"
declare build_dir="$build_default_dir"
-
+
build "$build_dir" "$target" || return
-
+
ohai "Flash"
-
+
[ -f "$build_dir/$target.bin" ] || { echo "Error: target '$target' is not flashable"; return 1; }
-
+
if [ "$found_stflash" = true ]; then
st-flash --reset write "$build_dir/$target.bin" 0x8000000
- elif [ "$found_stlink" = true ]; then
+ elif [ "$found_stlink" = true ]; then
ST-LINK_CLI.exe -P "$build_dir/$target.bin" 0x8000000 -V -Rst
else
echo "Error: No flashing software found!"
@@ -198,120 +198,120 @@ flash() {
run_tests() {
declare target="$1"
declare build_dir="$build_host_dir"
-
+
config_host=true
-
+
build "$build_dir" "$target" || return
-
+
ohai "Test"
-
+
cmake_disable_excluded_tests "$build_dir"
( cd "$build_dir" || return; ctest )
}
list() {
declare build_dir="$build_default_dir"
-
+
check_configured "$build_dir" || return
-
+
ohai "List targets"
-
+
declare -a opts
get_build_opts opts
-
+
echo "[1/1] All SBS targets available:"
cmake --build "$build_dir" "${opts[@]}" --target help \
- | grep -o '^[^/]*\.bin' | cut -f 1 -d '.'
+ | grep -o '^[^/]*\.bin' | cut -f 1 -d '.'
}
boards() {
declare build_dir="$build_default_dir"
-
+
check_configured "$build_dir" || return
-
+
ohai "List boards"
-
+
declare -a opts
get_build_opts opts
-
+
cmake --build "$build_dir" "${opts[@]}" --target help-boards
}
lint_copyright() {
ohai "Lint (Copyright)"
-
+
"$sbs_base/scripts/linter.py" --copyright "$source_dir/src"
}
lint_find() {
ohai "Lint (Find)"
-
+
"$sbs_base/scripts/linter.py" --find "$source_dir/src"
}
lint_clangtidy() {
declare build_dir="$1"
-
+
check_configured "$build_dir" || return
-
+
ohai "Lint (clang-tidy)"
-
+
defs=(--extra-arg=-D_MIOSIX=1 --extra-arg=-D_MIOSIX_GCC_PATCH_MINOR=1 \
- --extra-arg=-D_MIOSIX_GCC_PATCH_MAJOR=3 --extra-arg=-D__LINT__)
+ --extra-arg=-D_MIOSIX_GCC_PATCH_MAJOR=3 --extra-arg=-D__LINT__)
IFS=$'\n' read -rd '' -a incs < \
- <(arm-miosix-eabi-g++ -E -Wp,-v -xc++ /dev/null 2>&1 \
- | sed -n "s/^ /--extra-arg=-isystem/p")
-
+ <(arm-miosix-eabi-g++ -E -Wp,-v -xc++ /dev/null 2>&1 \
+ | sed -n "s/^ /--extra-arg=-isystem/p")
+
declare opts=()
[ "$to_edit" = true ] && opts+=(--fix-notes --fix-errors)
-
+
find "$source_dir/src" \
- -type f \( -iname "*.cpp" -o -iname "*.h" -o -iname "*.c" \) \
- -exec clang-tidy --header-filter=".*" -p="$build_dir" "${defs[@]}" \
- "${incs[@]}" "${opts[@]}" {} \;
+ -type f \( -iname "*.cpp" -o -iname "*.h" -o -iname "*.c" \) \
+ -exec clang-tidy --header-filter=".*" -p="$build_dir" "${defs[@]}" \
+ "${incs[@]}" "${opts[@]}" {} \;
}
lint_cppcheck() {
ohai "Lint (Cppcheck)"
-
+
declare -a opts=()
[ -n "$jobs" ] && opts+=("-j $jobs")
-
- cppcheck --language=c++ --std=c++11 --enable=all --inline-suppr \
- --suppress=unmatchedSuppression --suppress=unusedFunction \
- --suppress=missingInclude --error-exitcode=1 "${opts[@]}" \
- "$source_dir/src"
+
+ cppcheck --language=c++ --std=c++14 --enable=all --inline-suppr \
+ --suppress=unmatchedSuppression --suppress=unusedFunction \
+ --suppress=missingInclude --error-exitcode=1 -q "${opts[@]}" \
+ "$source_dir/src"
}
lint_clangformat() {
declare to_edit="$1"
-
+
ohai "Lint (clang-format)"
-
+
declare -a opts=(--style=file --Werror)
[ "$to_edit" = true ] && opts+=(-i) || opts+=(--dry-run)
-
+
find "$source_dir/src" \
- -type f \( -iname "*.cpp" -o -iname "*.h" -o -iname "*.c" \) \
- -exec clang-format "${opts[@]}" {} \;
+ -type f \( -iname "*.cpp" -o -iname "*.h" -o -iname "*.c" \) \
+ -exec clang-format "${opts[@]}" {} \;
}
lint() {
declare to_edit="$1"
-
+
if [ "$found_python" = true ]; then
lint_copyright
lint_find
fi
-
+
if [ "$found_clangtidy" = true ] && [ "$lint_clangtidy" = true ]; then
lint_clangtidy "$build_default_dir"
fi
-
+
if [ "$found_cppcheck" = true ]; then
lint_cppcheck
fi
-
+
if [ "$found_clangformat" = true ]; then
lint_clangformat "$to_edit"
fi
diff --git a/scripts/linter.py b/scripts/linter.py
index 4b2e80586..bbc7b2835 100755
--- a/scripts/linter.py
+++ b/scripts/linter.py
@@ -92,10 +92,6 @@ def print_banner():
print('+------------------------------+')
-def linter_print(*strings):
- print('[linter]', *strings)
-
-
class Colors():
BLACK = '\033[30m'
RED = '\033[31m'
@@ -111,7 +107,7 @@ class Colors():
# Checks for the right copyright notice in all .h and .cpp files
def check_copyright(directory):
- linter_print(Colors.GREEN + 'Copyright check' + Colors.RESET)
+ print(Colors.GREEN + 'Copyright check' + Colors.RESET)
# Statistics
totalCheckdFilesCounter = 0
@@ -134,7 +130,7 @@ def check_copyright(directory):
filesWithErrorsCounter += 1
# The file's copyright notice does not match the template!
- linter_print(Colors.YELLOW + 'Wrong copyright notice in file {0}'.format(
+ print(Colors.YELLOW + 'Wrong copyright notice in file {0}'.format(
currentFilepath) + Colors.RESET)
else:
fileAuthors = [a.strip()
@@ -142,10 +138,10 @@ def check_copyright(directory):
# Check the number of authors against 'Author' or `Authors`
if len(fileAuthors) == 1 and match.group(1)[-1] == 's':
- linter_print('\'Authors\' should to be changed to \'Author\' in {0}'.format(
+ print('\'Authors\' should to be changed to \'Author\' in {0}'.format(
currentFilepath))
if len(fileAuthors) > 1 and match.group(1)[-1] != 's':
- linter_print('\'Author\' should to be changed to \'Authors\' in {0}'.format(
+ print('\'Author\' should to be changed to \'Authors\' in {0}'.format(
currentFilepath))
# Save statistics on authors
@@ -157,28 +153,29 @@ def check_copyright(directory):
averageAuthorsPerFile += len(fileAuthors)
averageAuthorsPerFile /= totalCheckdFilesCounter
- linter_print('Checked {} files'.format(totalCheckdFilesCounter))
+ print('Checked {} files'.format(totalCheckdFilesCounter))
if filesWithErrorsCounter == 0:
- linter_print('All the files have the correct copyright notice')
+ print('All the files have the correct copyright notice')
else:
- linter_print(Colors.RED + '{:.1f}% ({}/{}) of all analyzed files do not match with the copyright template!'.format(
+ print(Colors.RED + '{:.1f}% ({}/{}) of all analyzed files do not match with the copyright template!'.format(
100*filesWithErrorsCounter/totalCheckdFilesCounter, filesWithErrorsCounter, totalCheckdFilesCounter) + Colors.RESET)
- if(not args.quiet):
- linter_print('{:.2} authors per file'.format(
+ if (not args.quiet):
+ print('{:.2} authors per file'.format(
averageAuthorsPerFile))
- linter_print('Number of mentions per author:')
- for author in authors:
- linter_print('{:3} - {}'.format(authors[author], author))
+
+ print('Number of mentions per author:')
+ for author in sorted(authors.items(), key=lambda item: item[1], reverse=True):
+ print('{:3} - {}'.format(author[1], author[0]))
# Exit if error if at least one file isn't correct
- if(filesWithErrorsCounter > 0):
+ if (filesWithErrorsCounter > 0):
exit(-1)
# Checks if all .h and .cpp files respects the clang format specified in .clang-format file
def check_format(directory):
- linter_print(Colors.GREEN + 'Formatting check' + Colors.RESET)
+ print(Colors.GREEN + 'Formatting check' + Colors.RESET)
# Statistics
totalCheckdFilesCounter = 0
@@ -197,27 +194,27 @@ def check_format(directory):
['clang-format', '-style=file', '--dry-run', '--Werror', '--ferror-limit=1', currentFilepath], stderr=DEVNULL)
# If and error occurs warn the user
- if(returnCode != 0):
+ if (returnCode != 0):
filesWithErrorsCounter += 1
- if(not args.quiet):
- linter_print(Colors.YELLOW + 'Wrong code format for file {1}'.format(
+ if (not args.quiet):
+ print(Colors.YELLOW + 'Wrong code format for file {1}'.format(
returnCode, currentFilepath) + Colors.RESET)
- linter_print('Checked {} files'.format(totalCheckdFilesCounter))
+ print('Checked {} files'.format(totalCheckdFilesCounter))
if filesWithErrorsCounter == 0:
- linter_print('All the files match the Skyward formatting style')
+ print('All the files match the Skyward formatting style')
else:
- linter_print(Colors.RED + '{:4.1f}% ({}/{}) of all analyzed files do not match Skyward formatting style!'.format(
+ print(Colors.RED + '{:4.1f}% ({}/{}) of all analyzed files do not match Skyward formatting style!'.format(
100*filesWithErrorsCounter/totalCheckdFilesCounter, filesWithErrorsCounter, totalCheckdFilesCounter), Colors.RESET)
# Exit if error if at least one file isn't correct
- if(filesWithErrorsCounter > 0):
+ if (filesWithErrorsCounter > 0):
exit(-1)
def find_in_code(directory, searchTerm, extensionFilters=('.cpp', '.h'), pathFilter=None):
- linter_print(
+ print(
Colors.GREEN + 'Checking for \'{}\' in code files'.format(searchTerm) + Colors.RESET)
# Statistics
@@ -243,16 +240,16 @@ def find_in_code(directory, searchTerm, extensionFilters=('.cpp', '.h'), pathFil
filesWithErrorsCounter += 1
# The current file has the error
- if(not args.quiet):
- linter_print(Colors.YELLOW + 'Found \'{}\' in file {}'.format(searchTerm,
- currentFilepath) + Colors.RESET)
+ if (not args.quiet):
+ print(Colors.YELLOW + 'Found \'{}\' in file {}'.format(searchTerm,
+ currentFilepath) + Colors.RESET)
- linter_print('Checked {} files'.format(totalCheckdFilesCounter))
+ print('Checked {} files'.format(totalCheckdFilesCounter))
if filesWithErrorsCounter == 0:
- linter_print(
+ print(
'All the files does not contain \'{}\''.format(searchTerm))
else:
- linter_print(Colors.RED + '{:.1f}% ({}/{}) of all analyzed files contain \'{}\'!'.format(
+ print(Colors.RED + '{:.1f}% ({}/{}) of all analyzed files contain \'{}\'!'.format(
100*filesWithErrorsCounter/totalCheckdFilesCounter, filesWithErrorsCounter, totalCheckdFilesCounter, searchTerm) + Colors.RESET)
return filesWithErrorsCounter
@@ -260,7 +257,8 @@ def find_in_code(directory, searchTerm, extensionFilters=('.cpp', '.h'), pathFil
def check_find(directory):
sum = find_in_code(directory, r'^using namespace', '.h')
- sum += find_in_code(directory, r'[^a-zA-Z0-9]printf\(', pathFilter='shared')
+ sum += find_in_code(directory,
+ r'[^a-zA-Z0-9]printf\(', pathFilter='shared')
sum += find_in_code(directory, r'( |^)assert\(')
sum += find_in_code(directory, '^ *throw ', pathFilter='catch')
@@ -269,7 +267,7 @@ def check_find(directory):
def check_cppcheck(directory):
- linter_print(Colors.GREEN + 'cppcheck' + Colors.RESET)
+ print(Colors.GREEN + 'cppcheck' + Colors.RESET)
# Run cppcheck on the directory
try:
result = check_output(['cppcheck', '-q', '--language=c++', '--template=gcc', '--std=c++11', '--enable=all', '--inline-suppr',
@@ -280,21 +278,21 @@ def check_cppcheck(directory):
errors = re.findall(r'\[(\w+)\]', result.decode('utf-8'))
errors = Counter(errors)
- if(not args.quiet):
- linter_print('cppcheck found the following errors:')
+ if (not args.quiet):
+ print('cppcheck found the following errors:')
for error in errors:
- linter_print('{:3} - {}'.format(errors[error], error))
+ print('{:3} - {}'.format(errors[error], error))
totalErrors = sum(errors.values())
- if(totalErrors > 0):
- linter_print(
+ if (totalErrors > 0):
+ print(
Colors.RED + 'cppcheck found {} errors in total'.format(totalErrors) + Colors.RESET)
exit(-1)
else:
- linter_print('cppcheck did not find any errors')
+ print('cppcheck did not find any errors')
except CalledProcessError as e:
- linter_print(e.output.decode('utf-8'))
+ print(e.output.decode('utf-8'))
exit(-1)
# -------------------------------------------------------------
@@ -305,26 +303,26 @@ def check_cppcheck(directory):
parser = config_cmd_parser()
args = parser.parse_args()
-if(not args.directory):
- linter_print('No directory specified')
+if (not args.directory):
+ print('No directory specified')
print('')
parser.print_help()
exit(-1)
-if(args.copyright):
+if (args.copyright):
check_copyright(args.directory)
-if(args.format):
+if (args.format):
check_format(args.directory)
-if(args.cppcheck):
+if (args.cppcheck):
check_cppcheck(args.directory)
-if(args.find):
+if (args.find):
check_find(args.directory)
# Checks everything if no option is specified
-if(not args.copyright and not args.format and not args.find and not args.cppcheck):
+if (not args.copyright and not args.format and not args.find and not args.cppcheck):
check_copyright(args.directory)
check_format(args.directory)
check_find(args.directory)
--
GitLab