diff --git a/script/lint-ci.sh b/script/lint-ci.sh new file mode 100755 index 0000000..255ede4 --- /dev/null +++ b/script/lint-ci.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# Run all linters +# Depends: git + +# ------------------------------------------ + +# Get the full path to this script while handling spaces and symlinks correctly +scriptPath="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" +cd "$scriptPath/.." || exit 1 + +green=$(tput setf 2) +red=$(tput setf 4) +nc=$(tput sgr0) + +failures=0 + +linters=" +lint-shell-script.sh +" + +for linter in $linters; do + echo "Running script/$linter" + if "script/$linter"; then + echo "[${green}PASS${nc}]: script/$linter" + else + echo "[${red}FAIL${nc}]: script/$linter" + failures=$(( failures + 1 )) + fi +done + +# Get all files staged for commit +files="$(git diff --cached --name-only)" + +echo "Running script/lint-clang-format.sh" +# shellcheck disable=SC2086 +if script/lint-clang-format.sh && git diff --exit-code $files; then + echo "[${green}PASS${nc}]: script/lint-clang-format.sh" +else + echo "[${red}FAIL${nc}]: script/lint-clang-format.sh" + failures=$(( failures + 1 )) +fi + +exit "$failures" diff --git a/script/lint-clang-format.sh b/script/lint-clang-format.sh new file mode 100755 index 0000000..c77e212 --- /dev/null +++ b/script/lint-clang-format.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# Run clang-format across the codebase +# Depends: clang-format, git + +# ------------------------------------------ + +# Get the full path to this script while handling spaces and symlinks correctly +scriptPath="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" +cd "$scriptPath/.." || exit 1 + +formatter=false +if command -v clang-format-11 >/dev/null 2>&1; then + formatter="clang-format-11" +elif command -v clang-format >/dev/null 2>&1; then + formatter="clang-format" + if ! "$formatter" --version | awk '{ if (substr($NF, 1, index($NF, ".") - 1) < 11) exit 1; }'; then + echo "You are using '$("${CLANG_FORMAT}" --version)', which appears to not be clang-format 11 or later." + exit 1 + fi +else + echo "clang-format-11 is not available, but C++ files need linting!" + echo "Either skip this script, or install clang-format-11." + exit 1 +fi + +files=$(git ls-files -- '*.cpp' '*.h' ':!:inferno/vendor') + +if [ -z "$files" ]; then + echo "No .cpp or .h files to check." + exit +fi + +# shellcheck disable=SC2086 +"$formatter" --style=file -i $files diff --git a/script/lint-shell-script.sh b/script/lint-shell-script.sh new file mode 100755 index 0000000..2780f60 --- /dev/null +++ b/script/lint-shell-script.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# Run shellcheck across the codebase +# Depends: git, shellcheck + +# ------------------------------------------ + +# Get the full path to this script while handling spaces and symlinks correctly +scriptPath="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" +cd "$scriptPath/.." || exit 1 + +if ! command -v shellcheck > /dev/null 2>&1; then + echo "shellcheck is not available, but shell script files need linting!" + echo "Either skip this script, or install shellcheck." + exit 1 +fi + +files=$(git ls-files -- '*.sh' ':!:inferno/vendor') + +if [ -z "$files" ]; then + echo "No .sh files to check." + exit +fi + +# shellcheck disable=SC2086 +shellcheck $files diff --git a/script/pre-commit.sh b/script/pre-commit.sh new file mode 100755 index 0000000..18e0b44 --- /dev/null +++ b/script/pre-commit.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# Manage pre-commit hooks in .git/hooks +# Depends: - + +# ------------------------------------------ + +scriptName="$(basename "$0")" + +help() { + b=$(tput bold) + u=$(tput smul) + nc=$(tput sgr0) + + cat << EOF +${b}NAME${nc} + ${scriptName} - manage pre-commit hooks + +${b}SYNOPSIS${nc} + ${b}${scriptName}${nc} ${u}COMMAND${nc} + +${b}COMMANDS${nc} + ${b}install${nc} + Install all pre-commit hooks. + + ${b}remove${nc} + Remove all pre-commit hooks. +EOF +} + +# Exit if no option is provided +[ "$#" -eq 0 ] && help && exit 1 + +# Get the full path to this script while handling spaces and symlinks correctly +scriptPath="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" +cd "$scriptPath/.." || exit 1 + +hooks=" +lint-ci.sh +" + +install() { + echo "Installing pre-commit hooks" + + preCommit=".git/hooks/pre-commit" + if ! test -f "$preCommit"; then + touch "$preCommit" + chmod +x "$preCommit" + echo "#!/bin/sh" > "$preCommit" + fi + + for hook in $hooks; do + sed -Ei "/$hook/d" "$preCommit" + sed -Ei "\$ a script/$hook" "$preCommit" + done +} + +remove() { + echo "Removing pre-commit hooks" + + preCommit=".git/hooks/pre-commit" + for hook in $hooks; do + sed -Ei "/$hook/d" "$preCommit" + done +} + +# Command handling +shift $((OPTIND - 1)) +case "$1" in + install | remove) + "$1" + ;; + *) + echo "$scriptName: invalid command '$1'" + echo "Try '$scriptName -h' for more information." + exit 1 + ;; +esac