Skip to content

Instantly share code, notes, and snippets.

@ahem
Created January 11, 2012 00:29
Show Gist options
  • Save ahem/1592195 to your computer and use it in GitHub Desktop.
Save ahem/1592195 to your computer and use it in GitHub Desktop.
A small node.js script to wrap MooTools.More in RequireJS defines
/*jshint node:true, funcscope:true */
var path = require('path');
var fs = require('fs');
var jsyaml = require('js-yaml');
function checkForError(err) {
if (err) { exitWithUsage(err); }
}
// =============================================================================
function createManifest(filename, cb) {
if (!filename) { return cb("no filename"); }
var base = path.dirname(filename);
var map = {};
fs.open(filename, 'r', function (err, fh) {
if (err) { return cb(err); }
var files = jsyaml.load(fh);
var manifest = {};
var cnt = 0;
files.sources.forEach(function (fn) {
fs.open(base + '/' + fn, 'r', function (err, fh) {
try {
jsyaml.safeLoadAll(fh, function (header) {
if (header.name) {
cnt++;
var module = fn
.replace('.js', '')
.replace('Source/', '')
.replace('More/More', 'MooTools.More');
header.file = base + '/' + fn;
header.module = module;
header.requires = header.requires
.filter(function (x) { return !x.match(/^Core/); })
.map(function (x) { return x[0] === '/' ? x.slice(1) : x; });
if (header.provides.indexOf('MooTools.More') >= 0) {
header.provides.push('More/MooTools.More');
}
manifest[module] = header;
}
});
} catch (e) {
// silently skip non-yaml parts of files, rethrow other exceptions
if (e.name !== 'ScannerError') {
throw e;
}
}
if (cnt === files.sources.length) {
cb(null, manifest);
}
});
});
});
}
function writeFile(writeFn, readFn, startScript, endScript, cb) {
var dir = path.dirname(writeFn);
fs.mkdir(dir, function (err) {
var out_stream = fs.createWriteStream(writeFn);
out_stream.write(startScript);
out_stream.once('drain', function () {
var in_stream = fs.createReadStream(readFn);
in_stream.pipe(out_stream, { end: false });
in_stream.once('end', function () {
out_stream.end(endScript);
});
});
});
}
function mapRequirement(manifest) {
return function (item) {
for (var k in manifest) {
if (manifest[k].provides.indexOf(item) >= 0) {
return '../' + k;
}
}
throw "Cannot find anything that provides '" + item + "'";
};
}
function generateFiles(manifest, root, cb) {
for (var key in manifest) {
var header = manifest[key];
var readFn = header.file;
var writeFn = root + '/' + key + '.js';
var startScript = 'define([';
if (header.requires.length) {
var requirements = header.requires.map(mapRequirement(manifest));
startScript += "'" + requirements.join("', '") + "'";
}
startScript += '], function () {\n';
var endScript = '';
if (header.name.split('.').length < 3 && header.name.match(/^[a-z0-9_\$\.]+$/i)) {
endScript = 'return ' + header.name + ' });\n';
} else {
endScript = 'return {} });\n';
}
writeFile(writeFn, readFn, startScript, endScript, checkForError);
}
}
// =============================================================================
function exitWithUsage(err) {
if (err && err !== true) {
console.log('\n' + err);
}
var scriptname = path.basename(process.argv[1]);
console.log('\nUsage: \n node ' + scriptname + ' OUTPUT_DIR PACKAGE.YML\n');
process.exit();
}
function main() {
if (process.argv.length < 4) {
exitWithUsage();
}
createManifest(process.argv[3], function (err, manifest) {
if (err) {
exitWithUsage(err);
}
generateFiles(manifest, process.argv[2], checkForError);
});
}
main();
process.on('uncaughtException', exitWithUsage);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment