mirror of
https://github.com/zhigang1992/deployd.git
synced 2026-05-13 12:37:17 +08:00
Merge branch '0.7' into 0.7-feature/module-dashboard
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
- New `Module` type in extension API
|
||||
- Modules can define multiple Resource Types with `this.addResourceType()`
|
||||
- [TODO] Modules can register their own dashboards.
|
||||
- Added `dir` to server options - for booting in other directories than `process.cwd()`.
|
||||
|
||||
### Breaking Changes
|
||||
- Most configuration properties on the `Resource` class have been moved to the prototype: `external`, `events`, `basicDashboard`, and `dashboard`.
|
||||
|
||||
@@ -132,7 +132,9 @@ function loadResources(resourceTypesQ, basepath, server) {
|
||||
|
||||
var instanceQ = q.spread([configJsonQ, resourceTypesQ], function(config, types) {
|
||||
var type = config.type;
|
||||
if (!types[type]) throw new Error("Cannot find type \"" + type + "\" for resource " + resourceName);
|
||||
if (!types[type]) {
|
||||
throw new Error("Cannot find type \"" + type + "\" for resource " + resourceName);
|
||||
}
|
||||
|
||||
var o = {
|
||||
config: config
|
||||
@@ -188,7 +190,7 @@ function initModules(allModulesQ, appFileQ) {
|
||||
};
|
||||
if (m.prototype instanceof Module) {
|
||||
initModule(m, scope, fn);
|
||||
} else if (m.prototype instanceof Resource) {
|
||||
} else if (m.prototype instanceof Resource || m.prototype.__resource__) {
|
||||
initResourceType(m, scope, fn);
|
||||
} else {
|
||||
initGenericModule(m, scope, fn);
|
||||
|
||||
@@ -27,7 +27,7 @@ util.inherits(Files, Resource);
|
||||
|
||||
Files.prototype.load = function(fn) {
|
||||
var resource = this;
|
||||
var defaultFolder = './public';
|
||||
var defaultFolder = path.join((this.options.dir || './'), 'public');
|
||||
|
||||
var server = this.server;
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ function loadModule(file, fn) {
|
||||
if (stat.isDirectory() || path.extname(file) === '.js') {
|
||||
var module;
|
||||
try {
|
||||
module = require(path.resolve(file));
|
||||
module = require(path.resolve(file));
|
||||
} catch (ex) {
|
||||
// TODO: test this; we don't want it to print the error twice (further down the callstack)
|
||||
console.error("An error occurred while loading " + file + ": ");
|
||||
@@ -87,6 +87,7 @@ function loadModule(file, fn) {
|
||||
}
|
||||
module = module || {};
|
||||
if (!module.id) module.id = (typeof module === 'function' && module.name) || path.basename(file, '.js');
|
||||
|
||||
return module;
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@@ -31,6 +31,7 @@ function extend(origin, add) {
|
||||
* - `db` the database connection info
|
||||
* - `host` the server's hostname
|
||||
* - `port` the server's port
|
||||
* - `dir` the base directory
|
||||
*
|
||||
* Properties:
|
||||
*
|
||||
@@ -98,14 +99,11 @@ function Server(options) {
|
||||
req.session = session;
|
||||
|
||||
var route = function() {
|
||||
config.loadConfig('./', server, function(err, results) {
|
||||
config.loadConfig(options.dir, server, function(err, results) {
|
||||
if (err) throw err;
|
||||
server.resources = results.resources;
|
||||
server.resourceTypes = results.resourceTypes;
|
||||
server.modules = results.modules;
|
||||
|
||||
|
||||
|
||||
var router = new Router(server.resources, server);
|
||||
server.router = router;
|
||||
|
||||
@@ -154,7 +152,7 @@ util.inherits(Server, http.Server);
|
||||
Server.prototype.listen = function(port, host) {
|
||||
var server = this;
|
||||
|
||||
config.loadConfig('./', server, function(err, results) {
|
||||
config.loadConfig(this.options.dir, server, function(err, results) {
|
||||
if (err) {
|
||||
console.error();
|
||||
console.error("Error loading config: ");
|
||||
|
||||
@@ -1,170 +1,170 @@
|
||||
var Deployment = require('../lib/client/deploy').Deployment
|
||||
, sh = require('shelljs')
|
||||
, http = require('http')
|
||||
, fs = require('fs');
|
||||
|
||||
try {
|
||||
fs.unlink(__dirname + '/../test-app/.dpd/deployments.json');
|
||||
} catch(e) {}
|
||||
|
||||
after(function () {
|
||||
try {
|
||||
fs.unlink(__dirname + '/../test-app/.dpd/deployments.json');
|
||||
} catch(e) {}
|
||||
});
|
||||
|
||||
describe('Deployment', function(){
|
||||
it('should sanitize the name', function() {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'ritch');
|
||||
|
||||
expect(d.name).to.equal('test-app');
|
||||
expect(d.user).to.equal('ritch');
|
||||
});
|
||||
|
||||
it('should determine name if one isnt provided', function() {
|
||||
var d = new Deployment(__dirname + '/../test-app');
|
||||
d.setConfig('test-app.deploydapp.com', {subdomain: 'abcdefg'});
|
||||
// recreate
|
||||
d = new Deployment(__dirname + '/../test-app');
|
||||
expect(d.subdomain).to.equal('abcdefg');
|
||||
});
|
||||
|
||||
it('should allow a custom subdomain', function() {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'ritch', 'custom-subdomain');
|
||||
|
||||
expect(d.name).to.equal('custom-subdomain');
|
||||
expect(d.user).to.equal('ritch');
|
||||
expect(d.subdomain).to.equal(d.name);
|
||||
});
|
||||
|
||||
function shouldSanitizeAs(input, output) {
|
||||
expect(Deployment.prototype.sanitize(input)).to.equal(output);
|
||||
}
|
||||
|
||||
it('should sanitize all the following names', function() {
|
||||
shouldSanitizeAs(' a b c ', 'a-b-c');
|
||||
shouldSanitizeAs('a b', 'a-b');
|
||||
shouldSanitizeAs('a.b.c', 'a-b-c');
|
||||
});
|
||||
|
||||
function shouldError(input) {
|
||||
try {
|
||||
Deployment.prototype.sanitize(input);
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error('should have errored for input: ' + input);
|
||||
}
|
||||
|
||||
it('should error for the following names', function() {
|
||||
shouldError('???');
|
||||
shouldError('');
|
||||
shouldError('-');
|
||||
shouldError('');
|
||||
shouldError('/');
|
||||
shouldError('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
|
||||
});
|
||||
|
||||
describe('.package()', function () {
|
||||
it('should create a package of the given app', function(done) {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'ritch')
|
||||
, tarball = d.path + '/.dpd/package.tgz';
|
||||
|
||||
d.package(tarball, function (err) {
|
||||
done(err);
|
||||
sh.rm(tarball);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setConfig()', function(){
|
||||
it('should persist a config value in JSON', function() {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'ritch', 'custom-name');
|
||||
|
||||
d.setConfig('foo', 'bar');
|
||||
|
||||
var json = require(__dirname + '/../test-app/.dpd/deployments.json');
|
||||
expect(json).to.exist;
|
||||
expect(json.foo).to.equal('bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getConfig()', function(){
|
||||
it('should return a persisted config value', function() {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'ritch', 'custom-name');
|
||||
|
||||
d.setConfig('foo', 'bar');
|
||||
var val = d.getConfig('foo');
|
||||
expect(val).to.equal('bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.publish()', function() {
|
||||
it('should make an http request to POSTing a tar, username, key, and subdomain', function(done) {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'ritch')
|
||||
, tar = __dirname + '/../test-app/.dpd/package.tgz'
|
||||
, port = 7007
|
||||
, requested = false
|
||||
, url = 'http://localhost:' + port + '/'
|
||||
, key = Math.random().toString()
|
||||
, size = 0;
|
||||
|
||||
|
||||
http.createServer(function (req, res) {
|
||||
req
|
||||
.on('data', function (data) {
|
||||
size += data.length;
|
||||
})
|
||||
.on('end', function () {
|
||||
res.end();
|
||||
});
|
||||
expect(req.method).to.equal('POST');
|
||||
expect(req.headers['x-remote-key']).to.equal(key);
|
||||
expect(req.headers['x-app-user']).to.equal(d.user);
|
||||
expect('http://' + req.headers.host + req.url).to.equal(url);
|
||||
requested = true;
|
||||
})
|
||||
.listen(port)
|
||||
.on('listening', function () {
|
||||
d.package(tar, function (err) {
|
||||
d.publish(url, tar, key, function (err) {
|
||||
if(err) console.log(err);
|
||||
expect(size).to.equal(fs.statSync(tar).size);
|
||||
if(!requested) throw new Error('failed to make a request to the server');
|
||||
done();
|
||||
sh.rm(tar);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should error gracefully', function(done) {
|
||||
var d = new Deployment(__dirname + '/../test-app', 'test-app', 'ritch')
|
||||
, tar = __dirname + '/../test-app/.dpd/package.tgz'
|
||||
, port = 7008
|
||||
, requested = false
|
||||
, url = 'http://localhost:' + port + '/'
|
||||
, key = Math.random().toString()
|
||||
, errMessage = 'an error occured';
|
||||
|
||||
|
||||
http.createServer(function (req, res) {
|
||||
res.statusCode = 500;
|
||||
res.end(errMessage);
|
||||
requested = true;
|
||||
})
|
||||
.listen(port)
|
||||
.on('listening', function () {
|
||||
d.package(tar, function (err) {
|
||||
d.publish(url, tar, key, function (err) {
|
||||
expect(err.message).to.equal(errMessage);
|
||||
if(!requested) throw new Error('failed to make a request to the server');
|
||||
done();
|
||||
sh.rm(tar);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
// var Deployment = require('../lib/client/deploy').Deployment
|
||||
// , sh = require('shelljs')
|
||||
// , http = require('http')
|
||||
// , fs = require('fs');
|
||||
//
|
||||
// try {
|
||||
// fs.unlink(__dirname + '/../test-app/.dpd/deployments.json');
|
||||
// } catch(e) {}
|
||||
//
|
||||
// after(function () {
|
||||
// try {
|
||||
// fs.unlink(__dirname + '/../test-app/.dpd/deployments.json');
|
||||
// } catch(e) {}
|
||||
// });
|
||||
//
|
||||
// describe('Deployment', function(){
|
||||
// it('should sanitize the name', function() {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'ritch');
|
||||
//
|
||||
// expect(d.name).to.equal('test-app');
|
||||
// expect(d.user).to.equal('ritch');
|
||||
// });
|
||||
//
|
||||
// it('should determine name if one isnt provided', function() {
|
||||
// var d = new Deployment(__dirname + '/../test-app');
|
||||
// d.setConfig('test-app.deploydapp.com', {subdomain: 'abcdefg'});
|
||||
// // recreate
|
||||
// d = new Deployment(__dirname + '/../test-app');
|
||||
// expect(d.subdomain).to.equal('abcdefg');
|
||||
// });
|
||||
//
|
||||
// it('should allow a custom subdomain', function() {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'ritch', 'custom-subdomain');
|
||||
//
|
||||
// expect(d.name).to.equal('custom-subdomain');
|
||||
// expect(d.user).to.equal('ritch');
|
||||
// expect(d.subdomain).to.equal(d.name);
|
||||
// });
|
||||
//
|
||||
// function shouldSanitizeAs(input, output) {
|
||||
// expect(Deployment.prototype.sanitize(input)).to.equal(output);
|
||||
// }
|
||||
//
|
||||
// it('should sanitize all the following names', function() {
|
||||
// shouldSanitizeAs(' a b c ', 'a-b-c');
|
||||
// shouldSanitizeAs('a b', 'a-b');
|
||||
// shouldSanitizeAs('a.b.c', 'a-b-c');
|
||||
// });
|
||||
//
|
||||
// function shouldError(input) {
|
||||
// try {
|
||||
// Deployment.prototype.sanitize(input);
|
||||
// } catch(e) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// throw new Error('should have errored for input: ' + input);
|
||||
// }
|
||||
//
|
||||
// it('should error for the following names', function() {
|
||||
// shouldError('???');
|
||||
// shouldError('');
|
||||
// shouldError('-');
|
||||
// shouldError('');
|
||||
// shouldError('/');
|
||||
// shouldError('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
|
||||
// });
|
||||
//
|
||||
// describe('.package()', function () {
|
||||
// it('should create a package of the given app', function(done) {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'ritch')
|
||||
// , tarball = d.path + '/.dpd/package.tgz';
|
||||
//
|
||||
// d.package(tarball, function (err) {
|
||||
// done(err);
|
||||
// sh.rm(tarball);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe('.setConfig()', function(){
|
||||
// it('should persist a config value in JSON', function() {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'ritch', 'custom-name');
|
||||
//
|
||||
// d.setConfig('foo', 'bar');
|
||||
//
|
||||
// var json = require(__dirname + '/../test-app/.dpd/deployments.json');
|
||||
// expect(json).to.exist;
|
||||
// expect(json.foo).to.equal('bar');
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe('.getConfig()', function(){
|
||||
// it('should return a persisted config value', function() {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'ritch', 'custom-name');
|
||||
//
|
||||
// d.setConfig('foo', 'bar');
|
||||
// var val = d.getConfig('foo');
|
||||
// expect(val).to.equal('bar');
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// describe('.publish()', function() {
|
||||
// it('should make an http request to POSTing a tar, username, key, and subdomain', function(done) {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'ritch')
|
||||
// , tar = __dirname + '/../test-app/.dpd/package.tgz'
|
||||
// , port = 7007
|
||||
// , requested = false
|
||||
// , url = 'http://localhost:' + port + '/'
|
||||
// , key = Math.random().toString()
|
||||
// , size = 0;
|
||||
//
|
||||
//
|
||||
// http.createServer(function (req, res) {
|
||||
// req
|
||||
// .on('data', function (data) {
|
||||
// size += data.length;
|
||||
// })
|
||||
// .on('end', function () {
|
||||
// res.end();
|
||||
// });
|
||||
// expect(req.method).to.equal('POST');
|
||||
// expect(req.headers['x-remote-key']).to.equal(key);
|
||||
// expect(req.headers['x-app-user']).to.equal(d.user);
|
||||
// expect('http://' + req.headers.host + req.url).to.equal(url);
|
||||
// requested = true;
|
||||
// })
|
||||
// .listen(port)
|
||||
// .on('listening', function () {
|
||||
// d.package(tar, function (err) {
|
||||
// d.publish(url, tar, key, function (err) {
|
||||
// if(err) console.log(err);
|
||||
// expect(size).to.equal(fs.statSync(tar).size);
|
||||
// if(!requested) throw new Error('failed to make a request to the server');
|
||||
// done();
|
||||
// sh.rm(tar);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// it('should error gracefully', function(done) {
|
||||
// var d = new Deployment(__dirname + '/../test-app', 'test-app', 'ritch')
|
||||
// , tar = __dirname + '/../test-app/.dpd/package.tgz'
|
||||
// , port = 7008
|
||||
// , requested = false
|
||||
// , url = 'http://localhost:' + port + '/'
|
||||
// , key = Math.random().toString()
|
||||
// , errMessage = 'an error occured';
|
||||
//
|
||||
//
|
||||
// http.createServer(function (req, res) {
|
||||
// res.statusCode = 500;
|
||||
// res.end(errMessage);
|
||||
// requested = true;
|
||||
// })
|
||||
// .listen(port)
|
||||
// .on('listening', function () {
|
||||
// d.package(tar, function (err) {
|
||||
// d.publish(url, tar, key, function (err) {
|
||||
// expect(err.message).to.equal(errMessage);
|
||||
// if(!requested) throw new Error('failed to make a request to the server');
|
||||
// done();
|
||||
// sh.rm(tar);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
Reference in New Issue
Block a user