#!/usr/bin/env bash # # Defense-in-depth for magit (the .git/hooks wrapper unsets it too); ensures # hooks invoked from emacs/magit behave the same as on the CLI. # https://magit.vc/manual/magit/My-Git-hooks-work-on-the-command_002dline-but-not-inside-Magit.html # unset GIT_LITERAL_PATHSPECS HAS_NODE=`which node 2> /dev/null || which nodejs 2> /dev/null || which iojs 2> /dev/null` # # There are some issues with Source Tree because paths are not set correctly for # the given environment. Sourcing the bash_profile seems to resolve this for bash users, # sourcing the zshrc for zshell users. # # https://answers.atlassian.com/questions/140339/sourcetree-hook-failing-because-paths-don-t-seem-to-be-set-correctly # function source_home_file { file="$HOME/$1" [[ -f "${file}" ]] && source "${file}" } if [[ -z "$HAS_NODE" ]]; then source_home_file ".bash_profile" || source_home_file ".zshrc" || source_home_file ".bashrc" || true fi NODE=`which node 2> /dev/null` NODEJS=`which nodejs 2> /dev/null` IOJS=`which iojs 2> /dev/null` LOCAL="/usr/local/bin/node" BINARY= # # Figure out which binary we need to use for our script execution. # if [[ -n "$NODE" ]]; then BINARY="$NODE" elif [[ -n "$NODEJS" ]]; then BINARY="$NODEJS" elif [[ -n "$IOJS" ]]; then BINARY="$IOJS" elif [[ -x "$LOCAL" ]]; then BINARY="$LOCAL" fi # # Run from the repository root so `require.resolve('pre-commit')` works for Yarn PnP, # and GUI git clients that invoke hooks with an unexpected cwd still resolve deps. # REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || REPO_ROOT="" if [[ -n "$REPO_ROOT" ]]; then cd "$REPO_ROOT" || exit 1 fi # # Resolve the entry point of the `pre-commit` package via Node so we work for # Yarn Plug'n'Play, hoisted, and nested layouts. If the package cannot be # resolved (e.g. the user switched to a branch with no `node_modules`, or # uninstalled `pre-commit`) skip the hook with exit 0 instead of failing the # commit -- a missing dev dependency must not block work. # RESOLVED= RESOLVE_RC=1 if [[ -n "$BINARY" ]]; then RESOLVED="$("$BINARY" -e "try { console.log(require.resolve('pre-commit')); } catch (e) { process.exit(2); }" 2>/dev/null)" RESOLVE_RC=$? fi # # Add --dry-run cli flag support so we can execute this hook without side effects # and see if it works in the current environment # if [[ $* == *--dry-run* ]]; then if [[ -z "$BINARY" ]] || [[ "$RESOLVE_RC" -ne 0 ]] || [[ -z "$RESOLVED" ]]; then exit 1 fi else if [[ "$RESOLVE_RC" -ne 0 ]] || [[ -z "$RESOLVED" ]]; then echo "pre-commit: 'pre-commit' package is not installed; skipping hooks (run \`npm install\` to re-enable)." >&2 exit 0 fi exec "$BINARY" "$RESOLVED" fi