diff options
author | Samy Pesse <samypesse@gmail.com> | 2016-02-16 18:46:16 +0100 |
---|---|---|
committer | Samy Pesse <samypesse@gmail.com> | 2016-02-16 18:46:16 +0100 |
commit | ca85c0ecf35eb2265b35ae480fbe34b12cf4bafe (patch) | |
tree | 06ca414fd4d54a3c8f8b2266d72cb91525d17c3c /lib/plugins | |
parent | 702db46f20d2b613540901311708cf4e49d95690 (diff) | |
download | gitbook-ca85c0ecf35eb2265b35ae480fbe34b12cf4bafe.zip gitbook-ca85c0ecf35eb2265b35ae480fbe34b12cf4bafe.tar.gz gitbook-ca85c0ecf35eb2265b35ae480fbe34b12cf4bafe.tar.bz2 |
Add method to install plugin from npm
Add tests for it
Diffstat (limited to 'lib/plugins')
-rw-r--r-- | lib/plugins/registry.js | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/lib/plugins/registry.js b/lib/plugins/registry.js index 6b1cddb..3fa532c 100644 --- a/lib/plugins/registry.js +++ b/lib/plugins/registry.js @@ -1,4 +1,10 @@ var npm = require('npm'); +var npmi = require('npmi'); +var semver = require('semver'); +var _ = require('lodash'); + +var Promise = require('../utils/promise'); +var gitbook = require('../gitbook'); var PLUGIN_PREFIX = 'gitbook-plugin-'; @@ -18,14 +24,84 @@ function validateId(name) { return name.indexOf(PLUGIN_PREFIX) === 0; } +// Initialize NPM for operations +var initNPM = _.memoize(function() { + return Promise.nfcall(npm.load, { + silent: true, + loglevel: 'silent' + }); +}); + // Link a plugin for use in a specific book function linkPlugin(book, pluginPath) { book.log('linking', pluginPath); } +// Resolve the latest version for a plugin +function resolveVersion(plugin) { + var npnName = npmId(plugin); + + return initNPM() + .then(function() { + return Promise.nfcall(npm.commands.view, [npnName+'@*', 'engines'], true); + }) + .then(function(versions) { + return _.chain(versions) + .pairs() + .map(function(v) { + return { + version: v[0], + gitbook: (v[1].engines || {}).gitbook + }; + }) + .filter(function(v) { + return v.gitbook && gitbook.satisfies(v.gitbook); + }) + .sort(function(v1, v2) { + return semver.lt(v1.version, v2.version)? 1 : -1; + }) + .pluck('version') + .first() + .value(); + }); +} + + // Install a plugin in a book -function installPlugin(book, pluginId) { - book.log('installing plugin', pluginId); +function installPlugin(book, plugin, version) { + book.log.info.ln('installing plugin', plugin); + + var npnName = npmId(plugin); + + return Promise() + .then(function() { + if (version) return version; + + book.log.info.ln('No version specified, resolve plugin "' + plugin + '"'); + return resolveVersion(plugin); + }) + + // Install the plugin with the resolved version + .then(function(version) { + if (!version) { + throw new Error('Found no satisfactory version for plugin "' + plugin + '"'); + } + + book.log.info.ln('install plugin' + plugin +'" from npm ('+npnName+') with version', version); + return Promise.nfcall(npmi, { + 'name': npnName, + 'version': version, + 'path': book.root, + 'npmLoad': { + 'loglevel': 'silent', + 'loaded': true, + 'prefix': book.root + } + }); + }) + .then(function() { + book.log.info.ok('plugin "' + plugin.name + '" installed with success'); + }); } module.exports = { @@ -33,6 +109,7 @@ module.exports = { pluginId: pluginId, validateId: validateId, + resolve: resolveVersion, link: linkPlugin, install: installPlugin }; |