coffeemill
Version:
CoffeeScript project manager
406 lines (357 loc) • 13.3 kB
JavaScript
// Generated by CoffeeScript 1.6.2
(function() {
var CoffeeMill, Deferred, coffee, colors, commander, ejs, fs, jade, path, spawn, sys, uglify,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
sys = require('sys');
path = require('path');
fs = require('fs');
spawn = require('child_process').spawn;
Deferred = require('jsdeferred').Deferred;
commander = require('commander');
uglify = require('uglify-js');
colors = require('colors');
ejs = require('ejs');
jade = require('jade');
coffee = require('coffee-script');
CoffeeMill = (function() {
var EXT_NAMES;
EXT_NAMES = ['.coffee'];
CoffeeMill.rTagVersion = /^v?([0-9\.]+)$/;
CoffeeMill.rDocComment = /\/\*\*([\s\S]+?)\*\/\s*(.*)/g;
CoffeeMill.rParam = /\s+{?(\S+?)}?\s+(\S+)\s+(.*)/g;
CoffeeMill.rReturn = /\s+{?(\S+?)}?\s+(.*)/g;
CoffeeMill.rCompletelyBlank = /^\s*$/;
CoffeeMill.rLineEndSpace = /[ \t]+$/g;
CoffeeMill.rBreak = /[\r\n]{3,}/g;
function CoffeeMill(cwd) {
var list;
this.cwd = cwd;
this.changed = __bind(this.changed, this);
list = function(val) {
return val.split(',');
};
commander.version(JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'))).version).usage('[options]').option('-n, --name <basename>', 'output directory (defualt is \'\')', '').option('-i, --input <dirnames>', 'output directory (defualt is \'src\')', list, ['src']).option('-o, --output <dirnames>', 'output directory (defualt is \'lib\')', list, ['lib']).option('-u, --uglify', 'minify with uglifyJS (.min.js)').option('-m, --map', 'generate source maps (.map)').option('-w, --watch', 'watch the change of input directory recursively').option('-v, --ver <version>', 'file version: supports version string, \'gitTag\' or \'none\' (default is \'none\')', 'none').parse(process.argv);
console.log(commander);
this.scanInput();
this.compile();
}
CoffeeMill.prototype.scanInput = function() {
var watcher, _i, _len, _ref;
_ref = this.watchers != null;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
watcher = _ref[_i];
watcher.close();
}
this.watchers = [];
return this.files = this.findFiles(commander.input, commander.watch ? this.changed : null);
};
CoffeeMill.prototype.findFiles = function(dirs, change, basedir, files) {
var childs, className, code, dir, dirPath, extendsName, extname, file, filePath, i, isBasedir, name, packages, r, stats, _i, _j, _len, _len1;
if (files == null) {
files = [];
}
isBasedir = basedir != null;
for (_i = 0, _len = dirs.length; _i < _len; _i++) {
dir = dirs[_i];
if (isBasedir) {
dirPath = dir;
} else {
dirPath = basedir = dir;
}
stats = fs.statSync(dirPath);
if (stats.isFile()) {
filePath = dirPath;
if (EXT_NAMES.indexOf(path.extname(filePath)) !== -1) {
packages = path.relative(basedir, filePath).split(path.sep);
packages.pop();
extname = path.extname(filePath);
name = path.basename(filePath, extname);
code = fs.readFileSync(filePath, 'utf8');
r = code.match(/class\s+(\w+)(?:\s+extends\s+(\w+))?/m);
if (r != null) {
r[0], className = r[1], extendsName = r[2];
}
files.push({
filePath: filePath,
extname: extname,
packages: packages,
name: name,
extendsName: extendsName || '',
code: code
});
}
} else if (stats.isDirectory()) {
if (change != null) {
this.watchers.push(fs.watch(dirPath, change));
}
childs = fs.readdirSync(dirPath);
for (i = _j = 0, _len1 = childs.length; _j < _len1; i = ++_j) {
file = childs[i];
childs[i] = path.join(dirPath, file);
}
this.findFiles(childs, change, basedir, files);
}
}
return files;
};
CoffeeMill.prototype.changed = function() {
var _this = this;
clearTimeout(this.timeoutId);
return this.timeoutId = setTimeout(function() {
_this.scanInput();
return _this.compile();
}, 100);
};
CoffeeMill.prototype.compile = function() {
var _this = this;
sys.puts(new Date().toString().underline);
return Deferred.next(function() {
switch (commander.ver) {
case 'none':
return '';
case 'gitTag':
return _this.gitTag();
default:
return commander.ver;
}
}).error(function(err) {
return '';
}).next(function(version) {
var code, codes, exp, exports, file, filename, output, outputDir, pkg, postfix, v3SourceMap, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
if (version !== '') {
sys.puts('version: ' + version);
postfix = "-" + version;
} else {
postfix = '';
}
_this.files.sort(function(a, b) {
if (a.extendsName === '') {
return -1;
} else if (b.extendsName === '') {
return 1;
} else if (b.extendsName === a.name) {
return -1;
} else if (a.extendsName === b.name) {
return 1;
} else {
return 0;
}
});
codes = [];
exports = {};
_ref = _this.files;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
file = _ref[_i];
codes.push(file.code);
exp = exports;
_ref1 = file.packages;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
pkg = _ref1[_j];
if (exp[pkg] == null) {
exp[pkg] = {};
}
exp = exp[pkg];
}
exp[file.name] = file.name;
}
codes.push('window[k] = v for k, v of ' + JSON.stringify(exports, null, 2).replace(/(:\s+)"(\w+)"/g, '$1$2'));
code = codes.join('\n\n');
_ref2 = commander.output;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
outputDir = _ref2[_k];
output = path.join(_this.cwd, outputDir);
if (!fs.existsSync(output)) {
fs.mkdirSync(output);
}
filename = "" + commander.name + postfix + ".coffee";
output = path.join(_this.cwd, outputDir, filename);
fs.writeFileSync(output, code, 'utf8');
sys.puts('concat : '.cyan + output);
_this.copy(code, filename);
_ref3 = _this.coffee(code, {
sourceMap: true,
generatedFile: "" + commander.name + postfix + ".js",
sourceRoot: '',
sourceFiles: ["" + commander.name + postfix + ".coffee"]
}), code = _ref3.js, v3SourceMap = _ref3.v3SourceMap;
if (commander.map) {
code += "\n/*\n//@ sourceMappingURL=" + commander.name + postfix + ".map\n*/";
}
filename = "" + commander.name + postfix + ".js";
output = path.join(_this.cwd, outputDir, filename);
fs.writeFileSync(output, code, 'utf8');
sys.puts('compile : '.cyan + output);
_this.copy(code, filename);
if (commander.map) {
filename = "" + commander.name + postfix + ".map";
output = path.join(_this.cwd, outputDir, filename);
fs.writeFileSync(output, v3SourceMap, 'utf8');
sys.puts('source map: '.cyan + output);
_this.copy(code, filename);
}
if (commander.uglify) {
code = uglify.minify(code, {
fromString: true
}).code;
filename = "" + commander.name + postfix + ".min.js";
output = path.join(_this.cwd, outputDir, filename);
fs.writeFileSync(output, code, 'utf8');
sys.puts('minify : '.cyan + output);
_this.copy(code, filename);
}
}
return sys.puts('complete!!'.green);
}).error(function(err) {
return sys.error(err.stack);
});
};
CoffeeMill.prototype.copy = function(code, filename) {
var output;
if (!commander.copy) {
return;
}
output = path.join(commander.copy, filename);
fs.writeFileSync(output, code, 'utf8');
return sys.puts('copy : '.cyan + output);
};
CoffeeMill.prototype.gitTag = function() {
var d, err, gitTag, out;
d = new Deferred();
gitTag = spawn('git', ['tag']);
out = '';
gitTag.stdout.setEncoding('utf8');
gitTag.stdout.on('data', function(data) {
return out += data;
});
err = '';
gitTag.stderr.setEncoding('utf8');
gitTag.stderr.on('data', function(data) {
return err += data.red;
});
gitTag.on('close', function() {
var i, minor, r, tag, tags, versions;
if (err !== '') {
return d.fail(err);
}
tags = out.split('\n');
i = tags.length;
while (i--) {
tag = tags[i];
r = tag.match(CoffeeMill.rTagVersion);
if ((r != null ? r[1] : void 0) == null) {
continue;
}
versions = r[1].split('.');
minor = parseInt(versions[versions.length - 1], 10);
versions[versions.length - 1] = minor + 1;
}
return d.call(versions.join('.'));
return d.fail('no tag as version');
});
return d;
};
CoffeeMill.prototype.jsdoc = function(wholeCode) {
var code, comment, doc, file, files, generateDoc, i, name, params, properties, r, r2, returns, _i, _len;
if (this.makefile.jsdoc.src.files != null) {
files = this.makefile.jsdoc.src.files;
for (i = _i = 0, _len = files.length; _i < _len; i = ++_i) {
file = files[i];
files[i] = path.join(this.cwd, commander.input, file);
}
code = this.concatFiles(files);
} else {
code = wholeCode;
}
properties = [];
while (r = CoffeeMill.rDocComment.exec(code)) {
comment = r[1];
name = r[2];
params = [];
returns = [];
comment = comment.replace(/^[ \t]*\/\/.*$/g, '').replace(/^[ \t]*\* ?/g, '');
comment = comment.replace(CoffeeMill.rParam, function(matched, type, name, description) {
var optional, r;
optional = false;
if (r = name.match(/^\[(.*)\]$/)) {
optional = true;
name = r[1];
}
r = name.split('=');
params.push({
types: type.split('|'),
optional: optional,
name: r[0],
defaultValue: r[1],
description: description
});
return '';
});
comment = comment.replace(CoffeeMill.rReturn, function(matched, type, description) {
returns.push({
types: type.split('|'),
description: description
});
return '';
});
if (CoffeeMill.rCompletelyBlank.test(comment)) {
continue;
}
r2 = name.match(/(\S+)\s*[:=]/);
if (typeof r2 === "function" ? r2([1] != null) : void 0) {
name = r2[1];
}
properties.push({
name: name,
comment: comment,
params: params,
returns: returns
});
}
switch (this.makefile.jsdoc.engine) {
case 'ejs':
generateDoc = ejs.compile(fs.readFileSync(this.makefile.jsdoc.template, 'utf8'), {
compileDebug: true
});
doc = generateDoc({
title: rawFilename,
properties: properties
}).replace(CoffeeMill.rLineEndSpace, '').replace(CoffeeMill.rBreak, '\n\n');
return fs.writeFileSync(this.makefile.jsdoc.filename, doc, 'utf8');
case 'jade':
generateDoc = jade.compile(fs.readFileSync(this.makefile.jsdoc.template, 'utf8'), {
compileDebug: true
});
doc = generateDoc({
title: rawFilename,
properties: properties
}).replace(CoffeeMill.rLineEndSpace, '').replace(CoffeeMill.rBreak, '\n\n');
return fs.writeFileSync(this.makefile.jsdoc.filename, doc, 'utf8');
}
};
CoffeeMill.prototype.concatFiles = function(files) {
var codes, file, _i, _len;
codes = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
codes.push(fs.readFileSync(file, 'utf8'));
}
return codes.join('\n\n');
};
CoffeeMill.prototype.coffee = function(code, options) {
var err;
try {
return coffee.compile(code, options);
} catch (_error) {
err = _error;
return sys.puts(("Compile Error: " + (err.toString())).red);
}
};
return CoffeeMill;
})();
exports.run = function() {
return new CoffeeMill(process.cwd());
};
}).call(this);
/*
//@ sourceMappingURL=coffeemill.map
*/