git prepare-commit-msg with node.js
I think people often overlook using node.js as a scripting tool like ruby or python. If you search the web for examples of customized git hooks, you'll probably have visited git-scm.com, where most of the examples are in ruby.
I wanted to show a pretty simple prepare-commit-msg hook written in node.js. This hook will append the name and description of whatever working branch you commit from. I use this technique to create a working branch for a JIRA ticket number, so all my commits to this ticket automatically include that ticket number. Then, JIRA can be configured to display github commits directly in the ticket details when that commit references the ticket in the commit message.
The script:
#!/usr/bin/env node
var exec = require('child_process').exec,
util = require('util'),
fs = require('fs'),
contents = null,
branch, desc;
console.log(process.argv);
// expect .git/COMMIT_EDITMSG
if(/COMMIT_EDITMSG/g.test(process.argv[2])){
// look for current branch name
branch = exec("git branch | grep '*'",
function (err, stdout, stderr) {
if(err){
// git branch will fail if initial commit has not been done,
// so we can safely skip this hook
process.exit(0);
}
// opens .git/COMMIT_EDITMSG
contents = fs.readFileSync(process.argv[2]);
// trims extra characters from start/end of line
var name = stdout.replace('* ','').replace('\n','');
// If the branch has a description, pull that
desc = exec('git config branch.'+ name +'.description',
function(err, stdout, stderr){
// don't handle errors (because we write out branch anyway)
// we found a description, add to 'name'
if(stdout){ name = util.format('%s (%s)', name, stdout.replace(/\n/g,'')); }
// '(no branch)' indicates we are in a rebase or other non-HEAD scenario
if(name !== '(no branch)'){
// Append branch name to original contents.
contents = util.format('%s\n\n:%s\n', contents, name);
// write contents back out to .git/COMMIT_EDITMSG
fs.writeFileSync(process.argv[2], contents);
process.exit(0);
} else {
process.exit(0);
}
});
});
}
The above script is pretty well-commented. If you decide to use it, you may want to comment out the first console.log which dumps all arguments sent to the script.
Here's an example of its usage.
Create and initialize a new local git repository.
$ mkdir example $ cd example $ git init
Then, copy the above example script into the git hooks directory under .git/hooks/prepare-commit-msg
Now, in the example directory, create and commit a file into the repository:
$ touch first $ git add . $ git commit -m 'Initial commit'
You'll see the array of arguments passed through the custom git hook, but if you issue a git log, you'll only see the commit message 'Initial commit'. That's because this custom hook expects a git branch, but there is no git branch until your initial commit is complete. To verify the script is working:
$ touch second $ git add . $ git commit -m 'Second commit'
A git log will now show you a tweaked message:
Second commit
:master
Now, you can create a branch named 'ABC-123' and do another commit:
$ git checkout -b ABC-123 $ touch third $ git add . $ git commit -m 'Third commit'
The commit message:
Third commit
:ABC-123
This hook also allows you to print out the branch description. To test, invoke the branch description editor:
$ git branch --edit-description ABC-123
I've added the text 'Supporting branch for ABC-234 and ABC-567'. Save this buffer according to your editor (:wq if you're using vim).
Add a fourth file as we have before, then verify with git log:
Fourth commit
:ABC-123 (Supporting branch for ABC-234 and ABC-567)
Because this script strips newlines from the branch description, you'd need to keep it short. Usually, that's not a problem.
This shows how to append text to your commit message, but it can easily be modified to replace commonly misspelled words (teh -> the).
This prepare-commit-msg hook is available in my blogs repo on github.
Why I don’t recommend the Step module [node.js, npm]
I prefer asyc to step. The async module has a cleaner interface, more options, and utilities. It's a little beefier in size, but those things are beside the point.
Here's why I don't really like step. Tell me what you'd expect from this function:
var Step = require('step');
Step(
function first(){
console.log('first');
this();
},
function second(){
var x;
console.log('second');
if(!x){
// do something that should set x
}
return x;
},
function third(){
console.log('third');
}
)
Did you guess:
$ node step-example.js first second
If you're not familiar with Step, you'll probably look at that first function and wonder what this(); actually does. Well, it is actually shorthand for next(); (I'm simplifying a little here).
Assuming you're at least somewhat familiar with asynchronous control flow, you could assume this(); calls the next function. But, what about the second function? It's returning a value. Does that return from second, or from Step, or from some other function? It returns from second(), but... it passes the value to third. Or, it should. Unless x is undefined, in which case it will be considered an unchained function. Now, I don't think your variables should regularly be 'undefined' at the point of return, but what if you use or someone on your team uses the popular convention of calling a callback as return callback(x);. If the Step module's convention of tweaking this semantics is ignored, another developer may look at it as a typo, "You can't call the context like that..." Right? Also, what if someone doesn't understand the return value can't be undefined and comments out the middle of that function? You may have cleanup logic that isn't getting checked in third().
We've all seen that happen before.
In the above example, if x was not undefined, it would be passed as a parameter to third().
It's this inconsistency which makes me feel like Step is an accident waiting to happen in a regular development team. The source code is pretty well written and concise. I think the author has done a great job, but the usage is unintuitive and I wouldn't recommend using the module.
On the other hand, async is beautifully intuitive.
Consider this example:
var async = require('async');
async.series([
function first(done){
console.log('first');
done(null, 'first');
},
function second(done){
var x;
console.log('second');
if(!x){
// do something that should set x
}
done(null, x);
},
function third(done){
console.log('third');
done(null, 'third');
}
], function(err, results){
console.log(results);
})
async.series allows us to run a series of tasks (functions defined within the array), which pass a value to the callback (that last function you see).
If you forget to pass a value, the results will contain undefined at the index of the array. Your third function won't be skipped unless you forget to invoke the callback. To me, this is a pretty obvious error and one that is easy to spot and correct. Here's is the output of the above call:
first second first third [ 'first', undefined, 'third' ]
To be fair, the example of Step acts more like a waterfall function. Here's what that would look like in async.
async.waterfall([
function first(done){
console.log('first');
done(null, 'first');
},
function second(val, done){
var x;
console.log('second has val: %j', val);
if(!x){
// do something that should set x
}
done(null, x);
},
function(val, done){
console.log('third has val: %j', val);
done(null, 'third');
}
], function(err, val){
console.log('callback has val: %j', val)
});
The above code is available on github: https://github.com/jimschubert/blogs
CommonJS Modules, node’s require() and private members
CommonJS Modules, node's require() and private members
Interestingly, node.js module documentation doesn't even mention CommonJS or the specification proposal it implements. I won't go over CommonJS Modules 1.0 in-depth in this post, but I suggest you read both of these links if you plan to explore node.js development.
An important take-away from this blog post (so important that I state it first) is that node.js caches modules. A module's exports are nothing more than an object. When you set a function or property to be exported, you're setting it on an object.
Conceptually, this:
var someFunction = function(){ /* implement */ };
module.exports.someFunction = exports.someFunction = someFunction;
...is the same as doing this outside of CommonJS modules...
var someFunction = function(){ /* implement */ };
var exports = {};
exports.someFunction = someFuntion;
I know, that seems like it should be common sense. When node.js caches the exports object at the application level, I think understanding this can become hairy -- especially if you come from a compiled language background.
For example, consider the following module.
var count = 0;
var doSomethingShared = function(){
count += 1;
console.log("Shared call count: %d", count);
};
var doSomethingNotShared = function(){
console.log("Other modules don't know about me!");
};
module.exports.shared = exports.shared = doSomethingShared;
module.exports.unshared = exports.unshared = doSomethingNotShared;
We can require this module easily and play around with it in node REPL:
$ node
> var example = require('./example.js');
undefined
> example.shared()
Shared call count: 1
undefined
> example.shared()
Shared call count: 2
undefined
> example.shared()
Shared call count: 3
undefined
> example.shared()
Shared call count: 4
undefined
> example.unshared()
Other modules don't know about me!
undefined
In the same REPL instance, you can re-require the module and see that 'count' is indeed shared:
> var example2 = require('./example.js');
undefined
> example2.shared()
Shared call count: 5
undefined
> example2.shared()
Shared call count: 6
undefined
You can even require the shared function directly:
> var shared = require('./example.js').shared;
undefined
> shared()
Shared call count: 7
undefined
> shared()
Shared call count: 8
undefined
I think you get the point; private variables which aren't exported are shared. In this example, 'count' is a private static property of the module.
Why this matters
This is very important, because when working in the asynchronous environment of node.js you have to be aware about *what* is being cached privately at the module level. In addition to this, if you plan to cache functions for whatever reason, you have to be incredibly sure you know what you're doing. I recommend to NEVER CACHE CALLBACK FUNCTIONS.
As an example of this statement, I've created a sample file processor script in the github repo as fs-example.js. That script reads this blog's directory in the repo, then loops over the files and executes 'processor', which is a custom broken module displaying the above problem. fs-example.js does an inline require, which as you've seen above doesn't make a difference.
The problem I'll display here exists because async calls are likely to take different lengths of time to execute. My example is using the linux commands 'head -1' and 'tail -1' on each file to get the first and last lines, respectively. These commands are nearly instantaneous, so I'm using a random setTimeout to display the problem with caching functions. You could easily modify these scripts to 'head' and 'tail' different web sites. But, whatever. Because head.js and tail.js are simple spawn wrappers, I'll focus on processor.js, which is where the potential bugginess exists.
// begin processor.js
var head = require('./head'),
tail = require('./tail');
// don't do this IRL
var callback = null;
var processor = function(file, cb){
if('function' === typeof cb){
callback = cb;
}
// these fail
head(file, function(d){
callback(d)
});
tail(file, function(d){
callback(d)
});
// these succeed
// head(file, callback);
// tail(file, callback);
};
module.exports = exports = processor;
This is a simple file for having such a subtle bug. The file includes the customized head and tail scripts. Then, it creates a function that tags a file, caches the callback function, and calls head and tail to execute the callback. You'll notice the commented-out lines at the end that claim 'these succeed'. Here's why...
When a callback is passed directly to a function as is done with head(file, callback), the function itself is passed as a reference. Meaning, when the head module executes that callback, it will always execute the referenced callback. Now, what if another developer wants to add logging or other processing of the data? You'll likely get something like the example, where a function is created and callback is called directly (rather than the cb passed into the function originally). Because 'callback' is cached at the module level and shared across calls to processor, the scope created by the processor function is shared with the anonymous function callback and points to whatever is the most recent callback function rather than what one might expect to be the intended function.
We could avoid the problem in the above non-commented code by referencing the 'cb' parameter rather than the cached 'callback' variable. This is because processor creates a closure over 'callback', but 'cb' would always be within the current execution context.
You can play around with the code from this post, which is available on github.
Generating sprites with HTML5 canvas (node-canvas)
About a week ago, I posted about drawing simple shapes in HTML5. HTML5's Canvas isn't only useful on the client side.
About a year ago, I rewrote my Quaketracker mashup which pulls rss content from USGS and displays markers on a Google Map. For part of this rewrite, I wanted to use custom markers to indicate the magnitude of the earthquake, both numerically and colorfully. That task was more involved than I realized it would be. There doesn't seem to be any easy way to generate such a sprite in The Gimp or other graphics software, so I set out to generate a sprite of magnitudes 0.0 through 9.9 with a color range from yellow to orange using node-canvas. This actually made the task very simple.
Before writing the script, I had to decide on an image. I created a pretty simple quote-bubble-like marker with a white background and a black outline. The image is 35x35 square with some transparency padding the actual marker image. This allows me to calculate the layout pretty easily. The white background on black outline gives me a very specific color to replace with the desired color of intensity.
node-canvas is a custom implementation of Canvas for node.js. When I originally wrote this script, I had a few issues compiling node-canvas. When I tweaked the script today, I had no issues. However, it seems like some things are not well-documented or incomplete (PixelArray).
Scripting it in node.js
A lot of times, if your script writes out to files, it's best to check for dependencies and cause your script to exit if they're not met. For example, I know this script is completely useless without node-canvas, so I can probe for the availability of that module and provide directions for installation. I'd do this before attempting to load any other functions from the canvas module. You could also check for versions at this point. If someone runs this script with node-canvas 0.6.0 it will still work, but this may not be the case with other modules. Here's how I start off the script.
var p = require('util').puts;
try {
var probe = require('canvas');
} catch(e) {
p("Cannot find node-canvas module.");
p("Did you install dependencies:\n");
p("\tnpm install -d");
process.exit();
}
var fs = require('fs');
var Canvas = require('canvas');
var Image = Canvas.Image;
var canvas, ctx, baseImage, outImage, img;
I don't usually use 'global' variables like those in the last line of the above snippet for applications or client-side scripting. For a script like this, you could have everything as a global variable as long as the names don't clash with your imported modules.
To initialize shared variables, I like to define an init() function and call that function at the end of the script. This is pretty common in other languages like Ruby and Python, so why node server-side JavaScript?
var init = function() {
// our working image is 35x35, we want 10x10 sheet of sprites
canvas = new Canvas(35*10,35*10);
ctx = canvas.getContext('2d');
baseImage = __dirname + '/base.png';
outImage = __dirname + '/markers.png';
// pre-load the image
img = new Image;
img.onload = function() {
processImage(fileProcessingComplete);
};
img.src = baseImage;
};
The cool thing about node-canvas is that the usage is very similar to the Canvas API implemented in browsers supporting the HTML5 Canvas. In fact, aside from the __dirname special property of node.js, you should be able to drop this init function into a browser with no problems. For this script, I want 100 different magnitudes to be generated from 0.0 through 9.9 (00-99 is 100) so the canvas is initialized to 10 rows and 10 columns of 35x35 squares. Just like a client-side Image object, we want to bind any post-processing of the image via the onload() function.
I'm going to Memento you a bit, and for that I'm sorry but the end is the easier concept. When all the processing is complete, we want to pull image data from the Canvas element and write it out to a file.
var fileProcessingComplete = function() {
var out = fs.createWriteStream(outImage),
stream = canvas.createPNGStream();
stream.on('data', function(chunk){
out.write(chunk);
});
// when PNG stream is done, drain WriteStream
stream.on('end', function(){
p('saved ' + outImage);
out.destroySoon();
});
};
Accessing streams in node.js is usually done asynchronously. We can take chunks of data from the ReadStream of createPNGStream() and pump that to the WriteStream of the output file. When the data from the PNG is done streaming, we tell the output stream to finish writing its buffered data and destroy itself. It sounds intense, but it's pretty straightforward.
Processing the colors and marker images is the fun part. To match the function call in the init function, we just create a function with a callback in the standard way.
var processImage = function(cb) {
// other code removed
if(typeof cb === "function") {
cb.call(this);
}
}
If there's a callback function passed as a parameter, when processImage is finished, it will call that function passing the current scope as the execution scope and no parameters.
To draw out the custom marker, we'll want to define how we want to display the text and at what color we want to have the 0.0 marker start.
ctx.font = 'normal 12px Impact'; ctx.textAlign = 'center'; var color = [255, 255, 0, 235];
The color array represents red, green, blue, and alpha channel (opacity). This may look odd if you're used to specifying alpha channels in css as "rgba(255,255,0,0.92)", but that value of 235 will give roughly 92% opacity.
We can make the script run pretty quickly by using a second canvas 2d context for the recolor phases (which modifies every white pixel).
// use a temp Canvas and Context of 35x35 size.
var tempCanvas = new Canvas(35,35);
var tempCtx = tempCanvas.getContext('2d');
This is an optimization I made today when tweaking the original script. In the original version of this script, I would write the base image to the output canvas then iterate over 'NxN' pixels on the output canvas to change the color of one pixel. Using a temporary canvas context, we only have to iterate over 35 pixels wide by 35 pixels high for every new marker. This not only speeds up the process, but it could be a difference of having a script that won't run on slower machines.
For each of the desired 100 magnitudes, we'll want to find the x and y values (top-left pixel) to which we'll write the updated marker. For every 1/2 magnitude, the Green color value decrements by 13 points.
for(var magnitude = 0; magnitude <= 100; magnitude++) {
var y = 35 * Math.floor(magnitude/10),
x = ( 35*(magnitude % 10) );
// This increments the color slightly
if(magnitude % 5 == 0){
color[1] = color[1] - 13;
}
// some code removed
ctx.fillText("" + parseFloat(magnitude / 10, 1), x + (35/2), y + (35/2), 35);
}
The last line of the above snippet fills the magnitude text on the output canvas. This could be moved to the next part of the script for a further optimization: instead of just modifying each white pixel's color, we could recolor and apply the text.
The part of the script which changes the color according to the magnitude looks like this:
tempCtx.drawImage(img, 0, 0, 35,35);
var imgData = tempCtx.getImageData(0, 0, 35, 35);
var data = imgData && imgData.data;
if(data) {
try {
for(var pixel=0;pixel<data.length;pixel=pixel+4) {
var red = data[pixel]
var green = data[pixel+1];
var blue = data[pixel+2];
var alpha = data[pixel+3];
if(red == 255 && green == 255 && blue == 255) {
data[pixel] = color[0];
data[pixel+1] = color[1];
data[pixel+2] = color[2];
data[pixel+3] = color[3];
}
}
} catch (err) { console.error(err.message); }
// Write our temp image data to the final canvas context
/* imageData, dx, dy, sx, sy, sw, sh */
ctx.putImageData(imgData,x,y,0,0, 35, 35);
}
Writing to the temporary canvas's 2d context gives us access to a data buffer which represents a 35x35 image where each pixel is represented by 4 bytes (rgba). Iterating this buffer by 4's, we can check that the given pixel (excluding alpha because that doesn't matter in this case) is white or rgba(255,255,255). If the pixel is white, we replace those 4 indexes with the values in our color array. When we're done iterating the buffer representing the 35x35 image, we can call putImageData on the output canvas. With that, the sprite is complete and our callback handles writing the file.
A note about putImageData
putImageData can be a strange beast. Notice the comment imageData, dx, dy, sx, sy, sw, sh... these are the parameters accepted by the function. Even the HTML5 Specs might make you go, "Uhm... what?" The idea is pretty simple once you understand it. You want to write a buffer (imgData) where the top-left pixel is at dx,dy. sx and sy (or dirtyX and dirtyY) represent a dirty rectangle of size sw x sh (or dirtyWidth by dirtyHeight).
If the imageData passed to the function is the same height and width as the target canvas context, you wouldn't want to overwrite every single pixel would you? You'd only want to overwrite pixels that have changed. Suppose in this script, I had an imageData object of 350x350 to complement the output canvas. When putting the modified imageData, I would have to calculate the current 35x35 box offset and write out the imageData to 0,0. As an example, if I wanted to overwrite the 35x35 box for the 9.9 magnitude marker with an imageData buffer of 350x350, I might write:
ctx.putImageData(imgData, 0, 0, 315, 315, 35, 35);
This would tell the context that although my buffer is 350x350, I've only changed a 35x35 rectangle starting at 315x15. Canvas is smart enough to only update those pixels rather than every pixel in the canvas.
On the other hand, in the script I've written, I only have an imageData object which represents a 35x35 buffer. So, I can tell putImageData to start at the point defined by (x,y) and write the buffer into a 35x35 rectangle. I like this method a little more, but it may not always be the case that you're writing a smaller buffer to the context.
The code
As always, the code for this blog post is available on github at jimschubert/blogs.
The sprite
Here's what the generated sprite looks like.
[node.js] Simple Logging in tweeter.js
tweeter.js is a simple OAuth implementation I started working on for a node.js application I had envisioned. The library works, as in it runs through the whole OAuth dance and allows the client to make API calls. There are some more in-depth things I never got around to (like caching the tokens and clearing sessions and whatnot) before I realized I don't like Twitter. Oh well.
I was just looking through my github repositories and I thought it would be cool to post about the simple logging mechanism I created for tweeter.js. Although not the coolest pattern I used in the project (which probably goes to mixins), I like how simple the solution is. Check out the code for other cool features..
Logging
The cool thing about this logging framework is that it allows you to write out logs to different streams. For instance, suppose you want to write all logging information other than errors to log.txt, but you want to keep errors in errors.txt.
The way I implemented this was to create an object of streams on the Log object. I used getters/setters to provide validation that an object being assigned to one of the properties is actually a stream. Although I didn't bother with it, this object could possibly be sealed or frozen.
// An object with safe getters/setters for each stream.
// Streams are:
// debug, info, error, warn
Log.prototype.streams = {
get none() { return { write: function() { }}; },
get debug() { return this._debug; },
set debug(val) {
requiresStream(val);
this._debug = val;
},
get info() { return this._info; },
set info(val) {
requiresStream(val);
this._info = val;
},
get warn() { return this._warn; },
set warn(val) {
requiresStream(val);
this._warn = val;
},
get error() { return this._error; },
set error(val) {
requiresStream(val);
this._error = val;
}
}
Because this is written for node.js, requiresStream() verifies the value is an instance of EventEmitter with a write function.
Defaults for these streams are set in the constructor with a default logLevel of -1 (disabled).
var Log = module.exports = exports = function Log(level) {
// default error to stderr and the rest to stdout
this.streams.debug = process.stdout;
this.streams.info = process.stdout;
this.streams.warn = process.stdout;
this.streams.error = process.stderr;
// default the logLevel to disabled
this.logLevel = level || -1;
}
An interesting thing about this logger is how I make the calling convention flexible. I use .NET regularly and I would call a logging function in .NET with an enum value to specify the logLevel. I wanted a similar functionality in this logger, so I created a lookup object to map a key (i.e. DEBUG) to a logLevel (0) and a stream (debug).
// [DISABLED] else [DEBUG > INFO > WARN > ERROR]
Log.prototype.logLevels = {
DISABLED: { value: -1, stream: 'none' },
DEBUG: { value: 0, stream: 'debug' },
INFO: { value: 1, stream: 'info' },
WARN: { value: 2, stream: 'warn' },
ERROR: { value: 3, stream: 'error' }
}
I considered accessing these on the streams object directly, but did it this way for readability and flexibility. A major deciding factor in choosing this route was the ability to reorder logging levels in a single place in the code.
// ## log(level msg);
// logs the output with a nice colorful indicator of the stream.
// `msg` may be a string or a formattable string and options.
Log.prototype.log = function(level, msg) {
var original = level;
try {
if(typeof level === 'string'){
level = this.logLevels[level.toUpperCase()];
}
// get logLevel value
if( (this.logLevel > -1) && (level.value >= this.logLevel) ) {
var stream = this.streams[level.stream];
stream.write( util.format.call(this, '[\033[%sm%s\033[39m]\t', colors[level.value], level.stream) );
stream.write( util.format.apply(this, slice.call(arguments,1) ) + '\n');
}
} catch (err) {
console.error("logging is improperly configured!\nIs %j a supported logLevel?\nError:\n%j\n",original, err);
}
}
An example
I've uploaded an example to github.
In this example, I write out logs for each of the 4 supported levels. The default is to write these out to stdout. After writing to the defaults, I set
var Log = require('./log.js'),
fs = require('fs');
var level = process.argv[2] || 1;
var logger = new Log(level),
level = logger.logLevels;
logger.log(level.DEBUG, "This is a debug message");
logger.log(level.INFO, "This is an info message");
logger.log(level.WARN, "This is a warning message");
logger.log(level.ERROR, "This is an error message");
var debugStream = fs.createWriteStream('./debug.txt');
var infoStream = fs.createWriteStream('./info.txt');
var warnStream = fs.createWriteStream('./warn.txt');
var errorStream = fs.createWriteStream('./error.txt');
logger.streams.debug = debugStream;
logger.streams.info = infoStream;
logger.streams.warn = warnStream;
logger.streams.error = errorStream;
logger.log(level.DEBUG, "This is a debug message");
logger.log(level.INFO, "This is an info message");
logger.log(level.WARN, "This is a warning message");
logger.log(level.ERROR, "This is an error message");
debugStream.end();
infoStream.end();
warnStream.end();
errorStream.end();
This provides the following input when passing a log level in via the command line:
Mastering Node: Addons and FunctionTemplate (uuid.node)
Last night, I pushed an addition to my fork of Mastering Node. I decided to add a bit to the Addons chapter. The first example in this chapter only shows how to add a function to a natively-compiled module (i.e. an addon). This example shows you how to start a module which can be used in the following way:
var Uuid = require('./uuid.node').Uuid;
var uuid = new Uuid();
var myId = uuid.generate();
The project files referenced in the following text can be downloaded from the repo: jimschubert/masteringnode
FunctionTemplate
In v8, a FunctionTemplate is used to create the equivalent to:
var template = function() { }
The function at this point is an object and not an instance of the function.
As an example, we will use the linux package uuid to generate a uuid. We will define the header for this addon as:
Install nodejs under ChromeOS (CR-48)
Why would I want to do this?
I'm a software developer. I love javascript. I love node.js. I love the direction Google is taking web development, user interaction, and the web in general. Installing node.js opens up a lot of possibilities for me on my CR-48. I don't know if this will work on anything other than the CR-48, considering the machine has to be in developer mode for these instructions.
If you don't have a chromebook yet, or you don't know what they are... where have you been? But seriously, visit http://www.google.com/chromebook/ and check them out.
Before I start, let me first say that following these instructions may void your warranty if you have one, open your machine up to vulnerabilities, or replace existing files and cause instability. If you don't know how to revert or fix any issues that may occur, don't continue. I offer no sort of warranty, support, or anything else. Consider this a 'hack' of sorts.
I found a blog post detailing how to install an archive package and ruby on rails in ChromeOS. I followed part of these instructions and I have modified them to fit my needs.
Prerequisites
- You must have a Chromebook, possibly only the CR-48
- You must be in 'developer mode'
- You must have a writable rootfs (see above link for developer mode)
Instructions
Downloading and installing xz
- Download the xz package
- Enter crosh or VT-2 (CTRL+ALT+T or CTRL+ALT+→)
- If VT-2, login to the shell
- Run on the terminal: cd /home/chronos/user/Downloads
- Run on the terminal: tar -zxf xz-*.tar.gz
- Run on the terminal: cd usr
- Run on the terminal: cp * /usr/
Now that xz is installed in /usr/bin (verify by running on the command line: which xz), you will be able to extract certain files that are necessary for nodejs and possibly any other package you'd like.
Download and install nodejs and openssl.
The site claims openssl is optional, but node wouldn't open without it
- Download nodejs
- Download openssl
- Enter the terminal again and navigate to /home/chronos/user/Downloads
- Run on the terminal: xz -d node*.xz
- Run on the terminal: tar -zxfv openssl*.tar.gz
- Run on the terminal: cd usr
- Run on the terminal: cp * /usr/
Now you should have a working install of nodejs. You can use npm, for instance, to install express and jade.

Makefile setup for minifying .js files in an expressjs application
There's not really any reason to uglify or minify your JavaScript files on a per-request basis or on a pre-cache basis. This should be done at deployment time only. This can be achieved by adding uglify-js to your package.json file.
// default package.js for an expressjs app using ejs and uglify-js
{
"name": "application-name"
, "version": "0.0.1"
, "private": true
, "dependencies": {
"express": "2.4.6"
, "ejs": ">=0.4.3"
, "uglify-js": ">=1.1.0"
}
}
Make sure the dependencies are installed with
npm install -d
Then, add the following make file and minify your JavaScripts as part of your make process!
JS = $(shell find public/javascripts/*.js) MINIFY = $(JS:.js=.min.js) all: clean $(MINIFY) clean: rm -f ./public/javascripts/*.min.js %.min.js: %.js node ./node_modules/uglify-js/bin/uglifyjs -o $@ $< .PHONY: clean js minify
(expandable source is the same as the gist. It is doubled here to show in RSS feed readers.)
[node.js] Getting started with nodeunit
The following code is part of the testing chapter I previously worked on in my fork of Mastering Node.
Throughout this post, you'll see references to files from a relative directory. If you clone my fork of Mastering Node, these file locations are relative to the root directory of that cloned repository.
For a pretty simple example of real-world testing using nodeunit, check out the initial testing done on my project, brushes.js [?].
Testing
Testing is a very large topic. There are different types of testing, each with different methodologies. Then, there are also strong feelings of developers toward which type of testing is the best or most effective.
- Assertion Testing
- Tests a true or false condition against known objects or values
- Behavioral Testing
- Tests how one object acts when interacting with another
- Functional/Acceptance Testing
- "Black box" testing of a system, usually code-agnostic
- Regression Testing
- Tests for consistency after changes have been made to code
- Others...
There are many other types of testing, but these are some large topics in the testing arena. Development practices include Test-Driven Development (TDD), Behavior-Driven Development, and others. Some programmers don't believe in testing, others believe tests should be written before the code, while others still believe tests should only be written for the most important code. As you can see, this is a large and complex topic.
Whether you write tests before you code, test only the most important code, or casually write tests when there is time, it is important to choose a testing tool that fits your needs.
assert Module
To begin, require the assert module:
var assert = require('assert');
This module exposes a few functions common to assertion testing:
// equality assert.equal(actual, expected, [message]) assert.notEqual(actual, expected, [message]) assert.deepEqual(actual, expected, [message]) assert.notDeepEqual(actual, expected, [message]) assert.strictEqual(actual, expected, [message]) assert.notStrictEqual(actual, expected, [message]) // exception assert.throws(block, [error], [message]) assert.doesNotThrow(block, [error], [message]) assert.ifError(value) // condition assert.ok(value, [message]) assert.fail(actual, expected, message, operator)
These are pretty self-explanatory if you've written assertion tests before. Let's look at a pretty simple test, anyway. We'll code in an object for the test that will do what we want for each test.
Synchronous Testing with Assert
// testing/equality_no_errors.js
var assert = require('assert'),
tester_a = {
val : 'a'
},
tester_b = {
val : 'b'
};
assert.equal(tester_a.val, 'a');
assert.equal(tester_b.val, 'b');
In this example, we're using the assert module to check that a value on each of these objects is the expected value. This works well because the values are equal. But, the assert module throws an AssertionError whenever an assertion fails. So, it doesn't really make sense to have a single file with end-to-end assertions as in the ./src/testing/equality_no_errors.js file. This is where testing frameworks like nodeunit or expresso come in very handy. They offer common functionality of test frameworks (like metrics, etc.).
To see how the AssertionError being thrown from assert.equal can be problematic, change the expected value in the first test to an incorrect value. Then, change the expected value in the very last test to an incorrect value and run node src/testing/equality_no_errors.js again. You'll see that, because of the procedural style of the code, the last test never runs!
In order to run multiple assertions and provide feedback, the simplest test (without a testing framework) would use a try/catch and provide output to stdout.
// testing/equality_with_errors.js
var assert = require('assert'),
tester_a = {
val : 'aa'
}, total = 0, good = 0;
// assert.equal(actual, expected, [message])
try {
console.log("assert.equal(tester_a.val, 'a')");
assert.equal(tester_a.val, 'a');
passed();
} catch (err) { writeException(err); }
console.log("%d of %d tests passed", good, total);
function writeException(err) {
console.log("Test failed!");
util.inspect(err);
if(err["name"] === "AssertionError") {
console.log("Message: " + (err["message"] || "None"));
console.log("Expected: " + err["expected"]);
console.log("Actual: " + err["actual"]);
console.log("Operation: " + err["operator"]);
}
console.log("");
total = total + 1;
}
function passed() {
good = good + 1;
total = total + 1;
console.log("Test passed!\n");
}
The above code is part of the code from within ./src/testing/equality_with_errors.js. It shows how to run synchronous tests with a minimal amount of redundant code, without writing a lightweight testing module for your tests. This may be what you want, but most likely it isn't.
The problems
You could write a simple helper module to run these tests for you. But, how do you verify the order of your tests? This can become complex very quickly.
You can partially resolve this with the try/catch block example above, but this requires a lot of redundant code. Compare ./src/testing/equality_with_errors.js and ./src/testing/equality_no_errors.js to see how the testing quickly expands! Run node testing/equality_with_errors.js to see the output. That's more like it! Isn't that nice?
Yes and no. There are a few problems with this code:
- It isn't evented
- It hard-codes test objects
- It is very redundant
- It isn't scalable
Well, then, what are other options?
Nodeunit
Nodeunit is a framework similar to nunit in that it allows for multiple test cases (running in parallel), and supports mocks and stubs. It is easy to use, and even allows you to run tests in the browser.
Nodeunit testing starts with exporting a test or two from a module.
// testing/nodeunit_basics.js
module.exports = {
'Test 1' : function(test) {
test.expect(1);
test.ok(true, "This shouldn't fail");
test.done();
},
'Test 2' : function(test) {
test.expect(2);
test.ok(1 === 1, "This shouldn't fail");
test.ok(false, "This should fail");
test.done();
}
};
Here, we have a module exporting two tests, Test 1 and Test 2. You may have noticed that the test object in the functions have an ok() method just like the assert module mentioned above. Good eye. In fact, test supports all of the assert functions and adds two others: expect(number) and done(). The expect function tells nodeunit how many tests are being run within the context of the current test case. When all tests are finished, call test.done() to let nodeunit know the test case has completed (and a callback may have failed).
The output of nodeunit is visually helpful.
$ nodeunit src/testing/nodeunit_basics.js
nodeunit_basics.js
✔ Test 1
✖ Test 2
Assertion Message: This should fail
AssertionError: false == true
at Object.ok (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/types.js:81:39)
at /home/jim/projects/masteringnode/src/testing/nodeunit_basics.js:10:14
at Object.runTest (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:54:9)
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:90:21
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:508:13
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:118:25
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:129:25
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:510:17
at Array.<anonymous> (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/types.js:144:17)
at EventEmitter._tickCallback (node.js:108:26)
FAILURES: 1/3 assertions failed (8ms)
Nodeunit will list all test cases run within the test, followed by any AssertionError output and the number of passing or failing assertions. This is the default (minimal) output.
Nodeunit reporters
Nodeunit ships with a number of reporters and it is possible to add custom reporters.
$ nodeunit --list-reporters Build-in reporters: * default: Default tests reporter * minimal: Pretty minimal output * junit: jUnit XML test reports * html: Report tests result as HTML * skip_passed: Skip passed tests output * browser: Browser-based test reporter
To output to junit, run the command as:
$ cd src/testing && nodeunit --reporter junit nodeunit_basics.js --output junit.out
This creates an xml file (whitespace has been condensed):
// testing/junit.out/nodeunit_basics.js.xml
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite name="nodeunit_basics.js"
errors="0"
failures="0"
tests="2">
<testcase name="Test 1">
</testcase>
<testcase name="Test 2">
</testcase>
</testsuite>
This is great, but in a real-world development environment, you may be asked to write reports with a specific format, wording, or links (in html) to files with failing test cases. Luckily, nodeunit allows us to customize this output.
Nodeunit Custom reporters
To write a custom reporter for nodeunit, first decide how you'd like nodeunit to report information about your tests. As a simple example, let's take a look at a different take on the minimal reporter.
Here are the modifications I'd like to see:
- Show the start time of the test
- Show the filename as bold/green
- Add [PASS] or [FAIL] after the ✔ or ✖
- Prefix a test case with a '|'
These may seem like contrived requirements. But, what if my manager wants me to parse textual output for [FAIL] and, for whatever reason, it has to say [FAIL]?
The modifications to the minimal reporter are too spread out to include inline here, so be sure to check out the file at ./src/testing/reporterse/example.js.
Here is the slightly modified minimal output, meeting all of the requirements.
$ cd src/testing && nodeunit --reporter reporters/example.js nodeunit_basics.js
Tests started: Tue Mar 22 2011 21:24:42 GMT-0700 (PDT)
nodeunit_basics.js:
✔ [PASS] | Test 1
✖ [FAIL] | Test 2
AssertionError: false == true
at Object.ok (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/types.js:81:39)
at /home/jim/projects/masteringnode/src/testing/nodeunit_basics.js:10:14
at Object.runTest (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:54:9)
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:90:21
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:508:13
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:118:25
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:129:25
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:510:17
at Array.<anonymous> (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/types.js:144:17)
at EventEmitter._tickCallback (node.js:108:26)
FAILURES: 1/3 assertions failed (9ms)
These were small modifications, but following through the reporters included in nodeunit, it will be easy to output test reports to your desired format.
[node.js] Mastering Node excerpt: Addons
Addons
The node documentation for addons is self-admittedly pretty weak as of v0.4.0.
This chapter doesn't aim to be a replacement for the official documentation. Instead, we'd hope this can expand on some of the basics a little more than a simple "Hello, World!" and drive you as a developer more on the path toward mastering node through its source code.
In fact, for now, we're only going to cover some shortcuts for creating properties on an object, functions, and interacting with function prototypes. This doesn't reach the evented level of node's awesomeness, but you should be able to look at examples in node's source and the documention for libev and libeio to find answers.
Pre-requisites
* Some C/C++ knowledge
* V8 JavaScript
* Internal Node libraries
* libev
* libeio
hello.node
Our first example is the very same one from node's docs. We're going to include it for those who haven't read through the docs and have instead trusted in the knowledge of this ebook's authors (thanks, by the way).
A node addon begins with a source file containing a single entry point:


