From c146d37f05dbc74c49251a27012b574b2f53d963 Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Mon, 3 Feb 2025 10:19:27 +0100 Subject: [PATCH] chore: improve pre-commit hook (add extra checks) --- .bin/pre-commit/check-all.sh | 53 +++++++++++++++++++ .bin/pre-commit/check-format.sh | 5 ++ .bin/pre-commit/check-lint.sh | 5 ++ .../pre-commit/check-makefile-file-listing.sh | 44 +++++++++++++++ .bin/pre-commit/extract-extra-dist.sh | 30 +++++++++++ .bin/pre-commit/pre-commit.sh | 4 ++ .../remove-nexus.sh} | 0 Makefile.am | 6 +++ 8 files changed, 147 insertions(+) create mode 100755 .bin/pre-commit/check-all.sh create mode 100755 .bin/pre-commit/check-format.sh create mode 100755 .bin/pre-commit/check-lint.sh create mode 100755 .bin/pre-commit/check-makefile-file-listing.sh create mode 100755 .bin/pre-commit/extract-extra-dist.sh create mode 100755 .bin/pre-commit/pre-commit.sh rename .bin/{pre-commit.sh => pre-commit/remove-nexus.sh} (100%) diff --git a/.bin/pre-commit/check-all.sh b/.bin/pre-commit/check-all.sh new file mode 100755 index 00000000..6b408d61 --- /dev/null +++ b/.bin/pre-commit/check-all.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# Check definition. Multiline string, every line is for one check. +# Format of line is: +# `Check title ./path/relative/to/this/script/check-script.sh`. +# The last space separates title from script path. +check_list=" +BIOME LINT CHECK ./check-lint.sh +BIOME FORMAT CHECK ./check-format.sh +MAKEFILE FILE LISTING CHECK ./check-makefile-file-listing.sh +" + +extract_title() { + echo "$1" | awk '{$NF=""; print $0}' +} + +extract_command() { + realpath "$(dirname "$0")"/"$(echo "$1" | awk '{print $NF}')" +} + +err_report="" +while IFS= read -r line; do + [ -n "$line" ] || continue + + check=$(extract_command "$line") + + if ! output=$("$check" 2>&1); then + err_report="${err_report}$(extract_title "$line") ($check)\n$output\n\n" + fi +done << EOF +$check_list +EOF + +if [ -z "$err_report" ]; then + exit 0 +fi + +echo "Warning: some check failed" +printf "%b" "$err_report" + +printf "Checks failed. Continue with commit? (c)Continue (a)Abort: " > /dev/tty +IFS= read -r resolution < /dev/tty + +case "$resolution" in + c | C) exit 0 ;; + a | A) + echo "Commit aborted." + exit 1 + ;; +esac + +echo "Unknown resolution '$resolution', aborting commit..." +exit 1 diff --git a/.bin/pre-commit/check-format.sh b/.bin/pre-commit/check-format.sh new file mode 100755 index 00000000..67a19741 --- /dev/null +++ b/.bin/pre-commit/check-format.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +root_dir="$(realpath "$(dirname "$0")"/../../)" + +npx @biomejs/biome format "$root_dir" diff --git a/.bin/pre-commit/check-lint.sh b/.bin/pre-commit/check-lint.sh new file mode 100755 index 00000000..414befe5 --- /dev/null +++ b/.bin/pre-commit/check-lint.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +root_dir="$(realpath "$(dirname "$0")"/../../)" + +npx @biomejs/biome lint --error-on-warnings "$root_dir" diff --git a/.bin/pre-commit/check-makefile-file-listing.sh b/.bin/pre-commit/check-makefile-file-listing.sh new file mode 100755 index 00000000..d4adc862 --- /dev/null +++ b/.bin/pre-commit/check-makefile-file-listing.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +makefile_list="\ +Makefile.am +packages/app/Makefile.am +packages/test/Makefile.am +" + +get_mentioned_files() { + for makefile in $1; do + [ -n "$makefile" ] || continue + "$(dirname "$0")"/extract-extra-dist.sh "$makefile" + done +} + +get_unlisted_files() { + makefiles=$1 + added_files=$2 + + mentioned_files=$(get_mentioned_files "$makefiles") + + for file in $added_files; do + if ! echo "$mentioned_files" | + grep --quiet --fixed-strings --line-regexp "$file" 2> /dev/null; then + echo "$file" + fi + done +} + +git_added="$(git diff --cached --name-only --diff-filter=A)" + +if [ -z "$git_added" ]; then + exit 0 +fi + +unlisted_files="$(get_unlisted_files "$makefile_list" "$git_added")" + +if [ -z "$unlisted_files" ]; then + exit 0 +fi + +echo "Warning: The following files are not listed in any Makefile.am:" +echo "$unlisted_files" +exit 1 diff --git a/.bin/pre-commit/extract-extra-dist.sh b/.bin/pre-commit/extract-extra-dist.sh new file mode 100755 index 00000000..16608e72 --- /dev/null +++ b/.bin/pre-commit/extract-extra-dist.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +makefile="$1" +inside_extra_dist=0 +files="" + +while IFS= read -r line; do + case "$line" in + *EXTRA_DIST[[:space:]]*=*) + inside_extra_dist=1 + files="${line#*=}" + files="${files%\\}" + ;; + *\\) + [ $inside_extra_dist -eq 1 ] && files="$files ${line%\\}" + ;; + *) # the last line in EXTRA_DIST + [ $inside_extra_dist -eq 1 ] && files="$files $line" && break + ;; + esac +done < "$makefile" + +# no globing +set -f +# split to arguments +# shellcheck disable=2086 +set -- $files +for file in "$@"; do + printf "%s\n" "${makefile%Makefile.am}$file" +done diff --git a/.bin/pre-commit/pre-commit.sh b/.bin/pre-commit/pre-commit.sh new file mode 100755 index 00000000..22a57d45 --- /dev/null +++ b/.bin/pre-commit/pre-commit.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +./.bin/pre-commit/remove-nexus.sh +./.bin/pre-commit/check-all.sh diff --git a/.bin/pre-commit.sh b/.bin/pre-commit/remove-nexus.sh similarity index 100% rename from .bin/pre-commit.sh rename to .bin/pre-commit/remove-nexus.sh diff --git a/Makefile.am b/Makefile.am index 8ceb00c8..d940a3fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,6 +26,12 @@ EXTRA_DIST = \ .bin/init_nexus.sh \ .bin/init.sh \ .bin/npm_install.sh \ + .bin/pre-commit/extract-extra-dist.sh \ + .bin/pre-commit/check-all.sh \ + .bin/pre-commit/check-format.sh \ + .bin/pre-commit/check-lint.sh \ + .bin/pre-commit/check-makefile-file-listing.sh \ + .bin/pre-commit/remove-nexus.sh \ .bin/pre-commit.sh \ .bin/render-spec.sh \ .browserslistrc \