I found myself needing to run a debugger on my Jasmine specs. The really fun part is that I am running these specs through the grunt-jasmine-node plugin for grunt. This means what I really need to do is run a debugger on top of grunt, and have it hit my Jasmine specs when they get around to being executed.
It turns out I can do this through a rather simple, one liner in a bash shell (or command prompt on Windows) and I instantly have access to the built in nodejs debugger when running code from any grunt command! But to get there, I had to follow a few steps down an interesting path and learn how to hijack grunt’s script execution.
Hijacking Grunt Execution
The first step in the solution is to hijack the execution of grunt so that you are running it w/ a call to NodeJS directly, instead of just using the Grunt command line tool. To do that, you need to know what the Grunt command line tool is. On OSX and Linux, you can get the “grunt” file location by running:
As you can see, the grunt command line is located at /user/local/bin/grunt on my box. A quick “cat” of that shows that this is a shell script with a shebang (hash-bang) to tell the shell how to execute the file as a nodejs script.
Now that I know this is a NodeJS script, I have options. I could modify the file to run a different shell command, but that’s a bad idea. Any updates or re-installs would requite me to change that file again. No thanks. The other option I have is just calling the “node” command line myself and telling node to run this script.
I’m now running the “grunt” script directly with node, instead of letting the shell figure out how to run it.
Using “which” To Simplify Execution
Again, in OSX and Linux I can use the “which” command line to make this even easier. Rather than having to remember where the grunt command is when I want to run it from node directly, I can use the $( … ) call. This call executes a child script and interpolates the output in to the parent command. At the same time, I’m going to add the “debug” call to the node command line.
When I run this, it gets expanded in to the same direct command line call as above (with the addition of “debug” of course). Only now, I don’t have to remember the path to the “grunt” command line tool. (Sadly, I don’t know how to get this effect on Windows. You might have to hard code the location of the grunt script for that OS.)
Making It A Bash Script
As short as the above script is, I don’t want to type it all out every time I want to debug code run from grunt. So I stuffed that one liner in to a bash script with it’s own shebang (hash bang) telling it to use bash to run this script.
Now that I have this in it’s own script, I need to be able to pass command line parameters in to the real command calls. On OSX and Linux, that can be done with the inclusion of “$@” – meaning “all command line parameters”, or “$1”, “$2”, “$..n” (where “n” is the parameter position number). On Windows, the same can be done with “%*” to get all params, or “%1”, “%2”, “%3” … “%..n” (thanks to Alexander Gross in the comments, for the “%*” tip).
The resulting script on my OSX box looks like this:
Running The Debugger On Jasmine-Node
I now have a “grunt-debug” file in my project folder. When I need to debug my grunt-jasmine-node tests now, I just run this:
My break points hit and I can debug in to the code (including my grunt-jasmine-node specs) with the built in NodeJS debugger!