mirror of
https://github.com/zhigang1992/deployd.git
synced 2026-05-29 00:51:30 +08:00
Refactored config loader
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
var fs = require('fs')
|
||||
, path = require('path')
|
||||
, Resource = require('./resource')
|
||||
, loadTypes = require('./type-loader')
|
||||
, _loadTypes = require('./type-loader')
|
||||
, InternalResources = require('./resources/internal-resources')
|
||||
, Files = require('./resources/files')
|
||||
, ClientLib = require('./resources/client-lib')
|
||||
, Dashboard = require('./resources/dashboard')
|
||||
, debug = require('debug')('config-loader')
|
||||
, ignore = {}
|
||||
, domain = require('domain');
|
||||
|
||||
, domain = require('domain')
|
||||
, async = require('async');
|
||||
|
||||
/*!
|
||||
* Loads resources from a project folder
|
||||
* Callback receives two arguments `(err, resources)`.
|
||||
@@ -18,157 +17,124 @@ var fs = require('fs')
|
||||
* @param {Function} callback
|
||||
*/
|
||||
module.exports.loadConfig = function(basepath, server, fn) {
|
||||
|
||||
var remaining = 0
|
||||
, finished = false
|
||||
, resourceConfig = resourceConfig || {}
|
||||
, resources = server.__resourceCache || []
|
||||
, src = {}
|
||||
, error;
|
||||
var resources = server.__resourceCache || [];
|
||||
|
||||
server.__resourceCache = null;
|
||||
|
||||
if(resources.length) {
|
||||
if (resources.length) {
|
||||
debug("Loading from cache");
|
||||
fn(null, resources);
|
||||
|
||||
if(server.options.env === 'development') {
|
||||
// dump the cache in two seconds
|
||||
setTimeout(function () {
|
||||
delete server.__resourceCache;
|
||||
}, 2000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
function done() {
|
||||
if(!finished && !remaining) {
|
||||
if(error) return fn(error);
|
||||
var getTypes = async.memoize(loadTypes);
|
||||
|
||||
remaining = -1;
|
||||
finished = true;
|
||||
async.waterfall([
|
||||
async.apply(loadResourceDir, basepath)
|
||||
, async.apply(loadResources, getTypes, basepath, server)
|
||||
, async.apply(addInternalResources, server, basepath)
|
||||
], function(err, result) {
|
||||
fn(err, result);
|
||||
});
|
||||
};
|
||||
|
||||
var InternalResources = require('./resources/internal-resources');
|
||||
|
||||
debug('done, adding internals');
|
||||
|
||||
var clientLib = new ClientLib('dpd.js', { config: { resources: resources }, server: server});
|
||||
|
||||
clientLib.load(function(err) {
|
||||
if (err) return fn(err);
|
||||
resources.push(new Files('', { config: { 'public': './public' }, server: server }));
|
||||
resources.push(clientLib);
|
||||
resources.push(new InternalResources('__resources', {config: {configPath: basepath}, server: server}));
|
||||
resources.push(new Dashboard('dashboard', {server: server}));
|
||||
|
||||
server.__resourceCache = resources;
|
||||
|
||||
fn(null, resources);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
loadTypes(function(defaults, types) {
|
||||
function loadTypes(fn) {
|
||||
_loadTypes(function(defaults, types) {
|
||||
Object.keys(types).forEach(function(key) {
|
||||
defaults[key] = types[key];
|
||||
});
|
||||
types = defaults;
|
||||
loadResources(types);
|
||||
types = defaults;
|
||||
fn(null, types);
|
||||
});
|
||||
}
|
||||
|
||||
function loadResource(name, path, config, types) {
|
||||
debug("Loading resource: %s", name);
|
||||
var type = config.type
|
||||
, resource
|
||||
, o = {
|
||||
config: config
|
||||
, server: server
|
||||
, db: server.db
|
||||
, configPath: path
|
||||
};
|
||||
function loadResourceDir(basepath, fn) {
|
||||
fs.readdir(path.join(basepath, 'resources'), fn);
|
||||
}
|
||||
|
||||
|
||||
if (types[type]) {
|
||||
var d = domain.create();
|
||||
d.on('error', function (err) {
|
||||
err.message += ' - when initializing: ' + o.config.type;
|
||||
console.error(err.stack || err);
|
||||
process.exit();
|
||||
});
|
||||
remaining++;
|
||||
d.run(function () {
|
||||
process.nextTick(function () {
|
||||
remaining--;
|
||||
resource = new types[o.config.type](name, o);
|
||||
if (resource.load) {
|
||||
remaining++;
|
||||
resource.load(function(err) {
|
||||
remaining--;
|
||||
|
||||
if (err) {
|
||||
error = err;
|
||||
return done();
|
||||
}
|
||||
resources.push(resource);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
resources.push(resource);
|
||||
}
|
||||
function loadResources(getTypes, basepath, server, files, fn) {
|
||||
async.map(files, function(resourceName, fn) {
|
||||
var resourcePath = path.join(basepath, 'resources', resourceName);
|
||||
var configPath = path.join(resourcePath, 'config.json');
|
||||
async.auto({
|
||||
types: function(fn) {
|
||||
getTypes(fn);
|
||||
},
|
||||
|
||||
configJsonFile: function(fn) {
|
||||
debug("reading %s", configPath);
|
||||
fs.readFile(configPath, 'utf-8', fn);
|
||||
},
|
||||
|
||||
configJson: ['configJsonFile', function(fn, results) {
|
||||
try {
|
||||
var settings = JSON.parse(results.configJsonFile);
|
||||
fn(null, settings);
|
||||
} catch (ex) {
|
||||
fn(ex);
|
||||
}
|
||||
}],
|
||||
|
||||
instance: ['configJson', 'types', function(fn, results) {
|
||||
debug("Loading resource: %s", resourceName);
|
||||
var config = results.configJson
|
||||
, types = results.types
|
||||
|
||||
, type = config.type
|
||||
, resource
|
||||
, o;
|
||||
|
||||
o = {
|
||||
config: config
|
||||
, server: server
|
||||
, db: server.db
|
||||
, configPath: resourcePath
|
||||
};
|
||||
|
||||
if (!types[type]) return fn(new Error("Cannot find type \"" + type + "\" for resource " + resourceName));
|
||||
|
||||
var d = domain.create();
|
||||
d.on('error', function (err) {
|
||||
err.message += ' - when initializing: ' + o.config.type;
|
||||
console.error(err.stack || err);
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
error = 'cannot find type ' + o.config.type + ' for resource ' + name;
|
||||
}
|
||||
if(error) throw error;
|
||||
}
|
||||
|
||||
function loadResources(types) {
|
||||
fs.readdir(path.join(basepath, 'resources'), function (err, dir) {
|
||||
if(dir && dir.length) {
|
||||
dir.forEach(function (file) {
|
||||
if(!ignore[file]) {
|
||||
remaining++;
|
||||
fs.stat(path.join(basepath, 'resources', file), function (err, stat) {
|
||||
remaining--;
|
||||
if(err) throw err;
|
||||
if(stat && stat.isDirectory()) {
|
||||
var spath = path.join(basepath, 'resources', file, 'config.json')
|
||||
, resource = file;
|
||||
|
||||
(fs.exists || path.exists)(spath, function (exists) {
|
||||
if(exists) {
|
||||
remaining++;
|
||||
fs.readFile(spath, 'utf-8', function(err, data) {
|
||||
remaining--;
|
||||
var settings;
|
||||
if(err) throw err;
|
||||
try {
|
||||
settings = JSON.parse(data);
|
||||
|
||||
loadResource(file, path.join(basepath, 'resources', file), settings, types);
|
||||
|
||||
} catch(e) {
|
||||
if(err) throw err;
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
d.run(function() {
|
||||
process.nextTick(function() {
|
||||
resource = new types[type](resourceName, o);
|
||||
loadResourceExtras(resource, fn);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}]
|
||||
}, function(err, results) {
|
||||
fn(err, results && results.instance);
|
||||
});
|
||||
}
|
||||
}, fn);
|
||||
}
|
||||
|
||||
function loadResourceExtras(resource, fn) {
|
||||
async.series([
|
||||
function(fn) {
|
||||
if (resource.load) {
|
||||
resource.load(fn);
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
}
|
||||
], function(err) {
|
||||
fn(err, resource);
|
||||
});
|
||||
}
|
||||
|
||||
function addInternalResources(server, basepath, resources, fn) {
|
||||
var internals = [
|
||||
new Files('', { config: { 'public': './public' }, server: server })
|
||||
, new ClientLib('dpd.js', { config: { resources: resources }, server: server})
|
||||
, new InternalResources('__resources', {config: {configPath: basepath}, server: server})
|
||||
, new Dashboard('dashboard', {server: server})
|
||||
];
|
||||
async.forEach(internals, loadResourceExtras, function(err) {
|
||||
fn(err, resources.concat(internals));
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user