Skip to content

Commit

Permalink
add basic lookup paths. Closes #1
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Aug 11, 2012
1 parent 236eb46 commit e9e5127
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 59 deletions.
3 changes: 2 additions & 1 deletion examples/components/tobi-ferret/component.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "ferret",
"dependencies": {
"tobi/bar": "*"
"tobi/bar": "*",
"loki/foo": "*"
},
"scripts": ["index.js"],
"styles": ["ferret.css"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "loki-foo",
"scripts": ["index.js"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'loki';
128 changes: 70 additions & 58 deletions lib/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

var fs = require('fs')
, path = require('path')
, join = path.join
, Batch = require('batch')
, debug = require('debug')('component:builder')
, Emitter = require('events').EventEmitter
Expand All @@ -26,6 +27,9 @@ module.exports = Builder;
function Builder(dir) {
this.dir = dir;
this.name = basename(dir);
this.paths = [];
this.paths.push(join(dir, 'components'));
this.paths.push(join(dir, '..'));
this.ignored = {
scripts: [],
styles: []
Expand All @@ -38,6 +42,35 @@ function Builder(dir) {

Builder.prototype.__proto__ = Emitter.prototype;

/**
* Lookup component `name` using `.paths`
* and invoke `fn(err, dir)`.
*
* @param {String} name
* @param {String} fn
* @api public
*/

Builder.prototype.lookup = function(name, fn){
var paths = this.paths;
var i = 0;

debug('lookup %s', name);
function next() {
var path = paths[i++];
if (!path) return fn();
var dir = join(path, name);
debug('lookup check %s', dir);
fs.exists(dir, function(yes){
if (!yes) return next();
debug('lookup found %s', dir);
fn(null, dir);
});
}

next();
};

/**
* Ignore the given component name(s) of `type`.
*
Expand Down Expand Up @@ -141,15 +174,17 @@ Builder.prototype.build = function(fn){
};

/**
* Build scripts and invoke `fn(err, js)`.
* Build `type` and invoke `fn`.
*
* @param {Function} fn
* @param {String} type
* @param {String} fn
* @param {String} process
* @api private
*/

Builder.prototype.buildScripts = function(fn){
Builder.prototype.buildType = function(type, fn, process){
var self = this;
debug('building %s js', this.name);
debug('building %s %s', this.name, type);

this.json(function(err, conf){
if (err) return fn(err);
Expand All @@ -160,28 +195,32 @@ Builder.prototype.buildScripts = function(fn){
dep = dep.replace('/', '-');

// ignored
if (self.ignoring(dep, 'scripts')) return debug('ignoring %s', dep);
if (self.ignoring(dep, type)) return debug('ignoring %s', dep);

// ignore it so we dont have dups
self.ignore(dep, 'scripts');

// build dep
var dir = self.path(path.join('..', dep));
debug('building dependency %s', dep);
var builder = new Builder(dir);
builder.ignored = self.ignored;
self.emit('dependency', builder);
batch.push(builder.buildScripts.bind(builder));
self.ignore(dep, type);

// lookup dep
batch.push(function(done){
self.lookup(dep, function(err, dir){
if (err) return done(err);
debug('building dependency %s in %s', dep, dir);
var builder = new Builder(dir);
builder.ignored = self.ignored;
self.emit('dependency', builder);
builder.buildType(type, done, process);
});
});
});
}

if (conf.scripts) {
conf.scripts.forEach(function(script){
var path = self.path(script);
if (conf[type]) {
conf[type].forEach(function(file){
var path = self.path(file);
batch.push(function(done){
fs.readFile(path, 'utf8', function(err, str){
if (err) return fn(err);
done(null, register(conf.name + '/' + script, str));
done(null, process(conf.name + '/' + file, str));
});
});
});
Expand All @@ -195,53 +234,26 @@ Builder.prototype.buildScripts = function(fn){
};

/**
* Build styles and invoke `fn(err, css)`.
* Build scripts and invoke `fn(err, js)`.
*
* @param {Function} fn
* @api private
*/

Builder.prototype.buildStyles = function(fn){
var self = this;
debug('building %s css', this.name);

this.json(function(err, conf){
if (err) return fn(err);
var batch = new Batch;

if (conf.dependencies) {
Object.keys(conf.dependencies).forEach(function(dep){
dep = dep.replace('/', '-');

// ignored
if (self.ignoring(dep, 'styles')) return debug('ignoring %s', dep);

// ignore it so we dont have dups
self.ignore(dep, 'styles');

// build dep
var dir = self.path(path.join('..', dep));
debug('building dependency %s', dep);
var builder = new Builder(dir);
builder.ignored = self.ignored;
self.emit('dependency', builder);
batch.push(builder.buildStyles.bind(builder));
});
}
Builder.prototype.buildScripts = function(fn){
this.buildType('scripts', fn, register);
};

if (conf.styles) {
conf.styles.forEach(function(script){
var path = self.path(script);
batch.push(function(done){
fs.readFile(path, 'utf8', done);
});
});
}
/**
* Build styles and invoke `fn(err, css)`.
*
* @param {Function} fn
* @api private
*/

batch.end(function(err, res){
if (err) return fn(err);
fn(null, res.join('\n'));
});
Builder.prototype.buildStyles = function(fn){
this.buildType('styles', fn, function(file, str){
return str;
});
};

Expand Down

0 comments on commit e9e5127

Please sign in to comment.