23

I've created a very simple pre-commit script:-

#!/usr/bin/env sh

# Run tests
npm test
if [ $? -ne 0 ]; then
  echo "Tests failed. Aborting.."
  exit 1
fi

exit 0

When I run git commit at the command line (with failing tests), I get the expected exit 1 with the message Tests failed. Aborting...

However, If I use GitHub for Mac however I get:

.git/hooks/pre-commit: line 5: npm: command not found
Tests failed. Aborting..
 (256)

I'm guessing its down to npm not being available to the execution environment that GitHub for Mac is using, but I've been tearing my hair out trying to work out how to fix this.

4 Answers 4

28

Resolved. As globally installed node modules end up under /usr/local/bin I simply needed to add the following at the beginning of my pre-commit:

PATH=$PATH:/usr/local/bin:/usr/local/sbin

i.e. appending both /usr/local/bin and /usr/local/sbin to PATH at the point of execution.

2
  • 1
    In case anyone else is worrying about breaking teammates' workflows, this works on windows as well since all git hooks on windows are run through git's bash emulator. Commented May 24, 2018 at 13:45
  • 1
    where to run this command?
    – Alan Yong
    Commented Feb 25, 2022 at 9:21
8

The $PATH variable that is available in GUI environments like Github Desktop and Sourcetree is different than the one available in the terminal. By default the $PATH available in the GUI environments can't find your node modules. As was stated in the previous answer, you can ensure that /usr/local/bin is in the path by adding

PATH=$PATH:/usr/local/bin:/usr/local/sbin

In my case this did not work because I am using Node Version Manager, which stores different versions of Node and makes it easy to upgrade and switch Node versions. It stores your node_modules for each version of Node in a separate file. Here is the code I used to get around this problem:

#!/usr/bin/env bash

PATH="/usr/local/bin:$PATH"

if [ -f $HOME/.nvm/nvm.sh ]
then
  . $HOME/.nvm/nvm.sh
  PATH="$HOME/.nvm/versions/node/$(nvm current)/bin:$PATH"
fi

This checks for NVM, and if it exists, loads it and uses it to find the path to the node modules for the currently used version of Node. If you are only trying to access node modules and don't need to get at anything special you can skip adding the sbin folder, e.g. /usr/local/sbin

2
  • 2
    "you can ensure that /usr/local/bin is in the path by adding" – by adding where?
    – sompylasar
    Commented Aug 31, 2017 at 22:23
  • @sompylasar in the pre-commit script, I posted the example. I modified the script in the question and posted it in my answer. It modifies the PATH based on whether or not nvm is available
    – RustyToms
    Commented Aug 31, 2017 at 23:04
1

I solved it by running:

sudo launchctl config user path "$(brew --prefix)/bin:${PATH}"

And creating a .huskyrc file in the home folder ~ (not in the project folder) with this content:

# This loads nvm.sh and sets the correct PATH before running hook
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

I followed these instructions from the Husky FAQ.

0

For me it was that I didn't have a dependency installed that was being called from pre-commit. In my case this was composer, so a brew install composer helped me out.

For future peeps, check if you are missing any dependancies being called in your pre-commit file by opening your-project-directory/.git/hooks/pre-commit in your favorite text editor and install missing the dependancies as needed.

Not the answer you're looking for? Browse other questions tagged or ask your own question.