Created
January 11, 2012 00:29
-
-
Save ahem/1592195 to your computer and use it in GitHub Desktop.
A small node.js script to wrap MooTools.More in RequireJS defines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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