Skip to content

Instantly share code, notes, and snippets.

@guilherme
Last active February 24, 2024 20:39
Show Gist options
  • Save guilherme/9604324 to your computer and use it in GitHub Desktop.
Save guilherme/9604324 to your computer and use it in GitHub Desktop.
Git pre-commit hook that detects if the developer forget to remove all the javascript console.log before commit.
#!/bin/sh
# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty
consoleregexp='console.log'
# CHECK
if test $(git diff --cached | grep $consoleregexp | wc -l) != 0
then
exec git diff --cached | grep -ne $consoleregexp
read -p "There are some occurrences of console.log at your modification. Are you sure want to continue? (y/n)" yn
echo $yn | grep ^[Yy]$
if [ $? -eq 0 ]
then
exit 0; #THE USER WANTS TO CONTINUE
else
exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
fi
fi
@TheophileMot
Copy link

TheophileMot commented May 31, 2022

@Kasik-D Sure. A couple of helpful things to know: $? gives the exit code of whatever command was previously run (the standard is 0 for success, 1 or another number otherwise); also, there are ways to compare numbers in a script, like [[ $x -ne $y ]]. Here -ne stands for "Not Equal to".

So try this:

run_linter () {
  npm lint -s     # or npx eslint *.js, or whatever your lint command is
  if [[ $? -ne 0 ]]
  then
    printf "Oh no\n"
    exit 1
  fi
}

# ...

run_linter
no_console
whatever_other_stuff

@Kasik-D
Copy link

Kasik-D commented Jun 1, 2022

@TheophileMot Thank you, one more qustions what is this programming language ? Where i see instruction of this

@TheophileMot
Copy link

@Kasik-D You're welcome. This language is Bash shell scripting. Bash (or a similar shell, like zsh) is what the terminal runs on MacOS or Linux machines. On Windows, you would have to download it. Learning Bash is a life-long journey, but there are many excellent resources. This looks like a good place to start: https://linuxconfig.org/bash-scripting-tutorial-for-beginners. Have fun!

@Kasik-D
Copy link

Kasik-D commented Jun 1, 2022

@TheophileMot Thanks again

@TimCreasman
Copy link

I've been working on a more general solution that takes a text file of blocked phrases as input and will detect if any of these phrases are in your commit. I also incorporated the color changes @TheophileMot added and formatted some additional things.

If you have a file block-list.txt with the following:

console.log
// TODO
other thing

It will detect these phrases and print out the offending diff statement.

Also disclaimer: I only tested this on OSX, but anyway here's the code:

#!/bin/bash

# Redirect output to stderr.
exec 1>&2

# Block list file location: Update this to point to your own list
blockListFile=".husky/_/block-list.txt"

# Terminal colors and formats
lightRed='\033[1;31m'
green='\033[0;32m'
yellow='\033[1;33m'
clearFormat='\033[0m'
underline='\033[4m'

# Flags
errorFoundFlag=0

confirm () {
  printf '%b\n' "$yellow"
  read -rp "Commit anyway? (y/n) " yn </dev/tty # Enable user input.
  printf '%b' "$clearFormat"

  if echo "$yn" | grep "^[Yy]$"; then
    printf "%bProceeding with commit...%b\n" "$green" "$clearFormat" # The user wants to continue.
  else
    exit 1 # The user does not wish to continue, so rollback.
  fi
}

# Finds the section of the diff that has the blocked phrase
offendingDiff () {
  # Skip this method if there is no parameter passed in
  if [ -z "$1" ]; then
    return 0
  fi

  git diff --cached --color=always | tail -r | awk "/$1/{flag=1}/diff/{flag=0}flag" | tail -r
}

checkRegexp () {
  # Skip this method if there is no parameter passed in
  if [ -z "$1" ]; then
    return 0
  fi

  # Here we prepend the regex with [^-] which will ensure we won't be blocked committing changes that remove the blocked phrase
  regex="^[^-].*$1"

  if [ "$(git diff --cached | grep -c "$regex")" != 0 ]; then
    printf "%b\nError: you are attempting to commit the blocked phrase: %b%s:%b\n" "$lightRed" "$underline" "$1" "$clearFormat"
    # Highlights and adds error arrows to the printout
    offendingDiff "$1" | sed "s/$1/$(printf "%b$1" "$underline")/" | sed "/$1/ s/$/ $(printf "%b<<<<<<<%b" "$lightRed" "$clearFormat")/"
    errorFoundFlag=1
  fi
}

checkBlockList () {
  while read -r line
  do
    checkRegexp "$line"
  done < "$blockListFile"
  if [ "$errorFoundFlag" = 1 ]; then
    confirm
  fi
}

checkBlockList

@Maximauve
Copy link

@TimCreasman thanks for this script, I tested it on Windows / Linux and it seems that the -r argument on tail -r in your OffendingDiff is unkown.

I found the tac command that works just fine

git diff --cached --color=always | tac | awk "/$1/{flag=1}/diff/{flag=0}flag" | tac

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