diff options
author | Samy Pessé <samypesse@gmail.com> | 2016-03-15 12:37:25 +0100 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2016-03-15 12:37:25 +0100 |
commit | fbffd54aa244d8a969200b0efbed3d7dc9eb73d0 (patch) | |
tree | 2b2dede4d212d40992a829cd33151d35a7a7d91d /lib/plugins | |
parent | 4d19a33af24d5ee68c473b78b81ae5e30ade6007 (diff) | |
download | gitbook-fbffd54aa244d8a969200b0efbed3d7dc9eb73d0.zip gitbook-fbffd54aa244d8a969200b0efbed3d7dc9eb73d0.tar.gz gitbook-fbffd54aa244d8a969200b0efbed3d7dc9eb73d0.tar.bz2 |
Load all plugins, even dependencies of plugins
Diffstat (limited to 'lib/plugins')
-rw-r--r-- | lib/plugins/index.js | 49 | ||||
-rw-r--r-- | lib/plugins/plugin.js | 33 | ||||
-rw-r--r-- | lib/plugins/registry.js | 18 |
3 files changed, 57 insertions, 43 deletions
diff --git a/lib/plugins/index.js b/lib/plugins/index.js index 88762c6..f897d9c 100644 --- a/lib/plugins/index.js +++ b/lib/plugins/index.js @@ -38,24 +38,21 @@ PluginsManager.prototype.get = function(name) { }); }; -// Load a plugin, or a list of plugins -PluginsManager.prototype.load = function(name) { +// Load a plugin (could be a BookPlugin or {name,path}) +PluginsManager.prototype.load = function(plugin) { var that = this; - if (_.isArray(name)) { - return Promise.serie(name, function(_name) { - return that.load(_name); - }); + if (_.isArray(plugin)) { + return Promise.serie(plugin, that.load); } return Promise() // Initiate and load the plugin .then(function() { - var plugin; - - if (!_.isString(name)) plugin = name; - else plugin = new BookPlugin(that.book, name); + if (!(plugin instanceof BookPlugin)) { + plugin = new BookPlugin(that.book, plugin.name, plugin.path); + } if (that.get(plugin.id)) { throw new Error('Plugin "'+plugin.id+'" is already loaded'); @@ -73,10 +70,36 @@ PluginsManager.prototype.load = function(name) { // Load all plugins from the book's configuration PluginsManager.prototype.loadAll = function() { - var plugins = _.pluck(this.book.config.get('plugins'), 'name'); + var that = this; + var pluginNames = _.pluck(this.book.config.get('plugins'), 'name'); + + return registry.list(this.book) + .then(function(plugins) { + // Filter out plugins not listed of first level + // (aka pre-installed plugins) + plugins = _.filter(plugins, function(plugin) { + return ( + plugin.depth > 1 || + _.contains(pluginNames, plugin.name) + ); + }); + + // Log state + that.log.info.ln(_.size(plugins) + ' are installed'); + if (_.size(pluginNames) != _.size(plugins)) that.log.info.ln(_.size(pluginNames) + ' explicitly listed'); - this.log.info.ln('loading', plugins.length, 'plugins'); - return this.load(plugins); + // Verify that all plugins are present + var notInstalled = _.filter(pluginNames, function(name) { + return !_.find(plugins, { name: name }); + }); + + if (_.size(notInstalled) > 0) { + throw new Error('Couldn\'t locate plugins "' + notInstalled.join(', ') + '", Run \'gitbook install\' to install plugins from registry.'); + } + + // Load plugins + return that.load(plugins); + }); }; // Setup a plugin diff --git a/lib/plugins/plugin.js b/lib/plugins/plugin.js index d707e5c..d1c00d8 100644 --- a/lib/plugins/plugin.js +++ b/lib/plugins/plugin.js @@ -24,13 +24,14 @@ function isModuleNotFound(err) { return err.message.indexOf('Cannot find module') >= 0; } -function BookPlugin(book, pluginId) { +function BookPlugin(book, pluginId, pluginFolder) { this.book = book; this.log = this.book.log.prefix(pluginId); + this.id = pluginId; this.npmId = registry.npmId(pluginId); - this.root; + this.root = pluginFolder; this.packageInfos = undefined; this.content = undefined; @@ -51,8 +52,7 @@ BookPlugin.prototype.bind = function(fn) { return fn.bind(compatibility.pluginCtx(this)); }; -// Load this plugin -// An optional folder to search in can be passed +// Load this plugin from its root folder BookPlugin.prototype.load = function(folder) { var that = this; @@ -60,18 +60,12 @@ BookPlugin.prototype.load = function(folder) { return Promise.reject(new Error('Plugin "' + this.id + '" is already loaded')); } - // Fodlers to search plugins in - var searchPaths = _.compact([ - folder, - this.book.resolve('node_modules'), - __dirname - ]); - // Try loading plugins from different location - var p = Promise.some(searchPaths, function(baseDir) { + var p = Promise() + .then(function() { // Locate plugin and load pacjage.json try { - var res = resolve.sync(that.npmId + '/package.json', { basedir: baseDir }); + var res = resolve.sync('./package.json', { basedir: that.root }); that.root = path.dirname(res); that.packageInfos = require(res); @@ -81,12 +75,12 @@ BookPlugin.prototype.load = function(folder) { that.packageInfos = undefined; that.content = undefined; - return false; + return; } // Load plugin JS content try { - that.content = require(resolve.sync(that.npmId, { basedir: baseDir })); + that.content = require(that.root); } catch(err) { // It's no big deal if the plugin doesn't have an "index.js" // (For example: themes) @@ -98,8 +92,6 @@ BookPlugin.prototype.load = function(folder) { }); } } - - return true; }) .then(that.validate) @@ -122,18 +114,15 @@ BookPlugin.prototype.load = function(folder) { // This method throws erros if plugin is invalid BookPlugin.prototype.validate = function() { var isValid = ( + this.isLoaded() && this.packageInfos && this.packageInfos.name && this.packageInfos.engines && this.packageInfos.engines.gitbook ); - if (!this.isLoaded()) { - throw new Error('Couldn\'t locate plugin "' + this.id + '", Run \'gitbook install\' to install plugins from registry.'); - } - if (!isValid) { - throw new Error('Invalid plugin "' + this.id + '"'); + throw new Error('Error loading plugin "' + this.id + '" at "' + this.root + '"'); } if (!gitbook.satisfies(this.packageInfos.engines.gitbook)) { diff --git a/lib/plugins/registry.js b/lib/plugins/registry.js index bc17a8c..ea172c4 100644 --- a/lib/plugins/registry.js +++ b/lib/plugins/registry.js @@ -23,7 +23,7 @@ function pluginId(name) { // Validate an NPM plugin ID function validateId(name) { - return name.indexOf(PLUGIN_PREFIX) === 0; + return name && name.indexOf(PLUGIN_PREFIX) === 0; } // Initialize NPM for operations @@ -107,24 +107,25 @@ function installPlugin(book, plugin, version) { } // List all packages installed inside a folder -// Returns a map { pluginName -> folder } +// Returns an ordered list of plugins function listInstalled(folder) { var options = { dev: false, log: function() {}, depth: 4 }; - var result = {}; + var results = []; function onPackage(pkg, isRoot) { if (!validateId(pkg.name)){ if (!isRoot) return; } else { - result[pluginId(pkg.name)] = { + results.push({ + name: pluginId(pkg.name), version: pkg.version, path: pkg.realPath, depth: pkg.depth - }; + }); } _.each(pkg.dependencies, function(dep) { @@ -135,18 +136,19 @@ function listInstalled(folder) { return Promise.nfcall(readInstalled, folder, options) .then(function(data) { onPackage(data, true); - return result; + return _.uniq(results, 'name'); }); } // List installed plugins for a book (defaults and installed) function listPlugins(book) { - return Promise.nfcall([ + return Promise.all([ listInstalled(path.resolve(__dirname, '../..')), listInstalled(book.root) ]) .spread(function(defaultPlugins, plugins) { - return _.extend(defaultPlugins, plugins); + var results = plugins.concat(defaultPlugins); + return _.uniq(results, 'name'); }); } |