summaryrefslogtreecommitdiffstats
path: root/lib/plugins/installPlugins.js
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2016-04-22 11:33:25 +0200
committerSamy Pessé <samypesse@gmail.com>2016-04-22 11:33:25 +0200
commitcc78b880cef726201f1670b5c9f7f6f3512c2dbe (patch)
tree2e41e8bf387b1f1efc5a78aa71e0369550cad495 /lib/plugins/installPlugins.js
parent4336fdb2414d460ffee68a0cc87c0cb0c85cf56e (diff)
downloadgitbook-cc78b880cef726201f1670b5c9f7f6f3512c2dbe.zip
gitbook-cc78b880cef726201f1670b5c9f7f6f3512c2dbe.tar.gz
gitbook-cc78b880cef726201f1670b5c9f7f6f3512c2dbe.tar.bz2
Add utils to install plugins
Diffstat (limited to 'lib/plugins/installPlugins.js')
-rw-r--r--lib/plugins/installPlugins.js125
1 files changed, 125 insertions, 0 deletions
diff --git a/lib/plugins/installPlugins.js b/lib/plugins/installPlugins.js
new file mode 100644
index 0000000..77ecfce
--- /dev/null
+++ b/lib/plugins/installPlugins.js
@@ -0,0 +1,125 @@
+var npm = require('npm');
+var npmi = require('npmi');
+var semver = require('semver');
+var Immutable = require('immutable');
+
+var Promise = require('../utils/promise');
+var Plugin = require('../models/plugin');
+var gitbook = require('../gitbook');
+
+var npmIsReady;
+
+/**
+ Initialize and prepare NPM
+
+ @return {Promise}
+*/
+function initNPM() {
+ if (npmIsReady) return npmIsReady;
+
+ npmIsReady = Promise.nfcall(npm.load, {
+ silent: true,
+ loglevel: 'silent'
+ });
+
+ return npmIsReady;
+}
+
+
+
+/**
+ Resolve a plugin to a version
+
+ @param {Plugin}
+ @return {Promise<String>}
+*/
+function resolveVersion(plugin) {
+ var npmId = Plugin.nameToNpmID(plugin.getName());
+ var requiredVersion = plugin.getVersion();
+
+ return initNPM()
+ .then(function() {
+ return Promise.nfcall(npm.commands.view, [npmId + '@' + requiredVersion, 'engines'], true);
+ })
+ .then(function(versions) {
+ versions = Immutable.Map(versions).entries().toList();
+
+ var result = versions
+ .map(function(entry) {
+ return {
+ version: entry[0],
+ gitbook: (entry[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;
+ })
+ .get(0);
+
+ if (!result) {
+ return undefined;
+ } else {
+ return result.get('version');
+ }
+ });
+}
+
+
+/**
+ Install a plugin for a book
+
+ @param {Book}
+ @param {Plugin}
+ @return {Promise}
+*/
+function installPlugin(book, plugin) {
+ var logger = book.getLogger();
+
+ var installFolder = book.getRoot();
+ var name = plugin.getName();
+ var requirement = plugin.getVersion();
+
+ logger.info.ln('installing plugin', name);
+
+ // Find a version to install
+ return resolveVersion(plugin)
+ .then(function(version) {
+ if (!version) {
+ throw new Error('Found no satisfactory version for plugin "' + name + '" with requirement "' + requirement + '"');
+ }
+
+ logger.info.ln('install plugin "' + plugin +'" from NPM with version', requirement);
+ return Promise.nfcall(npmi, {
+ 'name': plugin.getNpmID(),
+ 'version': version,
+ 'path': installFolder,
+ 'npmLoad': {
+ 'loglevel': 'silent',
+ 'loaded': true,
+ 'prefix': installFolder
+ }
+ });
+ })
+ .then(function() {
+ logger.info.ok('plugin "' + plugin + '" installed with success');
+ });
+}
+
+
+/**
+ Install plugin requirements for a book
+
+ @param {Book}
+ @param {OrderedMap<String:Plugin>}
+ @return {Promise}
+*/
+function installPlugins(book, plugins) {
+ return Promise.forEach(plugins, function(plugin) {
+ return installPlugin(book, plugin);
+ });
+}
+
+module.exports = installPlugins;