Skip to content

Instantly share code, notes, and snippets.

@carlos8f
Last active May 1, 2016 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlos8f/cd931ba95481a7570602 to your computer and use it in GitHub Desktop.
Save carlos8f/cd931ba95481a7570602 to your computer and use it in GitHub Desktop.
mayonnaise
node_modules
example
var dollop = require('dollop')
, path = require('path')
, inherits = require('util').inherits
, EventEmitter = require('events').EventEmitter
, parsedUrls = {}
, fs = require('fs')
, parseUrl = require('url').parse
/**
* specs:
* [
* {
* cwd: '/var/frameworks/supergood',
* globs: ['standard/robots.txt', 'standard/favicon.ico']
* },
* {
* cwd: '/home/bob/website',
* globs: ['assets/*.css', 'assets2/*.png']
* }
* ]
**/
function Mayonnaise (specs, options) {
if (specs && toString.call(specs) === '[object Object]') {
options = specs;
specs = '.';
}
options || (options = {});
this.options = options;
EventEmitter.call(this);
this.setMaxListeners(0);
var self = this;
this.pluginLookup = {};
this.ready = false;
// magic
if (!Array.isArray(specs)) specs = [specs];
var latch = specs.length;
this.dollops = specs.map(function (spec, idx) {
var opts = {cwd: spec.cwd};
Object.keys(options).forEach(function (k) {
if (k !== 'cwd') opts[k] = options[k];
});
return dollop(spec.globs || spec, opts)
.on('all', function (op, file) {
switch (op) {
case 'add':
if (file.stat.isFile()) {
file.pluginPath = self.makePluginPath(file);
if (typeof self.pluginLookup[file.pluginPath] === 'undefined') {
self.pluginLookup[file.pluginPath] = [];
}
if (!~self.pluginLookup[file.pluginPath].indexOf(file)) {
self.pluginLookup[file.pluginPath].push(file);
}
}
file.weight = idx;
case 'update':
file.plugin = self.compile(file);
break;
case 'remove':
break;
case 'reset':
// @todo: how to handle this
//self.ready = false;
//self.latch++;
return;
case 'ready':
if (!self.ready && !--latch) {
self.ready = true;
self.emit('ready', self.files());
}
return;
default: return;
}
self.emit(op, file);
self.emit('all', op, file);
})
});
}
inherits(Mayonnaise, EventEmitter);
Mayonnaise.prototype.makePluginPath = function (file) {
return file.key.replace(/\.[^\.]+$/, '');
};
Mayonnaise.prototype.compile = function (file) {
// override this method
};
Mayonnaise.prototype.files = function () {
return this.dollops.reduce(function (prev, d) {
return prev.concat(d.files());
}, []);
};
// return a file by key, if found.
// options:
// - merge (function): if set, a function(a, b) to merge results
// - priority: (string, default 'last') give priority to 'first' or 'last' dollop
Mayonnaise.prototype.get = function (key, options) {
options || (options = {});
var self = this;
var files = this.dollops.reduce(function (prev, d) {
var file = d.get(key);
if (file) prev.push(file);
return prev;
}, []);
if (options.priority === 'first') files.reverse();
if (options.merge) {
var ret;
files.forEach(function (file) {
if (ret) ret = options.merge(ret, file);
else ret = file;
});
return ret;
}
else return options.merge === 'first' ? files[0] : files[files.length - 1];
};
// return the active plugin file, if found.
// options:
// - merge (function): if set, a function(a, b) to merge results, and note that
// only the merged plugin content will be returned, not the plugin file.
// - priority: (string) give priority to 'first' or 'last' dollop
Mayonnaise.prototype.getPlugin = function (p, options) {
options || (options = {});
var self = this, ret;
var files = this.pluginLookup[p] || [];
files = files.slice();
if (options.priority === 'first') files.reverse();
files.forEach(function (file) {
if (options.merge) {
var compiled = self.compile(file);
if (typeof ret === 'undefined') ret = compiled;
else ret = options.merge(ret, compiled);
}
else {
if (!file.plugin) file.plugin = self.compile(file);
ret = file;
}
});
return ret;
};
Mayonnaise.prototype.close = function () {
this.dollops.forEach(function (d) {
d.close();
});
};
module.exports = function (specs, options) {
return new Mayonnaise(specs, options);
};
module.exports.Mayonnaise = Mayonnaise;
{
"name": "mayonnaise",
"version": "0.3.3",
"main": "index.js",
"scripts": {
"test": "test -d example || tar -xf example.tar.gz && ./node_modules/.bin/mocha --reporter spec --timeout 10s --bail"
},
"repository": {
"type": "git",
"url": "git@gist.github.com:/cd931ba95481a7570602.git"
},
"author": "Carlos Rodriguez <carlos@s8f.org> (http://s8f.org/)",
"license": "MIT",
"dependencies": {
"dollop": "^0.4.4",
"minimatch": "^3.0.0"
},
"devDependencies": {
"mocha": "^2.4.5"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment