Skip to content

Instantly share code, notes, and snippets.

@DerLobi
Last active May 9, 2022 09:45
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save DerLobi/d938ac7dc422145f85e6 to your computer and use it in GitHub Desktop.
Save DerLobi/d938ac7dc422145f85e6 to your computer and use it in GitHub Desktop.
Don't commit focused tests. Use this as a pre-commit hook and the commit won't succeed if you have staged changes that contain `fdescribe`, `fcontext`, `fit`, `fspecify` or `fexample`. Copy this file as `pre-commit` into the `.git/hooks` folder of your repository (create it if neccessary) and chmod +x the file.
#!/bin/sh
#
# This pre-commit hook looks for `fdescribe`, `fcontext`, `fit`, `fspecify` and `fexample` in the
# staged files and exits with an error code of 1 if there are such changes.
#
STATUS=0
DESCRIBEFILES=$(git diff --staged -G"^\s*fdescribe\(" --name-only | wc -l)
if [ $DESCRIBEFILES -gt 0 ]
then
echo "You forgot to remove a fdescribe in the following files:"
git diff --staged --name-only -G"^\s*fdescribe\("
echo ""
STATUS=1
fi
CONTEXTFILES=$(git diff --staged -G"^\s*fcontext\(" --name-only | wc -l)
if [ $CONTEXTFILES -gt 0 ]
then
echo "You forgot to remove a fcontext in the following files:"
git diff --staged --name-only -G"^\s*fcontext\("
echo ""
STATUS=1
fi
ITFILES=$(git diff --staged -G"^\s*fit\(" --name-only | wc -l)
if [ $ITFILES -gt 0 ]
then
echo "You forgot to remove a fit in the following files:"
git diff --staged --name-only -G"^\s*fit\("
echo ""
STATUS=1
fi
SPECIFYFILES=$(git diff --staged -G"^\s*fspecify\(" --name-only | wc -l)
if [ $SPECIFYFILES -gt 0 ]
then
echo "You forgot to remove a fspecify in the following files:"
git diff --staged --name-only -G"^\s*fspecify\("
echo ""
STATUS=1
fi
EXAMPLEFILES=$(git diff --staged -G"^\s*fexample\(" --name-only | wc -l)
if [ $EXAMPLEFILES -gt 0 ]
then
echo "You forgot to remove a fexample in the following files:"
git diff --staged --name-only -G"^\s*fexample\("
echo ""
STATUS=1
fi
exit $STATUS
@dnicolson
Copy link

I noticed that when removing an fdescribe the hook won't allow the commit because it can't differentiate from added/removed lines. A simple workaround is to wrap each block in something like this:

if [ $(git diff --staged | grep "^\+\s*fdescribe(") ]

This is because grep can check for +/- but git's -G doesn't appear to be able to.

@brendan-donegan
Copy link

brendan-donegan commented Jan 4, 2018

Thanks for this. Additionally the whole thing could be condensed down to 20 lines by use a bash for loop:

  9 for focus in fdescribe fcontext fit fspecify fexample; do
 10     FILES=$(git diff --staged -G"^\s*$focus\(" --name-only | wc -l)
 11     if [ $FILES -gt 0 ]
 12     then
 13         echo "You forgot to remove a $focus in the following files:"
 14         git diff --staged --name-only -G"^\s*$focus\("
 15         echo ""
 16         STATUS=1
 17     fi
 18 done

@chrisdeely
Copy link

Here's a full implementation using @brendan-donegan 's approach

#!/bin/sh
STATUS=0

for focus in fdescribe fcontext fit fspecify fexample; do
    FILES=$(git diff --staged -G"^\s*$focus\(" --name-only | wc -l)
    if [ $FILES -gt 0 ]
    then
        echo "You forgot to remove a $focus in the following files:"
        git diff --staged --name-only -G"^\s*$focus\("
        echo ""
        STATUS=1
    fi
done

exit $STATUS

@martin056
Copy link

Here's a full implementation using @brendan-donegan 's approach

#!/bin/sh
STATUS=0

for focus in fdescribe fcontext fit fspecify fexample; do
    FILES=$(git diff --staged -G"^\s*$focus\(" --name-only | wc -l)
    if [ $FILES -gt 0 ]
    then
        echo "You forgot to remove a $focus in the following files:"
        git diff --staged --name-only -G"^\s*$focus\("
        echo ""
        STATUS=1
    fi
done

exit $STATUS

@chrisdeely If fit or fdescribe had been added during a rebase for example this hook will fail.

I've changed the implementation as follows:

#!/bin/sh

STATUS=0

MATCHES=$(git --no-pager diff --staged -G'[fit|fdescribe]\(' -U0 --word-diff | grep -P '\-\]\{\+(fdescribe|fit)' | wc -l)
if [ $MATCHES -gt 0 ]
then
    echo "\033[31mYou forgot to remove 'fit' or 'fdescribe'"
    STATUS=1
fi

exit $STATUS

NOTE: I cannot find a way to print out the name of the file now :(

@chrisdeely
Copy link

@martin056 Nice - I have definitely encountered that issue before. I've had to temporarily disable this hook in order to get a rebase to work. I'll try your solution

@etienneCharignon
Copy link

Hi there, here is the version I've arrived to, integreting your remarques:

#!/bin/sh

STATUS=0


KEY_WORDS='fdescribe|fcontext|fit|fspecify|fexample|focus: true'
MATCHES=$(git --no-pager diff --staged -G"[$KEY_WORDS] " -U0 --word-diff | grep --extended-regexp "\-\]\{\+.*($KEY_WORDS)" | wc -l)
if [ $MATCHES -gt 0 ]
then
    echo "\033[31mYou forgot to remove focus in the following files:"
    git diff --staged --name-only -G"[$KEY_WORDS] "
    STATUS=1
fi

exit $STATUS

Note that

  • I improved the detection to also catch the focus: true
  • My grep version do not have the -P option but I think that --extended-regexp is the equivalent

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