Skip to content
This repository has been archived by the owner on May 5, 2021. It is now read-only.

Commit

Permalink
Fix dependencies, remove ignore option, cleanup code
Browse files Browse the repository at this point in the history
  • Loading branch information
jgonera committed Dec 28, 2012
1 parent 784941b commit 08ed7be
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 69 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1 +1,2 @@
node_modules/
test/css/
45 changes: 30 additions & 15 deletions bin/autoless
@@ -1,15 +1,14 @@
#!/usr/bin/env nodejs

var path = require('path')
, watch = require('watch')
, growl = require('growl')
, program = require('commander')
, less = require('less')
, Manager = require('../lib/manager');
var path = require('path');
var watch = require('watch');
var growl = require('growl');
var program = require('commander');
var less = require('less');
var Manager = require('../lib/manager');

program
.usage('[options] <source_dir> [destination_dir]')
.option('--ignore <regexp>', 'Pattern for ignored files', RegExp)
.option('--interval <ms>', 'How often files are checked for changes', 100)
.option('--no-watch', "Compile what needs to be compiled and exit")
.parse(process.argv);
Expand All @@ -21,14 +20,31 @@ var monitorOptions = {
interval: program.interval
};

var statusChar = {
'success': '✓',
'error': '✖',
'skipped': 'o'
};

var colors = {
'success': 32,
'error': 31,
'skipped': 36
};

var manager = new Manager(srcDir, dstDir);

function log(file, dstFile, result) {
console.log(file + ' -> ' + dstFile + ': ' + result.toUpperCase());
function color(status, str) {
return '\u001b[' + colors[status] + 'm' + str + '\u001b[0m';
}

function log(status, file, dstFile) {
dstFile = dstFile || '';
console.log(color(status, '%s %s -> %s'), statusChar[status], file, dstFile);
}

function notify(file, dstFile, result) {
growl(file + '\n-> ' + dstFile, {
function notify(result, file, dstFile) {
growl(file + ' -> ' + dstFile, {
title: 'LESS',
image: path.join(__dirname, '../images', result + '.svg')
});
Expand All @@ -37,12 +53,11 @@ function notify(file, dstFile, result) {
// FIXME: when https://github.com/mikeal/watch/issues/40 is fixed, use
// filter in monitorOptions instead
function fileFilter(file) {
return /\.less$/.test(file) && !(program.ignore && program.ignore.test(file));
return /\.less$/.test(file);
}

function check(file) {
if (fileFilter(file)) {
console.log(file);
manager.check(file);
}
}
Expand All @@ -56,8 +71,8 @@ watch.createMonitor(srcDir, monitorOptions, function(monitor) {
console.log('Finding files...');

manager.addFiles(files, function() {
manager.compileAll(function(err) {
if (!program.watch) process.exit(err ? 1 : 0);
manager.compileAll(function(errors) {
if (!program.watch) process.exit(errors);

monitor.on('changed', check);
monitor.on('created', check);
Expand Down
6 changes: 3 additions & 3 deletions lib/lessfile.js
@@ -1,6 +1,6 @@
var fs = require('fs')
, path = require('path')
, less = require('less');
var fs = require('fs');
var path = require('path');
var less = require('less');

function LessFile(file, dstFile) {
this.file = file;
Expand Down
88 changes: 41 additions & 47 deletions lib/manager.js
@@ -1,6 +1,6 @@
var path = require('path')
, EventEmitter = require('events').EventEmitter
, LessFile = require('./lessfile');
var path = require('path');
var EventEmitter = require('events').EventEmitter;
var LessFile = require('./lessfile');

function Manager(srcDir, dstDir) {
this.srcDir = srcDir;
Expand All @@ -13,14 +13,11 @@ function Manager(srcDir, dstDir) {
Manager.prototype = new EventEmitter();

Manager.prototype.update = function(file, callback) {
var self = this
, lessFile = this.files[file];
var self = this, lessFile = this.files[file];

if (!lessFile) {
var match = file.match(/^(.*)(\.[^\.]*)$/)
, base = match[1]
, ext = match[2]
, dstFile = path.join(this.dstDir, base.slice(this.srcDir.length) + '.css');
var base = file.match(/^(.*)\.[^\.]*$/)[1]
var dstFile = path.join(this.dstDir, base.slice(this.srcDir.length) + '.css');
lessFile = this.files[file] = new LessFile(file, dstFile);
}

Expand All @@ -34,8 +31,7 @@ Manager.prototype.update = function(file, callback) {
};

Manager.prototype.addFiles = function(files, callback) {
var self = this
, pending = 0;
var self = this, pending = 0;

function done(err) {
--pending;
Expand All @@ -48,55 +44,53 @@ Manager.prototype.addFiles = function(files, callback) {
});
};

Manager.prototype._check = function(file, recurse, callback) {
var self = this, lessFile = this.files[file], pending = 0;

function done(err) {
--pending;
if (callback && pending === 0) callback();
}

if (!this.dependencies[file]) {
lessFile.compile(function(err) {
self.emit('checked', err ? 'error' : 'success', lessFile.file, lessFile.dstFile);
if (err) self.emit('lessError', err);
if (callback) callback(err);
});
} else {
self.emit('checked', 'skipped', lessFile.file);
if (recurse) {
Object.keys(self.dependencies[file]).forEach(function(file) {
++pending;
self._check(file, recurse, done);
});
} else if (callback) {
callback();
}
}
};

Manager.prototype.compileAll = function(callback) {
var self = this
, pending = 0
, errors = null;
var self = this, pending = 0, errors = 0;

function done(err, lessFile) {
self.emit('checked', lessFile.file, lessFile.dstFile, err ? 'error' : 'success');
if (err) {
self.emit('lessError', err);
errors = true;
}
if (err) ++errors;
--pending;
if (pending === 0) callback(errors);
}

for (var file in this.files) {
var lessFile = this.files[file];
if (!this.dependencies[file]) {
++pending;
lessFile.compile(done);
} else {
self.emit('checked', lessFile.file, lessFile.dstFile, 'skipped');
}
++pending;
self._check(file, false, done);
};
};

Manager.prototype.check = function(file, callback) {
var self = this
, pending = 0;
var self = this;

function done(err, lessFile) {
--pending;
if (pending === 0) callback();
}

this.update(file, function(err, lessFile) {
if (!self.dependencies[file]) {
lessFile.compile(function(err, lessFile) {
self.emit('checked', lessFile.file, lessFile.dstFile, err ? 'error' : 'success');
if (err) self.emit('lessError', err);
if (callback) callback();
});
} else {
self.emit('checked', lessFile.file, lessFile.dstFile, 'skipped');
Object.keys(self.dependencies[file]).forEach(function(file) {
++pending;
self.check(file, done);
});
}
this.update(file, function(err) {
self._check(file, true, callback);
});
};

Expand Down
Empty file added test/css/empty
Empty file.
2 changes: 1 addition & 1 deletion test/lessfile_test.js
Expand Up @@ -53,7 +53,7 @@ describe("LessFile", function() {
it("saves css file", function(done) {
lessFile.compile(function(err) {
fs.existsSync('test/less/main.css').should.be.true;
fs.readFileSync('test/less/main.css').should.include('text-decoration');
fs.readFileSync('test/less/main.css', 'utf-8').should.include('text-decoration');
});
done();
});
Expand Down
48 changes: 45 additions & 3 deletions test/manager_test.js
Expand Up @@ -53,6 +53,17 @@ describe("Manager", function() {
done();
});
});

it("fires checked event for each file", function(done) {
var spy = sinon.spy();
manager.on("checked", spy);

manager.compileAll(function() {
spy.calledWith('success', 'test/less/main.less', 'test/css/main.css').should.be.true;
spy.calledWith('skipped', 'test/less/common.less').should.be.true;
done();
});
})
});

describe("when errors", function() {
Expand All @@ -66,6 +77,16 @@ describe("Manager", function() {
done();
});
});

it("fires checked event for each file", function(done) {
var spy = sinon.spy();
manager.on("checked", spy);

manager.compileAll(function() {
spy.calledWith('error', 'test/less/error.less', 'test/css/error.css').should.be.true;
done();
});
})
});
});

Expand All @@ -89,6 +110,16 @@ describe("Manager", function() {
done();
});
});

it("fires checked event for the file", function(done) {
var spy = sinon.spy();
manager.on("checked", spy);

manager.check('test/less/main.less', function() {
spy.alwaysCalledWith('success', 'test/less/main.less', 'test/css/main.css').should.be.true;
done();
});
})
});

describe("when file is imported", function() {
Expand All @@ -100,13 +131,24 @@ describe("Manager", function() {
});
});

it("checks its dependencies", function(done) {
var spy = sinon.spy(manager, 'check');
it("compiles its dependencies", function(done) {
var spy = sinon.spy(manager.files['test/less/main.less'], 'compile');
manager.check('test/less/common.less', function() {
spy.calledWith('test/less/main.less').should.be.true;
spy.called.should.be.true;
done();
});
});

it("fires checked event for files", function(done) {
var spy = sinon.spy();
manager.on("checked", spy);

manager.check('test/less/common.less', function() {
spy.calledWith('success', 'test/less/main.less', 'test/css/main.css').should.be.true;
spy.calledWith('skipped', 'test/less/common.less').should.be.true;
done();
});
})
});
});
});

0 comments on commit 08ed7be

Please sign in to comment.