Permalink
Browse files

Basic windows support. No dependency on system executables (rm, lessc…

…, mkdir).

* Replaced 'gzip' with node's zlib.
* Replaced calls to 'lessc' with parsing via API.
* Updated dependencies to newest versions.
* Added vows dev dependency.
* Official support for node 0.6+ only.
* Added zip binary test.
  • Loading branch information...
1 parent 5db34cb commit a9f36ee1842c38ae4c43be8a71477cbb3592eee4 @GoalSmashers GoalSmashers committed Aug 3, 2012
View
@@ -1,5 +1,6 @@
.DS_Store
node_modules
+examples/.assets.yml.json
examples/public/javascripts/bundled
examples/public/stylesheets/bundled
examples/public/stylesheets/application.css
View
@@ -1,9 +1,10 @@
TEST_DIR = test
+VOWS = ./node_modules/vows/bin/vows
all: test
-
+
test:
@@echo "Running all tests via vows"
- @@vows ${TEST_DIR}/*-test.js
-
+ @@${VOWS} ${TEST_DIR}/*-test.js
+
.PHONY: all test
View
@@ -3,9 +3,10 @@
var fs = require('fs'),
path = require('path'),
util = require('util'),
+ zlib = require('zlib'),
uglify = require('uglify-js'),
+ less = require('less'),
Seq = require('seq'),
- exec = require('child_process').exec,
crypto = require('crypto'),
cleanCSS = require('clean-css'),
EnhanceCSS = require('enhance-css'),
@@ -155,6 +156,18 @@ var cacheHash = function(data) {
return hash.digest('hex');
};
+// Dir maker
+var makeDir = function(dir) {
+ var toRoot = path.relative(options.root, dir),
+ currentDir = options.root;
+
+ toRoot.split('/').forEach(function(part) {
+ currentDir = path.join(currentDir, part);
+ if (!path.existsSync(currentDir))
+ fs.mkdirSync(currentDir, 0770);
+ });
+};
+
// Compiles LESS files to CSS
var compileLessToCss = function(type, callback) {
var filesList = expander.processList(type + '/**/*', { type: 'less', root: options.root });
@@ -163,7 +176,27 @@ var compileLessToCss = function(type, callback) {
Seq.ap(filesList).
parEach(maxConcurrent, function(pathToLessFile) {
util.puts(" Compiling '" + path.basename(pathToLessFile) + "'...");
- exec('lessc ' + pathToLessFile + ' > ' + pathToLessFile.replace('.less', '.css'), this);
+
+ var lessSource = fs.readFileSync(pathToLessFile, 'utf-8'),
+ self = this;
+
+ new (less.Parser)({
+ filename: pathToLessFile,
+ optimizations: 1
+ }).parse(lessSource, function(error, tree) {
+ if (error) {
+ util.error(pathToLessFile + ": " + util.inspect(error));
+ process.exit(1);
+ }
+
+ try {
+ css = tree.toCSS();
+ fs.writeFile(pathToLessFile.replace('.less', '.css'), css, 'utf-8', self);
+ } catch (e) {
+ util.error(pathToLessFile + ": " + util.inspect(error));
+ process.exit(2);
+ }
+ });
}).
seq('less', function() {
callback.call();
@@ -179,7 +212,8 @@ var processGroup = function(type, group, callback) {
if (type == 'stylesheets') {
Seq().
seq(function() {
- exec('mkdir -p ' + groupDir, this);
+ makeDir(groupDir);
+ this(null);
}).
seq(function() {
var data = joinFiles(filesList);
@@ -224,13 +258,15 @@ var processGroup = function(type, group, callback) {
} else {
Seq().
seq(function() {
- exec('mkdir -p ' + groupDir, this);
+ makeDir(groupDir);
+ this(null);
}).
seq(function() {
var content = joinFiles(filesList);
var isCufon = /Cufon\.registerFont/.test(content);
var ast = uglify.parser.parse(content);
var data = '';
+ var self = this;
if (isCufon || options.noMinifyJS) {
// Maybe no minification was required. We also skip mangling for Cufon as it doesn't like it.
@@ -248,12 +284,21 @@ var processGroup = function(type, group, callback) {
groupPath = path.join(options.root, type, 'bundled', group) + '-' + groupHash + '.' + extensions[type];
}
- fs.writeFile(groupPath, data, 'utf-8', this);
+ fs.writeFile(groupPath, data, 'utf-8', function(error) {
+ if (error) throw error;
+
+ self(null, data, groupPath);
+ });
}).
- seq(function() {
+ seq(function(data, groupPath) {
if (!options.gzip) return this(null);
- exec('gzip -c6 ' + groupPath + ' > ' + groupPath + '.gz', this);
+ var self = this;
+ zlib.gzip(data, function(error, compressedData) {
+ if (error) throw error;
+
+ fs.writeFile(groupPath + '.gz', compressedData, self);
+ });
}).
seq(function() {
util.puts(" Processed " + type + " group '" + group + "' - squeezing " + filesList.length + " file(s)");
View
@@ -15,11 +15,17 @@
},
"dependencies": {
"optimist": "0.3.x",
- "seq": "0.2.x",
- "gzip": "0.1.x",
- "uglify-js": "1.x",
- "clean-css": "0.4.x",
- "enhance-css": "0.3.x",
- "assets-expander": "0.2.x"
+ "seq": "0.3.x",
+ "uglify-js": "1.2.x",
+ "less": "1.x",
+ "clean-css": "0.5.x",
+ "enhance-css": "0.4.x",
+ "assets-expander": "0.3.x"
+ },
+ "devDependencies": {
+ "vows": "*"
+ },
+ "engines": {
+ "node": ">=0.6.0"
}
}
View
@@ -2,6 +2,7 @@ var vows = require('vows'),
assert = require('assert'),
fs = require('fs'),
path = require('path'),
+ zlib = require('zlib'),
exec = require('child_process').exec;
var withOptions = function(options) {
@@ -18,6 +19,7 @@ var cleanBundles = function(set) {
exec('rm -rf ' + fullPath('test/data/' + set + '/public/javascripts/bundled'));
exec('rm -rf ' + fullPath('test/data/' + set + '/public/stylesheets/bundled'));
exec('rm -rf ' + fullPath('test/data/' + set + '/public/stylesheets/*.css'));
+ exec('rm -rf ' + fullPath('test/data/' + set + '/public/stylesheets/**/*.css'));
exec('rm -rf ' + fullPath('test/data/' + set + '/.assets.yml.json'));
};
@@ -175,6 +177,12 @@ exports.packagingSuite = vows.describe('packaging all').addBatch({
assert.hasBundledFile('test1', 'javascripts', 'subset.js.gz');
assert.hasBundledFile('test1', 'javascripts', 'all.js.gz');
},
+ 'should correctly compress js content': function() {
+ var compressedBuffer = fs.readFileSync(fullPath(path.join('test', 'data', 'test1', 'public', 'javascripts', 'bundled', 'all.js.gz')));
+ zlib.gunzip(compressedBuffer, function(error, data) {
+ assert.equal(data.toString('utf8'), 'var x=0,y=0');
+ });
+ },
teardown: function() {
cleanBundles('test1');
}
@@ -239,13 +247,13 @@ exports.packagingSuite = vows.describe('packaging all').addBatch({
},
'should bundle js into packages': function() {
var cacheInfo = cacheData('test1');
- assert.hasBundledFile('test1', 'javascripts', 'subset-' + cacheInfo['stylesheets/subset'] + '.js');
- assert.hasBundledFile('test1', 'javascripts', 'all-' + cacheInfo['stylesheets/subset'] + '.js');
+ assert.hasBundledFile('test1', 'javascripts', 'subset-' + cacheInfo['javascripts/subset'] + '.js');
+ assert.hasBundledFile('test1', 'javascripts', 'all-' + cacheInfo['javascripts/all'] + '.js');
},
'should bundle js into compressed packages': function() {
var cacheInfo = cacheData('test1');
- assert.hasBundledFile('test1', 'javascripts', 'subset-' + cacheInfo['stylesheets/subset'] + '.js.gz');
- assert.hasBundledFile('test1', 'javascripts', 'all-' + cacheInfo['stylesheets/subset'] + '.js.gz');
+ assert.hasBundledFile('test1', 'javascripts', 'subset-' + cacheInfo['javascripts/subset'] + '.js.gz');
+ assert.hasBundledFile('test1', 'javascripts', 'all-' + cacheInfo['javascripts/all'] + '.js.gz');
},
teardown: function() {
cleanBundles('test1');
@@ -302,9 +310,23 @@ exports.packagingSuite = vows.describe('packaging all').addBatch({
exec('rm -rf ' + fullPath('test/data/test2/public/images/two-*'));
}
}
+}).addBatch({
+ 'should create deep directory structure': {
+ topic: withOptions('-r data/test4/public -c data/test4/assets.yml -g'),
+ 'should not give error': function(error, stdout) {
+ assert.isNull(error);
+ },
+ 'should create bundled files': function() {
+ assert.hasBundledFile('test4', 'stylesheets', 'desktop/all.css');
+ assert.hasBundledFile('test4', 'stylesheets', 'desktop/all.css.gz');
+ },
+ teardown: function() {
+ cleanBundles('test4');
+ }
+ }
});
-exports.Suite = vows.describe('packaging all').addBatch({
+exports.subsetSuite = vows.describe('packaging selected packages').addBatch({
'packaging only one selected package': {
topic: withOptions('-r data/test1/public -c data/test1/assets.yml -g -n -o all.css'),
'should not give error': function(error, stdout) {
@@ -496,7 +518,7 @@ exports.javascriptOptimizing = vows.describe('javascript optimizing').addBatch({
'data': function(error, data) {
if (error) throw error;
- assert.equal(["function factorial(n){return n==0?1:n*factorial(n-1)}for(var i=0,j=factorial(10).", "toString(),k=j.length;i<k;i++)console.log(j[i])"].join('\n'),
+ assert.equal(["function factorial(a){return a==0?1:a*factorial(a-1)}for(var i=0,j=factorial(10).", "toString(),k=j.length;i<k;i++)console.log(j[i])"].join('\n'),
data);
}
},
@@ -0,0 +1 @@
+var x = 0;
@@ -0,0 +1 @@
+var y = 0;
@@ -0,0 +1,2 @@
+stylesheets:
+ desktop/all: 'one'
@@ -0,0 +1,3 @@
+a {
+ color:#f00;
+}

0 comments on commit a9f36ee

Please sign in to comment.