Thursday, February 23, 2012

Building your own IDE

So, recently, I've been dabbling a bit in node.js / javascript. This has led me to the conclusion that these monolithic IDE's we use every day, are a Bad Idea (i'm looking at you eclipse). Because of the bloatedness of IDEA/eclipse/netbeans for javascript / HTML development I went back to basics. Basically building my own IDE using smaller, more specialized components. So, my basic setup is as follows:
  • Sublime Text 2 - text editor and syntax highlighting
  • jslint - Lint tool for Javascript code. It's basically a syntax checker, together with a bit of static analysis
  • npm - this is the node package manager. Think maven. It can also run your tests
  • guard - this is a ruby gem I use to watch for file changes. It can execute arbitrary commands whenever a file changes
  • libnotify/notify-send - libnotify is used to make popups on the desktop
Right, so those are the pieces. How do they fit together though? Well, easy. Guard is setup to watch my source/views and tests. Whenever any of these changes, the complete test suite is run using npm, and the output is received as JSON. I then parse the JSON to create a popup on my desktop, which instantenously gives me the results of the unit tests. This works so well that I haven't really touched the browser in the last week to test my javascript code. Here's the code for the test running/popup:
var exec = require("child_process").exec,
spawn = require("child_process").spawn,
command = "mocha -R json tests/*-test.js",
_ = require("underscore");
var child = exec(command, function (error, stdout, stderr) {
var output, STATUS, ICON, status;
if (stderr) {
STATUS="BROKEN";
ICON="/usr/share/icons/gnome/32x32/actions/gtk-close.png";
output = "Command run failure: " + error + "\n" + stderr;
} else {
try {
var results = JSON.parse(stdout);
output = "<b>Failures: " + results.stats.failures + "</b>\n";
output += "Successes: " + results.stats.passes + "\n";
if (results.stats.failures > 0) {
STATUS="FAILURE";
ICON="/usr/share/icons/gnome/32x32/actions/gtk-close.png";
output += "\n\n<b>Failure details</b>\n-----------\n";
output += _(results.failures).map(function (f) { return f.fullTitle + "\n"; });
} else {
STATUS="Success";
ICON="/usr/share/icons/gnome/32x32/actions/add.png";
}
} catch (e) {
output = stdout;
STATUS="BROKEN";
ICON="/usr/share/icons/gnome/32x32/actions/gtk-close.png";
}
}
spawn("notify-send", [STATUS, output, "-i", ICON, "-t", "10000"]);
});
Here's my guard file:
guard 'shell' do
watch(%r"tests/.*test\..*") {|m|
`node bgtests.js`
}
watch(%r"js/.*js") {|m|
`node bgtests.js`
}
end
view raw Guardfile hosted with ❤ by GitHub
The popups look really nice. They are also quite customisable (depending on your notify backend). Try
notify-send "Test" test
on your PC to see what it does. Anyway, first post! Here's an example of the popup: