Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: improve pre-commit hook #265

Merged
merged 2 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ test FEATURE='':
cargo test --features {{FEATURE}}
fi

fmt:
@just format
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an alias for just format, so you can also do just fmt


format:
cargo fmt --all
find . -type f -iname "*.toml" -print0 | xargs -0 taplo format
Expand Down
54 changes: 54 additions & 0 deletions scripts/hooks/commit-msg.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
export PATH=$PATH:/usr/local/bin

#
# White Whale contracts commit hook, used to make sure commits follow the conventional commits format.
# See more at https://www.conventionalcommits.org/
#
# Install the hook with the --install option.
#

project_toplevel=$(git rev-parse --show-toplevel)
git_directory=$(git rev-parse --git-dir)

install_hook() {
mkdir -p "$git_directory/hooks"
ln -sfv "$project_toplevel/scripts/hooks/commit-msg.sh" "$git_directory/hooks/commit-msg"
}

if [ "$1" = "--install" ]; then
if [ -f "$git_directory/hooks/commit-msg" ]; then
read -r -p "There's an existing commit-msg hook. Do you want to overwrite it? [y/N] " response
case "$response" in
[yY][eE][sS] | [yY])
install_hook
;;
*)
printf "Skipping hook installation :("
exit $?
;;
esac
else
install_hook
fi
exit $?
fi

printf "Checking commit message format...\n"

COMMIT_MSG_FILE="$1"

if [ ! -f "$COMMIT_MSG_FILE" ]; then
echo "Error: Commit message file not found."
exit 1
fi

COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Regular expression to match Conventional Commits format
CONVENTIONAL_COMMIT_REGEX="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(\S+\))?: .+$"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tried to do it with convco first but it was giving me some issues so i just did a regex :P


if ! echo "$COMMIT_MSG" | grep -qE "$CONVENTIONAL_COMMIT_REGEX"; then
echo "Commit message does not follow Conventional Commits format."
exit 1
fi
90 changes: 57 additions & 33 deletions scripts/hooks/pre-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ git_directory=$(git rev-parse --git-dir)
install_hook() {
mkdir -p "$git_directory/hooks"
ln -sfv "$project_toplevel/scripts/hooks/pre-commit.sh" "$git_directory/hooks/pre-commit"
cargo install taplo-cli --locked
}

if [ "$1" = "--install" ]; then
Expand All @@ -39,46 +40,69 @@ format_check() {

has_formatting_issues=0
first_file=1

# Check and format Rust files
rust_staged_files=$(git diff --name-only --staged -- '*.rs')
format_files "$rust_staged_files"

# check for issues
for file in $rust_staged_files; do
format_check_result=$(rustfmt --check $file)
if [ "$format_check_result" != "" ]; then
if [ $first_file -eq 0 ]; then
printf "\n"
fi
printf "$file"
has_formatting_issues=1
first_file=0
fi
# Check and format TOML files
toml_staged_files=$(git diff --name-only --staged -- '*.toml')
format_files "$toml_staged_files"

# Check and format Shell script files
sh_staged_files=$(git diff --name-only --staged -- '*.sh')
format_files "$sh_staged_files"

if [ $has_formatting_issues -ne 0 ]; then
printf "\nSome files were formatted and added to the commit.\n"
fi
}

format_files() {
local staged_files=$1

for file in $staged_files; do
case "$file" in
*.rs)
format_check_result=$(rustfmt --check $file 2>&1)
;;
*.toml)
taplo fmt $file >/dev/null 2>&1
git add $file
printf "$file\n"
;;
*.sh)
format_check_result=$(shfmt -d $file 2>&1)
;;
esac

format_file
done
}

if [ $has_formatting_issues -ne 0 ]; then # there are formatting issues
printf "\nFormatting issues were found in files listed above. Trying to format them for you...\n"
exit_code=0
format_file() {
if [ "$format_check_result" != "" ]; then
if [ $first_file -eq 0 ]; then
printf "\n"
fi
printf "$file"
has_formatting_issues=1
first_file=0

for file in $rust_staged_files; do
case "$file" in
*.rs)
rustfmt $file
format_exit_code=$?

if [ $format_exit_code -ne 0 ]; then
# rustfmt couldn't format the current file
exit_code=1
else
not_staged_file=$(git diff --name-only -- $file)

if [ "$not_staged_file" != "" ]; then # it means the file changed and it's not staged, i.e. rustfmt did the job.
git add $not_staged_file
fi
fi
done

if [ $exit_code -ne 0 ]; then
printf "rustfmt failed to format some files. Please review, fix them and stage them manually."
exit 1
fi
;;
*.sh)
shfmt -w $file
;;
esac

# Add formatted file to commit if changes were made
not_staged_file=$(git diff --name-only -- $file)
if [ "$not_staged_file" != "" ]; then
git add $not_staged_file
fi
fi
}

Expand Down
Loading