Skip to content

Instantly share code, notes, and snippets.

@swateek
Last active September 9, 2022 04:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save swateek/aca3875b1648675f9a6b146c5dfdb5c7 to your computer and use it in GitHub Desktop.
Save swateek/aca3875b1648675f9a6b146c5dfdb5c7 to your computer and use it in GitHub Desktop.
PreCommit Hook - Convert Tab to Spaces for Golang Files
#!/bin/bash
# Print an introduction line in cyan
printf "\033[0;36mPre-commit hook - For Checking Tabs in Golang Files...\033[0m \n"
# Grab feed of staged files
files=$(git diff --name-only --cached -- "*.go")
numfiles=$( printf '%s' "$files" | grep -c '^' )
if [ $numfiles -eq 0 ]
then
printf "\033[0;35mNo Golang files staged. This precommit hook need not run.\033[0m\n"
exit 0
fi
# Default to zero which means the changes are good and the commit can go ahead
exitstatus=0
numnonpassingfiles=0
# Iterate over the filenames to discover the longest
longest=0
for i in $files
do
if [ ${#i} -gt $longest ]
then
longest=${#i}
fi
done
# Iterate over the staged filenames
for i in $files
do
# Print file name eg: "Checking: text.txt"
printf "\033[0;35mChecking:\033[0m %s " "$i"
# Print some padding spaces so the failed/success statuses line up
padding=$(expr $longest - ${#i})
for ((n=0;n<$padding;n++))
do
printf " "
done
# Count number of lines with the plus symbol and tab characters at the start (eg. New lines, indented wrongly)
tabbedlines=$( git diff --cached -U0 -- $i | egrep "^\+ " )
tabbedlinecount=$( printf "%s" "$tabbedlines" | grep -c '^' )
# Print the coloured [failed] or [success] report
if [ $tabbedlinecount -gt 0 ]
then
printf "\033[0;31m[failed]\n"
((numnonpassingfiles++))
exitstatus=1
else
printf "\033[0;32m[passed]\n"
fi
# Print report line about tab character being used
if [ $tabbedlinecount -gt 0 ]
then
printf "%s lines indented with a tab character: \033[0;32m \n" "$tabbedlinecount"
while read -r line;
do
printf "%s\n" "$line"
done <<< "$tabbedlines"
printf "\n"
printf "Converting Tabs to Spaces.. you'll need to add the file again\n"
expand -t4 `echo $i` | sponge `echo $i`
fi
# Reset print color back to default for the next iteration
printf "\033[0m"
done
# Print a summary of lint
if [ $exitstatus -eq 0 ]
then
printf "\033[0;32m%s %s file" "--" "$numfiles"
if [ $numfiles -gt 1 ]
then
printf "s"
fi
printf " passed. Continuing with commit... \033[0m\n"
else
printf "%s Sorry, %s of %s staged files contain lines that do not pass.\n" "--" "$numnonpassingfiles" "$numfiles"
fi
exit $exitstatus

PreCommit Hook

A pre-commit hook is added locally to the .git/hooks folder and is executed before you can add a commit message.

Pre-Requisite

In this script we use expand and sponge commands, so you need to have the relevant libraries installed.

To install for Ubuntu,

apt get -y moreutils

Adding the Script

Inside .git/hooks directory, create a file pre-commit and add the lines in the pre-commit file below.

How To?

  • Add the files via VSCode, or git add -A
  • After you type your commit message, the pre-commit script will be executed. It'll change the file and you need to add it back again.

References

Completely built out of - this script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment