Permalink
Browse files

Merge branch '2012-03-05_UglifyII'

  • Loading branch information...
2 parents 7488bf0 + 2081ed2 commit d87187deae2571d4d249061bb216b54ed2defc46 @dsimard committed Mar 9, 2012
Showing with 126 additions and 168 deletions.
  1. +6 −7 README.md
  2. +12 −22 bin/ready.js
  3. +23 −10 lib/config.js
  4. +27 −78 lib/ready.js
  5. +0 −1 lib/usage.txt
  6. +4 −1 lib/utils.js
  7. +6 −6 package.json
  8. +48 −43 test/test.js
View
13 README.md
@@ -1,9 +1,9 @@
![alt text](http://s3.amazonaws.com/files.posterous.com/headers/2452232/scaled500.png "ready.js - continuous javascript integration")
## What does it do?
-1. Check if your javascript are valid with [jslint](http://www.jslint.com/).
-2. Minify your javascript with [Closure Compiler](http://code.google.com/closure/compiler/) (optimize and minify your code).
-3. Watch your javascript files for jslint while you're coding.
+1. Check if your javascript files are valid with [jshint](http://www.jshint.com/).
+2. Compile your javascript files with [Uglify JS](http://marijnhaverbeke.nl/uglifyjs).
+3. Watch your javascript files for jshint while you're coding.
4. Create an aggregated file of all your javascripts.
## Installation
@@ -19,14 +19,13 @@
-w | --watch SRC watch the files with JSLint in SRC
-o | --order FILES specify an order (ex : --order "jquery.js, jquery.ui.js")
-e | --exclude FILES exclude the FILES from JSLint and compilation (ex : -e "jquery.js")
- -i | --installcompiler PATH install the google compiler specified by PATH
-compiledext EXT the compiled javascripts will have EXT as an extension
-aggregateto FILENAME the compiled javascripts will be aggregated to this FILENAME
--keep will keep the individual minified files
- --nojslint will not run JSLint
- --nocompiler will not run the compiler
- --norecursive will not look for files recursively
+ --no-analysis will not analyse the javascript files with jshint
+ --no-compile will not compile the javascript files with uglify-js
+ --no-recursive will not look for files recursively
JsLintOptions:
You can use any jsLint options (http://bit.ly/jslintoptions) as an argument.
View
34 bin/ready.js
@@ -28,7 +28,7 @@ function sortAggregates(a, b) {
}
function compile(file, callback) {
- if (config.runGCompiler && !util.isExcluded(file)) {
+ if (config.compile && !util.isExcluded(file)) {
logger.log("Compiling '" + file + "'");
r.compile(file, function(success, code, data) {
if (success) {
@@ -125,30 +125,20 @@ function aggregateAll() {
}
function startProcessing() {
- // Warn that the offline compiler isn't installed
- if (config.runGCompiler) {
- r.searchOfflineCompiler(function(compiler) {
- if (!compiler || compiler.length == 0) {
- logger.info("Google Closure Compiler not installed (http://code.google.com/closure/compiler/)");
- logger.info("Run " + "readyjs -i /path/to/compiler.jar".bold + " to install it locally");
- }
- });
- }
-
// Start the process
util.forEachJs(function(file) {
- if (config.runJslint && !util.isExcluded(file)) {
- // Run jslint
- r.jslint(file, function(success, jslint) {
+ if (config.analyse && !util.isExcluded(file)) {
+ // Run analysis
+ r.analyse(file, function(success, jshint) {
if (success) {
- logger.log("JSLINT success : " + file);
+ logger.log("Analysis success : " + file);
compile(file, aggregate);
} else {
- logger.log("JSLINT error : " + file);
- util.showJslintErrors(jslint);
+ logger.log("Analysis error : " + file);
+ util.showAnalysisErrors(jshint);
process.exit(1);
}
- }, config.jslintOptions);
+ }, config.analysisOptions);
} else {
compile(file, aggregate);
}
@@ -158,12 +148,12 @@ function startProcessing() {
function watchFiles() {
util.forEachJs(function(file) {
if (!util.isExcluded(file)) {
- r.watch(file, function(success, jslint) {
+ r.watch(file, function(success, jshint) {
if (success) {
- logger.log("JSLint on '" + file + "' : OK");
+ logger.log("Analysis on '" + file + "' : OK");
} else {
- logger.log("JSLint error on '" + file + "'");
- util.showJslintErrors(jslint);
+ logger.log("Analysis error on '" + file + "'");
+ util.showAnalysisErrors(jshint);
}
});
}
View
33 lib/config.js
@@ -9,31 +9,35 @@ var r = {
var c = { src : "./", // the source dir of js files
dest : "./compiled", // the destination of your minified files
compiledExtension : "min", // extension of the minified file
- runJslint : true, // if should run jsLintf
- runGCompiler : true, // if should run GoogleCompiler
+ analyse : true, // if should analyse the files with jslint
+ compile : true, // if should run the compiler
keepCompiled : false, // if should keep the minified files
aggregateTo : "all.js", // If a string is specified, all the .js will be aggregated to this file in the config.dest
order : [], // The order of aggregation (example : we want jquery before jquery.ui) Must not specified every file.
exclude : [], // Files that are not compiled but still aggregated
recursive : true, // Should look for javascript recursively
test : false, // If it's running from test environment
- jslintOptions: {} //config for jsLint
+ analysisOptions: {} // Options for the analysis (jshint)
};
// Add the args shortcut to avoid conflict
c.s = c.src,
c.d = c.dest,
c.compiledext = c.compiledExtension,
+ c.runJslint = c.analyse,
+ c.runGCompiler = c.compile,
c.aggto = c.aggregateTo,
c.keep = c.keepCompiled,
c.nocompiler = null,
c.nojslint = null,
c.norecursive = null,
c.e = c.exclude,
- c.o = c.order;
+ c.o = c.order,
+ c.jslintOptions = c.analysisOptions;
return c;
})(),
+
loadConfig : function(extConfig) {
extConfig = extConfig || {};
def = {};
@@ -52,10 +56,15 @@ var r = {
// Boolean inversion
r.config.keepCompiled = (argv["keep"] !== undefined) ? !def.keepCompiled : r.config.keepCompiled;
- r.config.runJslint = (argv["nojslint"] !== undefined) ? !def.runJslint : r.config.runJslint;
- r.config.runGCompiler = (argv["nocompiler"] !== undefined) ? !def.runGCompiler : r.config.runGCompiler;
- r.config.recursive = (argv["norecursive"] !== undefined) ? !def.recursive : r.config.recursive;
- r.config.debug = (argv["debug"] !== undefined) ? !def.debug : r.config.debug;
+ r.config.debug = (argv["debug"] !== undefined) ? !def.debug : r.config.debug;
+
+ // Override old config with new
+ r.config.analyse = (argv["nojslint"] !== undefined) ? !def.runJslint : r.config.runJslint;
+ r.config.analyse = (argv["analysis"] !== undefined) ? argv["analysis"]: r.config.analyse;
+ r.config.compile = (argv["nocompiler"] !== undefined) ? !def.runGCompiler : r.config.runGCompiler;
+ r.config.compile = (argv["compile"] !== undefined) ? argv["compile"] : r.config.compile;
+ r.config.recursive = (argv["norecursive"] !== undefined) ? !def.recursive : r.config.recursive;
+ r.config.recursive = (argv["recursive"] !== undefined) ? argv["recursive"] : r.config.recursive;
// Arrays
if (argv.e || argv.exclude) {
@@ -72,6 +81,10 @@ var r = {
});
}
+ // Aliases for backward compatibility
+ r.config.runJslint = r.config.analyse;
+ r.config.runGCompiler = r.config.compile;
+
// Every other arg parameters is considered a jslint option
var jslintArgs = Object.getOwnPropertyNames(argv).filter(function(element, index) {
return r.config[element] === undefined;
@@ -85,11 +98,11 @@ var r = {
v = boolMatch && boolMatch.length == 1 ? boolMatch[0] === "true" : null;
}
- if (v !== null) r.config.jslintOptions[i] = v;
+ if (v !== null) r.config.analysisOptions[i] = v;
});
// Minified extension must be letters or numbers
- if (r.config.runGCompiler && !r.config.compiledExtension.match(/^[0-9a-zA-Z]+$/)) {
+ if (r.config.compile && !r.config.compiledExtension.match(/^[0-9a-zA-Z]+$/)) {
logger.log("config.compiledExtension is not valid. Using 'min' as default value.");
r.config.compiledExtension = "min";
}
View
105 lib/ready.js
@@ -1,13 +1,15 @@
var sys = require("util"),
fs = require("fs"),
cp = require('child_process'),
- rest = require("../node_modules/restler"),
- jslint = require("../node_modules/readyjslint").JSLINT,
+ jshint = require("../node_modules/jshint").JSHINT,
path = require("path"),
config = require("./config"),
logger = require("./logger"),
+ uglify = require("uglify-js"),
+ jsp = uglify.parser,
+ pro = uglify.uglify,
inspect = require("util").inspect;
-
+
var r = {
// Get the code from fileOrCode
getCode : function(fileOrCode, callback) {
@@ -20,93 +22,40 @@ var r = {
callback(fileOrCode);
}
},
- // Look for offline compiler
- searchOfflineCompiler : function(callback) {
- var compiler = path.join(__dirname, "../../../compiler.jar");
- path.exists(compiler, function(exists) {
- if (exists) {
- callback(compiler);
- } else {
- compiler = path.join(__dirname, "../vendor/compiler.jar");
- path.exists(compiler, function(exists) {
- if (exists) {
- callback(compiler);
- } else {
- callback();
- }
- });
- }
- });
- },
// Compile the code
- compile : function(fileOrCode, callback) {
- // Check if there's an offline compiler
- r.searchOfflineCompiler(function(compilerPath) {
- if (compilerPath) {
- r.compileOffline(compilerPath, fileOrCode, callback);
- } else {
- r.compileOnline(fileOrCode, callback);
- }
- });
- },
- // Compile offline
- compileOffline : function(compilerPath, file, callback) {
- var cmd = ["java", "-jar", compilerPath, "--js", file].join(" ");
-
- cp.exec(cmd, function(err, stdout, stderr) {
- if (err) {
- logger.warn("Could not compile " + file);
- logger.error(stderr);
- } else {
- r.compileCompleted(null, stdout, callback);
- }
- });
- },
- // Compile online
- compileOnline : function(fileOrCode, callback) {
- r.getCode(fileOrCode, function(code) {
- // Don't send to google compiler in test
- var params = {"js_code" : code,
- "compilation_level" : "SIMPLE_OPTIMIZATIONS",
- "output_format" : "json",
- "output_info" : "compiled_code"
- };
-
- var completed = function(data) {
- r.compileCompleted(data, code, callback);
+ compile : function(file, callback) {
+ r.getCode(file, function(code) {
+ try {
+ var ast = jsp.parse(code);
+ ast = pro.ast_mangle(ast);
+ ast = pro.ast_squeeze(ast);
+ var compiledCode = pro.gen_code(ast);
+
+ callback(true, compiledCode);
+ } catch(e) {
+ logger.info(inspect(e));
+ logger.error("Compile error for '" + file + "'");
}
- if (config.test) {
- completed();
- } else {
- var url = "http://closure-compiler.appspot.com/compile";
- rest.post(url, {data : params}).addListener('complete', completed);
- }
- });
- },
- // On compile completed
- compileCompleted : function(data, code, callback) {
- var newData = {compiledCode : code};
-
- if (data) { newData = JSON.parse(data); }
-
- var success = newData.compiledCode && newData.compiledCode.length > 0 && !newData.serverErrors;
- callback(success, newData.compiledCode, newData);
+ });
},
- // Check with jslint
- jslint : function(fileOrCode, callback, options) {
+ // Analyse with jshint
+ analyse : function(fileOrCode, callback, options) {
r.getCode(fileOrCode, function(code) {
- var success = jslint(code, options);
- callback(success, jslint);
+ var success = jshint(code, options);
+ callback(success, jshint);
});
},
// Watch a file
watch : function(file, callback) {
- r.jslint(file, callback);
- fs.watchFile(file, function() {r.jslint(file, callback);});
+ r.jshint(file, callback);
+ fs.watchFile(file, function() {r.jshint(file, callback);});
}
};
+// Aliases
+r.analyze = r.analyse;
+
module.exports = r;
View
1 lib/usage.txt
@@ -6,7 +6,6 @@ options:
-w | --watch SRC watch the files with JSLint in SRC
-o | --order FILES specify an order (ex : --order "jquery.js, jquery.ui.js")
-e | --exclude FILES exclude the FILES from JSLint and compilation (ex : -e "jquery.js")
- -i | --installcompiler PATH install the google compiler specified by PATH
-compiledext EXT the compiled javascripts will have EXT as an extension
-aggregateto FILENAME the compiled javascripts will be aggregated to this FILENAME
View
5 lib/utils.js
@@ -63,7 +63,7 @@ var r = {
return config.exclude.indexOf(filename) >= 0
},
// Show formated jslint errors
- showJslintErrors : function (jslint) {
+ showAnalysisErrors : function (jslint) {
jslint.errors.reverse().forEach(function(e) {
if (e) {
logger.log([e.line.toString(), ",", e.character.toString(), " : ",
@@ -115,4 +115,7 @@ var r = {
}
}
+// Aliases
+r.showJslintErrors = r.showAnalysisErrors;
+
module.exports = r;
View
12 package.json
@@ -1,19 +1,19 @@
{
"name" : "ready.js",
- "version" : "1.3.6",
+ "version" : "2.0.0",
"description" : "continuous javascript integration",
- "keywords" : ["continuous integration", "jslint", "javascript", "minifier", "compiler", "ci"],
+ "keywords" : ["continuous integration", "jslint", "javascript", "minifier", "compiler", "ci", "uglifier"],
"author" : "dsimard <dsimard@azanka.ca> (http://github.com/dsimard)",
"bin" : { "readyjs" : "./bin/ready.js" },
"repository" : {
"type" : "git",
"url" : "https://dsimard@github.com/dsimard/ready.js.git"
},
"dependencies" : {
- "readyjslint" : "0.0.4",
- "restler" : "0.2.X",
- "optimist" : "0.3.X",
- "colors" : "~0.6.0"
+ "optimist" : "~0.3.1",
+ "colors" : "~0.6.0",
+ "uglify-js" : "~1.2.5",
+ "jshint" : "~0.5.9"
},
"engines" : {"node" : ">=0.6.0"}
}
View
91 test/test.js
@@ -5,6 +5,7 @@ var sys = require("util"),
a = require("assert"),
r = require("../lib/ready"),
path = require("path"),
+ colors = require("../node_modules/colors"),
inspect = require("util").inspect;
const SRC = "./test/javascripts/";
@@ -81,7 +82,7 @@ function getConfig(extend) {
function createFile(path, code, options) {
options = options || {};
- code = code || ["function load() {}"].join("");
+ code = code || ["function load() {} // not compiled"].join("");
// Create the SRC directory if not exists
var isDir = false;
@@ -187,20 +188,13 @@ function getAggCode(config) {
// All tests to run
var tests = {
- // Check if compiler.jar is present in vendor
- "check compiler.jar" : function(onEnd) {
- path.exists("vendor/compiler.jar", function(exists) {
- a.ok(exists, "Compiler.jar MUST exist in 'vendor'");
- onEnd();
- });
- },
- // jslint
- "jslint" : function(onEnd) {
- r.jslint("function load() {}", function(success, jslint) {
+ // Analyse
+ "analyse" : function(onEnd) {
+ r.analyse('function load() {}', function(success, jslint) {
a.ok(success);
a.ok(jslint.errors.length == 0);
- r.jslint("function load() {", function(success, jslint) {
+ r.analyse("function load() {", function(success, jslint) {
a.ok(!success);
a.ok(jslint.errors.length == 1);
@@ -210,7 +204,7 @@ var tests = {
},
"jslint with options" : function(onEnd) {
- r.jslint("var f = eval('1');", function(success, jslint) {
+ r.analyse("var f = eval('1');", function(success, jslint) {
a.ok(success);
a.ok(jslint.errors.length == 0);
onEnd();
@@ -369,7 +363,7 @@ var tests = {
exec(getConfig({exclude:["a.js"]}), function(error, stdout) {
var code = fs.readFileSync(DEST + ALL).toString();
a.equal(code.match(/load\(\)\s\{\}/).length, 1);
- a.equal(code.match(/load\(\)\{\}\;/g).length, 2);
+ a.equal(code.match(/load\(\)\{\}/g).length, 2);
onEnd();
});
@@ -380,7 +374,7 @@ var tests = {
execArgv(getConfig(), "--exclude 'a.js'", function(error, stdout) {
var code = fs.readFileSync(DEST + ALL).toString();
a.equal(code.match(/load\(\)\s\{\}/).length, 1);
- a.equal(code.match(/load\(\)\{\}\;/g).length, 2);
+ a.equal(code.match(/load\(\)\{\}/g).length, 2);
onEnd();
});
@@ -400,31 +394,8 @@ var tests = {
onEnd();
});
},
- // Google compiler server error
- "Google compiler server error" : function(onEnd) {
- var _completed = r.compileCompleted;
-
- r.compileCompleted = function(data, code, callback) {
- data = {serverErrors:[{code:22, error:"Too many compiles performed recently. Try again later."}]};
- _completed(data, code, callback);
- }
-
- createTwoFiles();
- exec(null, function(error, stdout) {
- a.throws(function() {
- fs.statSync(DEST + "js.min.js");
- });
-
- a.throws(function() {
- fs.statSync(DEST + "js2.min.js");
- });
-
- r.compileCompleted = _completed;
- onEnd();
- });
- },
- // Google compiler error
- "Google compiler error" : function(onEnd) {
+ // compiler error
+ "compiler error" : function(onEnd) {
createBadFile();
exec(getConfig({test:false, runJslint:false}), function(error, stdout) {
a.throws(function() {
@@ -434,6 +405,8 @@ var tests = {
a.throws(function() {
fs.statSync(DEST + "js2.min.js");
});
+
+ a.ok(stdout.match(/Unexpected token/i))
onEnd();
});
@@ -542,6 +515,7 @@ var tests = {
createBadFile();
execArgv(getConfig(), "--nojslint --nocompiler", function(error, stdout, stderr) {
+
// It just dumped to all.js
var code = fs.readFileSync(DEST + ALL).toString();
a.equal(code.match(/\sbad\.js\s/).length, 1);
@@ -576,9 +550,41 @@ var tests = {
createFile("file.js", "function subdir2() {}", {subdir:"subdir2"});
execNoConfig(SRC + " " + DEST, function(err, stdout, stderr) {
+ var code = fs.readFileSync(DEST + ALL).toString();
+ a.equal(code.match(/\sfile\.js\s/ig).length, 3);
onEnd();
});
},
+ "no recursive" : function(onEnd) {
+ createFile("file.js", "function main() {}");
+ createFile("file.js", "function subdir1() {}", {subdir:"subdir1"});
+ createFile("file.js", "function subdir2() {}", {subdir:"subdir2"});
+
+ execArgv(getConfig(), "--no-recursive", function(error, stdout, stderr) {
+ var code = fs.readFileSync(DEST + ALL).toString();
+ a.equal(code.match(/\sfile\.js\s/ig).length, 1);
+
+ execArgv(getConfig(), "--norecursive", function(error, stdout, stderr) {
+ var code = fs.readFileSync(DEST + ALL).toString();
+ a.equal(code.match(/\sfile\.js\s/ig).length, 1);
+ onEnd();
+ });
+ });
+ },
+ "try new options" : function(onEnd) {
+ createTwoFiles();
+ createBadFile();
+
+ execArgv(getConfig(), "--no-analysis --no-compile", function(error, stdout, stderr) {
+
+ // It just dumped to all.js
+ var code = fs.readFileSync(DEST + ALL).toString();
+ a.equal(code.match(/\sbad\.js\s/).length, 1);
+ a.equal(code.match(/\js\.js\s/).length, 1);
+
+ onEnd();
+ });
+ },
};
if (process.argv[2]) {
@@ -587,7 +593,7 @@ if (process.argv[2]) {
cleanUp();
tests[t](cleanUp);
} else {
- console.log("ERROR : '"+t+"' does not exist")
+ console.log(("ERROR : '"+t+"' does not exist").red)
}
} else {
var keys = [];
@@ -599,10 +605,9 @@ if (process.argv[2]) {
cleanUp();
var key = keys.shift();
if (key) {
- console.log("Running " + key + "...");
+ console.log(("\n"+key).bold);
if (tests[key]) {
tests[key](execTest);
- console.log("----------");
}
}
})();

0 comments on commit d87187d

Please sign in to comment.