Permalink
Browse files

Merge branch 'review/235'

  • Loading branch information...
2 parents aa7c059 + f2d0b6e commit 2b9feb16ae71630912153bd4fd7591d91833920d @tj tj committed Jan 18, 2013
Showing with 118 additions and 73 deletions.
  1. +6 −2 Makefile
  2. +11 −30 bin/component-install
  3. +64 −33 lib/Package.js
  4. +37 −8 test/remotes.js
View
@@ -8,6 +8,10 @@ test:
--timeout 10s \
--slow 3s \
--bail \
- --reporter spec
+ --reporter spec \
+ $(SCRIPTS)
-.PHONY: test
+test-remotes:
+ @$(MAKE) test SCRIPTS=test/remotes.js
+
+.PHONY: test test-remotes
View
@@ -140,7 +140,7 @@ function report(pkg, options) {
pkg.on('error', function(err){
if (404 != err.status) utils.fatal(err.stack);
- if (options.error) {
+ if (err.fatal) {
error(err.message);
process.exit(1);
}
@@ -180,37 +180,18 @@ process.on('exit', function(){
*/
function install(name, version) {
- var i = 0;
-
- next();
-
- function next() {
- var remote = conf.remotes[i++];
- if (!remote) return;
-
- // parse remote
- var last = i == conf.remotes.length - 1;
- remote = url.parse(remote);
-
- // strip trailing /
- remote.href = remote.href.slice(0, -1);
-
- // kick of installation
- var pkg = component.install(name, version, {
- dest: program.out,
- force: program.force,
- dev: program.dev,
- remote: remote.href
- });
+ // kick off installation
+ var pkg = component.install(name, version, {
+ dest: program.out,
+ force: program.force,
+ dev: program.dev,
+ remotes: conf.remotes
+ });
- // only error on the last remote otherwise
- // we assume it may be fetchable
- pkg.once('error', next);
- report(pkg, { error: !last });
+ report(pkg);
- // TODO: add callback
- pkg.install();
- }
+ // TODO: add callback
+ pkg.install();
}
/**
View
@@ -14,6 +14,7 @@ var Emitter = require('events').EventEmitter
, debug = require('debug')('component:installer')
, Batch = require('batch')
, http = require('http')
+ , url = require('url')
, fs = require('fs');
/**
@@ -46,7 +47,7 @@ function Package(pkg, version, options) {
if (!version) throw new Error('version required');
this.name = pkg;
this.dest = options.dest || 'components';
- this.remote = options.remote || 'https://raw.github.com';
+ this.remotes = options.remotes || ['https://raw.github.com'];
this.auth = options.auth;
this.force = !! options.force;
this.version = version;
@@ -92,7 +93,7 @@ Package.prototype.join = function(path){
*/
Package.prototype.url = function(file){
- return this.remote + '/' + this.name + '/' + this.version + '/' + file;
+ return this.remote.href + '/' + this.name + '/' + this.version + '/' + file;
};
/**
@@ -244,7 +245,8 @@ Package.prototype.getDependencies = function(deps, fn){
batch.push(function(done){
var pkg = new Package(name, version, {
dest: self.dest,
- force: self.force
+ force: self.force,
+ remotes: self.remotes
});
self.emit('dep', pkg);
pkg.on('end', done);
@@ -292,43 +294,72 @@ Package.prototype.install = function(){
Package.prototype.reallyInstall = function(){
var self = this;
- var batch = new Batch;
- this.getJSON(function(err, json){
- if (err) return self.emit('error', err);
-
- var files = [];
- if (json.scripts) files = files.concat(json.scripts);
- if (json.styles) files = files.concat(json.styles);
- if (json.templates) files = files.concat(json.templates);
- if (json.files) files = files.concat(json.files);
- if (json.images) files = files.concat(json.images);
- if (json.fonts) files = files.concat(json.fonts);
- json.repo = json.repo || self.remote + '/' + self.name;
-
- if (json.dependencies) {
+ var i = 0;
+ var batch;
+ var last;
+
+ next();
+
+ function next() {
+ self.remote = self.remotes[i++];
+ if (!self.remote) return self.emit('error', new Error('can\'t find remote for "' + self.name + '"'));
+
+ // parse remote
+ last = i == self.remotes.length - 1;
+ self.remote = url.parse(self.remote);
+
+ // strip trailing /
+ self.remote.href = self.remote.href.slice(0, -1);
+
+ // only error on the last remote otherwise
+ // we assume it may be fetchable
+ self.once('error', next);
+
+ // kick off installation
+ batch = new Batch;
+ self.getJSON(function(err, json){
+ if (err) {
+ err.fatal = !last;
+ return self.emit('error', err);
+ }
+
+ var files = [];
+ if (json.scripts) files = files.concat(json.scripts);
+ if (json.styles) files = files.concat(json.styles);
+ if (json.templates) files = files.concat(json.templates);
+ if (json.files) files = files.concat(json.files);
+ if (json.images) files = files.concat(json.images);
+ if (json.fonts) files = files.concat(json.fonts);
+ json.repo = json.repo || self.remote.href + '/' + self.name;
+
+ if (json.dependencies) {
+ batch.push(function(done){
+ self.getDependencies(json.dependencies, done);
+ });
+ }
+
batch.push(function(done){
- self.getDependencies(json.dependencies, done);
+ self.mkdir(self.dirname(), function(err){
+ json = JSON.stringify(json, null, 2);
+ self.writeFile('component.json', json, done);
+ });
});
- }
- batch.push(function(done){
- self.mkdir(self.dirname(), function(err){
- json = JSON.stringify(json, null, 2);
- self.writeFile('component.json', json, done);
+ batch.push(function(done){
+ self.mkdir(self.dirname(), function(err){
+ self.getFiles(files, done);
+ });
});
- });
- batch.push(function(done){
- self.mkdir(self.dirname(), function(err){
- self.getFiles(files, done);
+ batch.end(function(err){
+ if (err) {
+ err.fatal = !last;
+ return self.emit('error', err);
+ }
+ self.emit('end');
});
});
-
- batch.end(function(err){
- if (err) return self.emit('error', err);
- self.emit('end');
- });
- });
+ }
};
/**
View
@@ -23,20 +23,33 @@ describe('component install from remote', function(){
})
before(function(done){
+ mkdir('test/private-registry/testdependencies/master', done);
+ })
+
+ before(function(done){
+ fs.writeFile('test/private-registry/testdependencies/master/component.json', JSON.stringify({
+ name: 'testdependencies',
+ repo: 'private-registry/testdependencies',
+ remotes: ['http://localhost:4000'],
+ dependencies: {'private-registry/testcomponent': "*"}
+ }), done);
+ })
+
+ before(function(done){
app.use(express.static(__dirname));
- app.listen(3000, done);
+ app.listen(4000, done);
})
before(function(done){
auth.use(express.basicAuth('admin', '1234'));
auth.use(express.static(__dirname));
- auth.listen(3001, done);
+ auth.listen(4001, done);
})
describe('without authentication', function(){
beforeEach(function(done){
fs.writeFile('component.json', JSON.stringify({
- remotes: ['http://localhost:3000']
+ remotes: ['http://localhost:4000']
}), done);
})
@@ -51,7 +64,7 @@ describe('component install from remote', function(){
done();
})
})
-
+
it('should fallback to github', function(done){
exec('bin/component install component/emitter', function(err, stdout, stderr){
if (err) return done(err);
@@ -63,13 +76,29 @@ describe('component install from remote', function(){
done();
})
})
+
+ it('should install private dependencies', function(done){
+ exec('bin/component install private-registry/testdependencies', function(err, stdout, stderr){
+ if (err) return done(err);
+ stdout.should.include('install');
+ stdout.should.include('dep');
+ stdout.should.include('complete');
+ var json = require(path.resolve('components/private-registry-testdependencies/component.json'));
+ json.name.should.equal('testdependencies');
+ json.repo.should.equal('private-registry/testdependencies');
+ json = require(path.resolve('components/private-registry-testcomponent/component.json'));
+ json.name.should.equal('testcomponent');
+ json.repo.should.equal('private-registry/testcomponent');
+ done();
+ })
+ })
})
describe('with authentication', function(){
describe('url notation', function(done){
before(function(done){
fs.writeFile('component.json', JSON.stringify({
- remotes: ['http://admin:1234@localhost:3001']
+ remotes: ['http://admin:1234@localhost:4001']
}), done);
})
@@ -89,17 +118,17 @@ describe('component install from remote', function(){
describe('and bad credentials', function(){
beforeEach(function(done){
fs.writeFile('component.json', JSON.stringify({
- remotes: ['http://admin:abcd@localhost:3001']
+ remotes: ['http://admin:abcd@localhost:4001']
}), done);
})
it('should fail when credentials are incorrect', function(done){
exec('bin/component install private-registry/testcomponent', function(err, stdout, stderr){
if (err) return done(err);
stderr.should.include('error');
- stderr.should.include('failed to fetch http://admin:abcd@localhost:3001/private-registry/testcomponent/master/component.json');
+ stderr.should.include('failed to fetch http://admin:abcd@localhost:4001/private-registry/testcomponent/master/component.json');
stderr.should.include('got 401 "Unauthorized"');
- assert(!exists('components/private-registry-testcomponent/component.json'),
+ assert(!exists('components/private-registry-testcomponent/component.json'),
'component should not be installed');
done();
})

0 comments on commit 2b9feb1

Please sign in to comment.