diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js index 38d6b68c0..ed9c66a37 100644 --- a/src/static/js/pluginfw/plugins.js +++ b/src/static/js/pluginfw/plugins.js @@ -1,7 +1,6 @@ var npm = require("npm/lib/npm.js"); var readInstalled = require("./read-installed.js"); var path = require("path"); -var async = require("async"); var fs = require("fs"); var tsort = require("./tsort"); var util = require("util"); @@ -15,6 +14,7 @@ exports.plugins = {}; exports.parts = []; exports.hooks = {}; +// @TODO RPB this appears to be unused exports.ensure = function (cb) { if (!exports.loaded) exports.update(cb); @@ -53,109 +53,94 @@ exports.formatHooks = function (hook_set_name) { return "
" + res.join("\n") + "
"; }; -exports.callInit = function (cb) { +exports.callInit = function () { + const fsp_stat = util.promisify(fs.stat); + const fsp_writeFile = util.promisify(fs.writeFile); + var hooks = require("./hooks"); - async.map( - Object.keys(exports.plugins), - function (plugin_name, cb) { - var plugin = exports.plugins[plugin_name]; - fs.stat(path.normalize(path.join(plugin.package.path, ".ep_initialized")), function (err, stats) { - if (err) { - async.waterfall([ - function (cb) { fs.writeFile(path.normalize(path.join(plugin.package.path, ".ep_initialized")), 'done', cb); }, - function (cb) { hooks.aCallAll("init_" + plugin_name, {}, cb); }, - cb, - ]); - } else { - cb(); - } - }); - }, - function () { cb(); } - ); + let p = Object.keys(exports.plugins).map(function (plugin_name) { + let plugin = exports.plugins[plugin_name]; + let ep_init = path.normalize(path.join(plugin.package.path, ".ep_initialized")); + return fsp_stat(ep_init).catch(async function() { + await fsp_writeFile(ep_init, "done"); + await hooks.aCallAll("init_" + plugin_name, {}); + }); + }); + + return Promise.all(p); } exports.pathNormalization = function (part, hook_fn_name) { return path.normalize(path.join(path.dirname(exports.plugins[part.plugin].package.path), hook_fn_name)); } -exports.update = function (cb) { - exports.getPackages(function (er, packages) { - var parts = []; - var plugins = {}; +exports.update = async function () { + let packages = await exports.getPackages(); + var parts = []; + var plugins = {}; - // Load plugin metadata ep.json - async.forEach( - Object.keys(packages), - function (plugin_name, cb) { - loadPlugin(packages, plugin_name, plugins, parts, cb); - }, - function (err) { - if (err) cb(err); - exports.plugins = plugins; - exports.parts = sortParts(parts); - exports.hooks = pluginUtils.extractHooks(exports.parts, "hooks", exports.pathNormalization); - exports.loaded = true; - exports.callInit(cb); - } - ); + // Load plugin metadata ep.json + let p = Object.keys(packages).map(function (plugin_name) { + return loadPlugin(packages, plugin_name, plugins, parts); }); - }; -exports.getPackages = function (cb) { + return Promise.all(p).then(function() { + exports.plugins = plugins; + exports.parts = sortParts(parts); + exports.hooks = pluginUtils.extractHooks(exports.parts, "hooks", exports.pathNormalization); + exports.loaded = true; + }).then(exports.callInit); +} + +exports.getPackages = async function () { // Load list of installed NPM packages, flatten it to a list, and filter out only packages with names that var dir = path.resolve(npm.dir, '..'); - readInstalled(dir, function (er, data) { - if (er) cb(er, null); + let data = await util.promisify(readInstalled)(dir); - var packages = {}; - function flatten(deps) { - _.chain(deps).keys().each(function (name) { - if (name.indexOf(exports.prefix) === 0) { - packages[name] = _.clone(deps[name]); - // Delete anything that creates loops so that the plugin - // list can be sent as JSON to the web client - delete packages[name].dependencies; - delete packages[name].parent; - } + var packages = {}; + function flatten(deps) { + _.chain(deps).keys().each(function (name) { + if (name.indexOf(exports.prefix) === 0) { + packages[name] = _.clone(deps[name]); + // Delete anything that creates loops so that the plugin + // list can be sent as JSON to the web client + delete packages[name].dependencies; + delete packages[name].parent; + } - // I don't think we need recursion - //if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies); - }); - } + // I don't think we need recursion + //if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies); + }); + } - var tmp = {}; - tmp[data.name] = data; - flatten(tmp[data.name].dependencies); - cb(null, packages); - }); + var tmp = {}; + tmp[data.name] = data; + flatten(tmp[data.name].dependencies); + return packages; }; -function loadPlugin(packages, plugin_name, plugins, parts, cb) { +async function loadPlugin(packages, plugin_name, plugins, parts) { + let fsp_readFile = util.promisify(fs.readFile); + var plugin_path = path.resolve(packages[plugin_name].path, "ep.json"); - fs.readFile( - plugin_path, - function (er, data) { - if (er) { - console.error("Unable to load plugin definition file " + plugin_path); - return cb(); - } - try { - var plugin = JSON.parse(data); - plugin['package'] = packages[plugin_name]; - plugins[plugin_name] = plugin; - _.each(plugin.parts, function (part) { - part.plugin = plugin_name; - part.full_name = plugin_name + "/" + part.name; - parts[part.full_name] = part; - }); - } catch (ex) { - console.error("Unable to parse plugin definition file " + plugin_path + ": " + ex.toString()); - } - cb(); + try { + let data = await fsp_readFile(plugin_path); + try { + var plugin = JSON.parse(data); + plugin['package'] = packages[plugin_name]; + plugins[plugin_name] = plugin; + _.each(plugin.parts, function (part) { + part.plugin = plugin_name; + part.full_name = plugin_name + "/" + part.name; + parts[part.full_name] = part; + }); + } catch (ex) { + console.error("Unable to parse plugin definition file " + plugin_path + ": " + ex.toString()); } - ); + } catch (er) { + console.error("Unable to load plugin definition file " + plugin_path); + } } function partsToParentChildList(parts) {