Search code examples
node.jsgitbashgithooks

How to stop a bash script from an infinite loop?


I have this bash script in my project directory named as shrinkwrap.sh:

update_package_json_changed_files() {
  echo "> changed files"

  git diff --cached --name-only | grep -x package.json
}

update_shrinkwrap_and_at_to_git_index() {
  echo "> Updating npm-shrinkwrap.json and adding to current commit."

  npm shrinkwrap
  git add npm-shrinkwrap.json 
}

if get_package_json_changed_files; then
  update_shrinkwrap_and_at_to_git_index
fi

and I am running this script in package.json as the following:

"scripts": {
  "shrinkwrap": "bin/shrinkwrap.sh"
}

and I installed npm pre-commit in order to execute the script as the following:

"pre-commit": ["shrinkwrap"]

when I try to commit, the script goes into an infinte loop. It keeps running, and nothing can stop it. I tried command + C, control + Z. Nothing worked. Did anyone run into this issue before ? why is that happening ?


Solution

  • It is possible that it is triggered on file change, and proceed to change at least one file, which in turns triggers it (on file change), which makes it change a file, which... and so on.

    A usual way to break that is to generate a flag file (touch /tmp/in_progress), and to call update_shrinkwrap_and_at_to_git_index() only if that file does not exist.
    If it exists, delete it (but don't do anything else)

    So:

    • update_shrinkwrap_and_at_to_git_index() a touch /tmp/in_progress and
    • before if get_package_json_changed_files; add a if [ -e /tmp/in_progress ]; then rm /tmp/in_progress; exit 0; fi

    The OP Max Doung comments:

    I added sudo to in front of npm shrinkwarp, and it did stop the loop.when I take it out, loop starts again. Wondering why?

    That suggests the hook is triggered by a user-local settings (one in ~/.gitconfig for instance)

    Executing the command with a different account (here root, through sudo) would avoid using said global user account-specific setting.