Skip to content

Instantly share code, notes, and snippets.

@alexindigo
Created June 18, 2014 07:20
Show Gist options
  • Save alexindigo/e67ac202d9e385600f88 to your computer and use it in GitHub Desktop.
Save alexindigo/e67ac202d9e385600f88 to your computer and use it in GitHub Desktop.
Workaround for BusterJS EMFILE problem – https://github.com/busterjs/buster/issues/347

Workaround a.k.a. deep-down-the-rabbit-hole hack for busterjs EMFILE problem somehow OSX decided that 256 of open files is enough for each process :) re: busterjs/buster#347

Contains of the executable buster-test-workaround.js, which could be used as drop-in replacement for buster-test.

And second file grunt_options_buster.js helps to point your grunt task to the workaround executable instead of original buster-test.

#!/usr/bin/env node
// workaround for buster-test cli executable
// could be called from command line the same way as `buster-test`
// with all the arguments and whatnot
//
// To make it work you'd need to install `graceful-fs` module
// from here: https://www.npmjs.org/package/graceful-fs
//
// Also it expects `buster-test` to be installed locally within your project
// if you're using global `buster` command update `originalBusterTest` accordingly
//
// Don't forget to make it executable
var originalBusterTest = './node_modules/.bin/buster-test';
// "better" fs
var fs = require('graceful-fs');
// override file-resolver
var fileResolver = require('buster/node_modules/buster-test-cli/node_modules/buster-cli/node_modules/buster-configuration/node_modules/ramp-resources/lib/resource-file-resolver.js');
// extra allowances for promises
var when = require('buster/node_modules/when');
fileResolver._prepareResource = fileResolver.prepareResource;
fileResolver.prepareResource = function(rootPath, path, resource)
{
var promise = fileResolver._prepareResource(rootPath, path, resource);
var fileName = fileResolver.absolutePath(rootPath, path);
// replace original resource.content method
// with new shiny thing
resource.content = resourceContent.bind(resource, fileName);
return promise;
};
// require original buster-test
// to make it part of the process
require(originalBusterTest);
// new content resolver
function resourceContent(fileName)
{
var d = when.defer();
fs.readFile(fileName, this.encoding, function (err, data) {
if (err) { return d.resolver.reject(err); }
d.resolver.resolve(data);
});
return d.promise;
};
// In case if you're using `grunt-buster`
// this is extra piece for your grunt job config file
// overrides `grunt-buster`s cmd.findExecutable method
// to point to the workaround file
module.exports =
{
// your grunt-buster options
};
// Workaround a.k.a. deep-down-the-rabbit-hole hack
// resolves `buster-test` into custom workaround file
// leaving as is everything else
var gruntBuster = require('grunt-buster/tasks/buster/cmd');
gruntBuster._findExecutable = gruntBuster.findExecutable;
gruntBuster.findExecutable = function(cmd, callback)
{
// site/buster-test-workaround.js
return gruntBuster._findExecutable(cmd, function(err, candidate)
{
// create middleman to continue with faking fs module
// for the executable down below
if (!err && cmd == 'buster-test')
{
candidate = './buster-test-workaround.js';
}
return callback(err, candidate);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment