From 90296b92cde8622db8ac84c7f59da409068f4c18 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Wed, 12 Jul 2017 23:29:56 -0600 Subject: [PATCH 1/3] Override winston to use console.log instead of stdout --- app.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app.js b/app.js index 7a0b7bc2a5..d3b4af0697 100644 --- a/app.js +++ b/app.js @@ -37,6 +37,7 @@ var winston = require('winston'); var path = require('path'); var pkg = require('./package.json'); var file = require('./src/file'); +var debug = require('./src/meta/debugParams')().execArgv.length; global.env = process.env.NODE_ENV || 'production'; @@ -52,6 +53,22 @@ winston.add(winston.transports.Console, { stringify: (!!nconf.get('json-logging')), }); +if (debug) { + var winstonCommon = require('winston/lib/winston/common'); + // Override to use real console.log etc for VSCode debugger + winston.transports.Console.prototype.log = function (level, message, meta, callback) { + const output = winstonCommon.log(Object.assign({}, this, { + level, + message, + meta, + })); + + console[level in console ? level : 'log'](output); + + setImmediate(callback, null, true); + }; +} + // Alternate configuration file support var configFile = path.join(__dirname, '/config.json'); From ee5895f5344d600c780a4c07c77ef195887ac471 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Wed, 12 Jul 2017 23:31:29 -0600 Subject: [PATCH 2/3] Fix #5488 Support scoped plugin npm packages --- public/src/admin/extend/plugins.js | 4 +- src/plugins.js | 84 +++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/public/src/admin/extend/plugins.js b/public/src/admin/extend/plugins.js index 9622b4fbc0..dbc722aa2a 100644 --- a/public/src/admin/extend/plugins.js +++ b/public/src/admin/extend/plugins.js @@ -20,7 +20,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t pluginsList.on('click', 'button[data-action="toggleActive"]', function () { var pluginEl = $(this).parents('li'); pluginID = pluginEl.attr('data-plugin-id'); - var btn = $('#' + pluginID + ' [data-action="toggleActive"]'); + var btn = $('[id="' + pluginID + '"] [data-action="toggleActive"]'); socket.emit('admin.plugins.toggleActive', pluginID, function (err, status) { if (err) { return app.alertError(err); @@ -30,7 +30,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t btn.toggleClass('btn-warning', status.active).toggleClass('btn-success', !status.active); // clone it to active plugins tab - if (status.active && !$('#active #' + pluginID).length) { + if (status.active && !$('#active [id="' + pluginID + '"]').length) { $('#active ul').prepend(pluginEl.clone(true)); } diff --git a/src/plugins.js b/src/plugins.js index 7c758c517a..de328887eb 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -298,38 +298,74 @@ Plugins.normalise = function (apiReturn, callback) { }; Plugins.showInstalled = function (callback) { - var npmPluginPath = path.join(__dirname, '../node_modules'); + var nodeModulesPath = path.join(__dirname, '../node_modules'); + var pluginNamePattern = /^(@.*?\/)?nodebb-(theme|plugin|widget|rewards)-.*$/; async.waterfall([ - async.apply(fs.readdir, npmPluginPath), - + function (next) { + fs.readdir(nodeModulesPath, next); + }, function (dirs, next) { - dirs = dirs.filter(function (dir) { - return dir.startsWith('nodebb-plugin-') || - dir.startsWith('nodebb-widget-') || - dir.startsWith('nodebb-rewards-') || - dir.startsWith('nodebb-theme-'); - }).map(function (dir) { - return path.join(npmPluginPath, dir); - }); + var pluginPaths = []; - async.filter(dirs, function (dir, callback) { - fs.stat(dir, function (err, stats) { - if (err) { - if (err.code === 'ENOENT') { - return callback(null, false); - } - return callback(err); - } - callback(null, stats.isDirectory()); - }); - }, next); + async.each(dirs, function (dirname, next) { + var dirPath = path.join(nodeModulesPath, dirname); + + async.waterfall([ + function (cb) { + fs.stat(dirPath, function (err, stats) { + if (err && err.code !== 'ENOENT') { + return next(err); + } + if (err || !stats.isDirectory()) { + return next(); + } + + if (pluginNamePattern.test(dirname)) { + pluginPaths.push(dirname); + return next(); + } + + if (dirname[0] !== '@') { + return next(); + } + fs.readdir(dirPath, cb); + }); + }, + function (subdirs, cb) { + async.each(subdirs, function (subdir, next) { + if (!pluginNamePattern.test(subdir)) { + return next(); + } + + var subdirPath = path.join(dirPath, subdir); + fs.stat(subdirPath, function (err, stats) { + if (err && err.code !== 'ENOENT') { + return next(err); + } + + if (err || !stats.isDirectory()) { + return next(); + } + + pluginPaths.push(dirname + '/' + subdir); + next(); + }); + }, cb); + }, + ], next); + }, function (err) { + next(err, pluginPaths); + }); }, - function (files, next) { + function (dirs, next) { + dirs = dirs.map(function (dir) { + return path.join(nodeModulesPath, dir); + }); var plugins = []; - async.each(files, function (file, next) { + async.each(dirs, function (file, next) { async.waterfall([ function (next) { Plugins.loadPluginInfo(file, next); From dc324b36b2aef337f17a3070b24ed33f92d40b96 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Wed, 19 Jul 2017 11:38:51 -0600 Subject: [PATCH 3/3] Add test for Plugins.showInstalled --- src/plugins.js | 11 ++++++----- .../@nodebb/another-thing/package.json | 1 + .../@nodebb/another-thing/plugin.json | 1 + .../@nodebb/nodebb-plugin-abc/package.json | 1 + .../@nodebb/nodebb-plugin-abc/plugin.json | 1 + .../nodebb-plugin-xyz/package.json | 1 + .../nodebb-plugin-xyz/plugin.json | 1 + .../plugin_modules/something-else/package.json | 1 + .../plugin_modules/something-else/plugin.json | 1 + test/plugins.js | 17 +++++++++++++++++ 10 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 test/mocks/plugin_modules/@nodebb/another-thing/package.json create mode 100644 test/mocks/plugin_modules/@nodebb/another-thing/plugin.json create mode 100644 test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/package.json create mode 100644 test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/plugin.json create mode 100644 test/mocks/plugin_modules/nodebb-plugin-xyz/package.json create mode 100644 test/mocks/plugin_modules/nodebb-plugin-xyz/plugin.json create mode 100644 test/mocks/plugin_modules/something-else/package.json create mode 100644 test/mocks/plugin_modules/something-else/plugin.json diff --git a/src/plugins.js b/src/plugins.js index de328887eb..41cd1da7b8 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -297,25 +297,26 @@ Plugins.normalise = function (apiReturn, callback) { }); }; +Plugins.nodeModulesPath = path.join(__dirname, '../node_modules'); + Plugins.showInstalled = function (callback) { - var nodeModulesPath = path.join(__dirname, '../node_modules'); var pluginNamePattern = /^(@.*?\/)?nodebb-(theme|plugin|widget|rewards)-.*$/; async.waterfall([ function (next) { - fs.readdir(nodeModulesPath, next); + fs.readdir(Plugins.nodeModulesPath, next); }, function (dirs, next) { var pluginPaths = []; async.each(dirs, function (dirname, next) { - var dirPath = path.join(nodeModulesPath, dirname); + var dirPath = path.join(Plugins.nodeModulesPath, dirname); async.waterfall([ function (cb) { fs.stat(dirPath, function (err, stats) { if (err && err.code !== 'ENOENT') { - return next(err); + return cb(err); } if (err || !stats.isDirectory()) { return next(); @@ -361,7 +362,7 @@ Plugins.showInstalled = function (callback) { function (dirs, next) { dirs = dirs.map(function (dir) { - return path.join(nodeModulesPath, dir); + return path.join(Plugins.nodeModulesPath, dir); }); var plugins = []; diff --git a/test/mocks/plugin_modules/@nodebb/another-thing/package.json b/test/mocks/plugin_modules/@nodebb/another-thing/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/@nodebb/another-thing/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/@nodebb/another-thing/plugin.json b/test/mocks/plugin_modules/@nodebb/another-thing/plugin.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/@nodebb/another-thing/plugin.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/package.json b/test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/plugin.json b/test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/plugin.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/@nodebb/nodebb-plugin-abc/plugin.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/nodebb-plugin-xyz/package.json b/test/mocks/plugin_modules/nodebb-plugin-xyz/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/nodebb-plugin-xyz/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/nodebb-plugin-xyz/plugin.json b/test/mocks/plugin_modules/nodebb-plugin-xyz/plugin.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/nodebb-plugin-xyz/plugin.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/something-else/package.json b/test/mocks/plugin_modules/something-else/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/something-else/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/mocks/plugin_modules/something-else/plugin.json b/test/mocks/plugin_modules/something-else/plugin.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/mocks/plugin_modules/something-else/plugin.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/plugins.js b/test/plugins.js index caccbe2851..40c6c9c97f 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -94,6 +94,23 @@ describe('Plugins', function () { }); }); + it('should show installed plugins', function (done) { + var nodeModulesPath = plugins.nodeModulesPath; + plugins.nodeModulesPath = path.join(__dirname, './mocks/plugin_modules'); + + plugins.showInstalled(function (err, pluginsData) { + assert.ifError(err); + var paths = pluginsData.map(function (plugin) { + return path.relative(plugins.nodeModulesPath, plugin.path).replace(/\\/g, '/'); + }); + assert(paths.indexOf('nodebb-plugin-xyz') > -1); + assert(paths.indexOf('@nodebb/nodebb-plugin-abc') > -1); + + plugins.nodeModulesPath = nodeModulesPath; + done(); + }); + }); + describe('install/activate/uninstall', function () { var latest; var pluginName = 'nodebb-plugin-imgur';