summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/models/plugin.js7
-rw-r--r--lib/plugins/__tests__/listDependencies.js (renamed from lib/plugins/__tests__/listAll.js)10
-rw-r--r--lib/plugins/__tests__/sortDependencies.js42
-rw-r--r--lib/plugins/__tests__/sortPlugins.js45
-rw-r--r--lib/plugins/findInstalled.js29
-rw-r--r--lib/plugins/listAll.js44
-rw-r--r--lib/plugins/listDependencies.js33
-rw-r--r--lib/plugins/listDepsForBook.js18
-rw-r--r--lib/plugins/listForBook.js18
-rw-r--r--lib/plugins/loadForBook.js68
-rw-r--r--lib/plugins/sortDependencies.js (renamed from lib/plugins/sortPlugins.js)16
11 files changed, 172 insertions, 158 deletions
diff --git a/lib/models/plugin.js b/lib/models/plugin.js
index c8bb2f7..acabba9 100644
--- a/lib/models/plugin.js
+++ b/lib/models/plugin.js
@@ -18,6 +18,9 @@ var Plugin = Immutable.Record({
// Depth of this plugin in the dependency tree
depth: Number(0),
+ // Parent depending on this plugin
+ parent: String(),
+
// Content of the "package.json"
package: Immutable.Map(),
@@ -49,6 +52,10 @@ Plugin.prototype.getDepth = function() {
return this.get('depth');
};
+Plugin.prototype.getParent = function() {
+ return this.get('parent');
+};
+
/**
* Return the ID on NPM for this plugin
* @return {String}
diff --git a/lib/plugins/__tests__/listAll.js b/lib/plugins/__tests__/listDependencies.js
index 6a08c84..940faba 100644
--- a/lib/plugins/__tests__/listAll.js
+++ b/lib/plugins/__tests__/listDependencies.js
@@ -1,11 +1,11 @@
var PluginDependency = require('../../models/pluginDependency');
-var listAll = require('../listAll');
+var listDependencies = require('../listDependencies');
var toNames = require('../toNames');
-describe('listAll', function() {
+describe('listDependencies', function() {
it('must list default', function() {
var deps = PluginDependency.listFromString('ga,great');
- var plugins = listAll(deps);
+ var plugins = listDependencies(deps);
var names = toNames(plugins);
expect(names).toEqual([
@@ -16,7 +16,7 @@ describe('listAll', function() {
it('must list from array with -', function() {
var deps = PluginDependency.listFromString('ga,-great');
- var plugins = listAll(deps);
+ var plugins = listDependencies(deps);
var names = toNames(plugins);
expect(names).toEqual([
@@ -27,7 +27,7 @@ describe('listAll', function() {
it('must remove default plugins using -', function() {
var deps = PluginDependency.listFromString('ga,-search');
- var plugins = listAll(deps);
+ var plugins = listDependencies(deps);
var names = toNames(plugins);
expect(names).toEqual([
diff --git a/lib/plugins/__tests__/sortDependencies.js b/lib/plugins/__tests__/sortDependencies.js
new file mode 100644
index 0000000..87df477
--- /dev/null
+++ b/lib/plugins/__tests__/sortDependencies.js
@@ -0,0 +1,42 @@
+var PluginDependency = require('../../models/pluginDependency');
+var sortDependencies = require('../sortDependencies');
+var toNames = require('../toNames');
+
+describe('sortDependencies', function() {
+ it('must load themes after plugins', function() {
+ var allPlugins = PluginDependency.listFromArray([
+ 'hello',
+ 'theme-test',
+ 'world'
+ ]);
+
+ var sorted = sortDependencies(allPlugins);
+ var names = toNames(sorted);
+
+ expect(names).toEqual([
+ 'hello',
+ 'world',
+ 'theme-test'
+ ]);
+ });
+
+ it('must keep order of themes', function() {
+ var allPlugins = PluginDependency.listFromArray([
+ 'theme-test',
+ 'theme-test1',
+ 'hello',
+ 'theme-test2',
+ 'world'
+ ]);
+ var sorted = sortDependencies(allPlugins);
+ var names = toNames(sorted);
+
+ expect(names).toEqual([
+ 'hello',
+ 'world',
+ 'theme-test',
+ 'theme-test1',
+ 'theme-test2'
+ ]);
+ });
+}); \ No newline at end of file
diff --git a/lib/plugins/__tests__/sortPlugins.js b/lib/plugins/__tests__/sortPlugins.js
deleted file mode 100644
index 4aa26a3..0000000
--- a/lib/plugins/__tests__/sortPlugins.js
+++ /dev/null
@@ -1,45 +0,0 @@
-var Immutable = require('immutable');
-
-var Plugin = require('../../models/plugin');
-var sortPlugins = require('../sortPlugins');
-var toNames = require('../toNames');
-
-describe('sortPlugins', function() {
- it('must load themes after plugins', function() {
- var allPlugins = Immutable.OrderedMap([
- ['hello', Plugin.createFromString('hello')],
- ['theme-test', Plugin.createFromString('theme-test')],
- ['world', Plugin.createFromString('world')]
- ]);
-
- var sorted = sortPlugins(allPlugins);
- var names = toNames(sorted);
-
- expect(names).toEqual([
- 'hello',
- 'world',
- 'theme-test'
- ]);
- });
-
- it('must keep order of themes', function() {
- var allPlugins = Immutable.OrderedMap([
- ['theme-test', Plugin.createFromString('theme-test')],
- ['theme-test1', Plugin.createFromString('theme-test1')],
- ['hello', Plugin.createFromString('hello')],
- ['theme-test2', Plugin.createFromString('theme-test2')],
- ['world', Plugin.createFromString('world')]
- ]);
-
- var sorted = sortPlugins(allPlugins);
- var names = toNames(sorted);
-
- expect(names).toEqual([
- 'hello',
- 'world',
- 'theme-test',
- 'theme-test1',
- 'theme-test2'
- ]);
- });
-}); \ No newline at end of file
diff --git a/lib/plugins/findInstalled.js b/lib/plugins/findInstalled.js
index dca3cbf..06cc6c4 100644
--- a/lib/plugins/findInstalled.js
+++ b/lib/plugins/findInstalled.js
@@ -8,21 +8,21 @@ var Plugin = require('../models/plugin');
var PREFIX = require('../constants/pluginPrefix');
/**
- Validate if a package name is a GitBook plugin
-
- @return {Boolean}
-*/
+ * Validate if a package name is a GitBook plugin
+ *
+ * @return {Boolean}
+ */
function validateId(name) {
return name && name.indexOf(PREFIX) === 0;
}
/**
- List all packages installed inside a folder
-
- @param {String} folder
- @return {OrderedMap<String:Plugin>}
-*/
+ * List all packages installed inside a folder
+ *
+ * @param {String} folder
+ * @return {OrderedMap<String:Plugin>}
+ */
function findInstalled(folder) {
var options = {
dev: false,
@@ -31,7 +31,7 @@ function findInstalled(folder) {
};
var results = Immutable.OrderedMap();
- function onPackage(pkg, isRoot) {
+ function onPackage(pkg, parent) {
if (!pkg.name) return;
var name = pkg.name;
@@ -43,18 +43,19 @@ function findInstalled(folder) {
var pluginName = name.slice(PREFIX.length);
if (!validateId(name)){
- if (!isRoot) return;
+ if (parent) return;
} else {
results = results.set(pluginName, Plugin({
name: pluginName,
version: version,
path: pkgPath,
- depth: depth
+ depth: depth,
+ parent: parent
}));
}
Immutable.Map(dependencies).forEach(function(dep) {
- onPackage(dep);
+ onPackage(dep, pluginName);
});
}
@@ -77,7 +78,7 @@ function findInstalled(folder) {
var module_folder = path.join(node_modules, module);
return Promise.nfcall(readInstalled, module_folder, options)
.then(function(data) {
- onPackage(data, true);
+ onPackage(data);
});
});
})
diff --git a/lib/plugins/listAll.js b/lib/plugins/listAll.js
deleted file mode 100644
index 70bf9cd..0000000
--- a/lib/plugins/listAll.js
+++ /dev/null
@@ -1,44 +0,0 @@
-var Immutable = require('immutable');
-var Plugin = require('../models/plugin');
-
-var DEFAULT_PLUGINS = require('../constants/defaultPlugins');
-var sortPlugins = require('./sortPlugins');
-
-/**
- List all plugins for a book
-
- @param {List<PluginDependency>} deps
- @return {OrderedMap<Plugin>}
-*/
-function listAll(deps) {
- // Extract list of plugins to disable (starting with -)
- var toRemove = deps
- .filter(function(plugin) {
- return !plugin.isEnabled();
- })
- .map(function(plugin) {
- return plugin.getName();
- });
-
- // Concat with default plugins
- deps = deps.concat(DEFAULT_PLUGINS);
-
- // Convert to an ordered map of Plugin
- var plugins = deps
- .map(function(dep) {
- var plugin = Plugin.createFromDep(dep);
-
- return [dep.getName(), plugin];
- });
- plugins = Immutable.OrderedMap(plugins);
-
- // Remove plugins
- plugins = plugins.filterNot(function(plugin, name) {
- return toRemove.includes(name);
- });
-
- // Sort plugins
- return sortPlugins(plugins);
-}
-
-module.exports = listAll;
diff --git a/lib/plugins/listDependencies.js b/lib/plugins/listDependencies.js
new file mode 100644
index 0000000..d52eaa9
--- /dev/null
+++ b/lib/plugins/listDependencies.js
@@ -0,0 +1,33 @@
+var DEFAULT_PLUGINS = require('../constants/defaultPlugins');
+var sortDependencies = require('./sortDependencies');
+
+/**
+ * List all dependencies for a book, including default plugins.
+ * It returns a concat with default plugins and remove disabled ones.
+ *
+ * @param {List<PluginDependency>} deps
+ * @return {List<PluginDependency>}
+ */
+function listDependencies(deps) {
+ // Extract list of plugins to disable (starting with -)
+ var toRemove = deps
+ .filter(function(plugin) {
+ return !plugin.isEnabled();
+ })
+ .map(function(plugin) {
+ return plugin.getName();
+ });
+
+ // Concat with default plugins
+ deps = deps.concat(DEFAULT_PLUGINS);
+
+ // Remove plugins
+ deps = deps.filterNot(function(plugin) {
+ return toRemove.includes(plugin.getName());
+ });
+
+ // Sort
+ return sortDependencies(deps);
+}
+
+module.exports = listDependencies;
diff --git a/lib/plugins/listDepsForBook.js b/lib/plugins/listDepsForBook.js
new file mode 100644
index 0000000..196e3aa
--- /dev/null
+++ b/lib/plugins/listDepsForBook.js
@@ -0,0 +1,18 @@
+var listDependencies = require('./listDependencies');
+
+/**
+ * List all plugin requirements for a book.
+ * It can be different from the final list of plugins,
+ * since plugins can have their own dependencies
+ *
+ * @param {Book}
+ * @return {List<PluginDependency>}
+ */
+function listDepsForBook(book) {
+ var config = book.getConfig();
+ var plugins = config.getPluginDependencies();
+
+ return listDependencies(plugins);
+}
+
+module.exports = listDepsForBook;
diff --git a/lib/plugins/listForBook.js b/lib/plugins/listForBook.js
deleted file mode 100644
index 5fb920f..0000000
--- a/lib/plugins/listForBook.js
+++ /dev/null
@@ -1,18 +0,0 @@
-var listAll = require('./listAll');
-
-/**
- List all plugin requirements for a book.
- It can be different from the final list of plugins,
- since plugins can have their own dependencies
-
- @param {Book}
- @return {OrderedMap<Plugin>}
-*/
-function listForBook(book) {
- var config = book.getConfig();
- var plugins = config.getPluginDependencies();
-
- return listAll(plugins);
-}
-
-module.exports = listForBook;
diff --git a/lib/plugins/loadForBook.js b/lib/plugins/loadForBook.js
index 96a0cb5..757677e 100644
--- a/lib/plugins/loadForBook.js
+++ b/lib/plugins/loadForBook.js
@@ -1,47 +1,69 @@
-var Promise = require('../utils/promise');
+var Immutable = require('immutable');
-var listForBook = require('./listForBook');
+var Promise = require('../utils/promise');
+var listDepsForBook = require('./listDepsForBook');
var findForBook = require('./findForBook');
var loadPlugin = require('./loadPlugin');
/**
- * Load a list of plugins in a book
+ * Load all plugins in a book
+ *
* @param {Book}
* @return {Promise<Map<String:Plugin>}
*/
function loadForBook(book) {
var logger = book.getLogger();
- var requirements = listForBook(book);
- var requirementsKeys = requirements.keySeq().toList();
+ // List the dependencies
+ var requirements = listDepsForBook(book);
+
+ // List all plugins installed in the book
return findForBook(book)
- .then(function(installed) {
- // Filter out plugins not listed of first level
- // (aka pre-installed plugins)
- installed = installed.filter(function(plugin) {
- return (
- plugin.getDepth() > 0 ||
- requirements.has(plugin.getName())
- );
- });
+ .then(function(installedMap) {
+ var missing = [];
+ var plugins = requirements.reduce(function(result, dep) {
+ var name = dep.getName();
+ var installed = installedMap.get(name);
+
+ if (installed) {
+ var deps = installedMap
+ .filter(function(plugin) {
+ return plugin.getParent() === name;
+ })
+ .toArray();
+
+ result = result.concat(deps);
+ result.push(installed);
+ } else {
+ missing.push(name);
+ }
+
+ return result;
+ }, []);
+
+ // Convert plugins list to a map
+ plugins = Immutable.List(plugins)
+ .map(function(plugin) {
+ return [
+ plugin.getName(),
+ plugin
+ ];
+ });
+ plugins = Immutable.OrderedMap(plugins);
// Log state
- logger.info.ln(installed.size + ' plugins are installed');
- if (requirements.size != installed.size) {
+ logger.info.ln(installedMap.size + ' plugins are installed');
+ if (requirements.size != installedMap.size) {
logger.info.ln(requirements.size + ' explicitly listed');
}
// Verify that all plugins are present
- var notInstalled = requirementsKeys.filter(function(name) {
- return !installed.has(name);
- });
-
- if (notInstalled.size > 0) {
- throw new Error('Couldn\'t locate plugins "' + notInstalled.join(', ') + '", Run \'gitbook install\' to install plugins from registry.');
+ if (missing.length > 0) {
+ throw new Error('Couldn\'t locate plugins "' + missing.join(', ') + '", Run \'gitbook install\' to install plugins from registry.');
}
- return Promise.map(installed, function(plugin) {
+ return Promise.map(plugins, function(plugin) {
return loadPlugin(book, plugin);
});
});
diff --git a/lib/plugins/sortPlugins.js b/lib/plugins/sortDependencies.js
index 155b691..7f10095 100644
--- a/lib/plugins/sortPlugins.js
+++ b/lib/plugins/sortDependencies.js
@@ -18,19 +18,17 @@ function pluginType(plugin) {
/**
- * Sort the list of installed plugins to match list in book.json
+ * Sort the list of dependencies to match list in book.json
* The themes should always be loaded after the plugins
*
- * @param {<OrderedMap<String:Plugin>>} plugins
- * @return {OrderedMap<String:Plugin>}
+ * @param {List<PluginDependency>} deps
+ * @return {List<PluginDependency>}
*/
-function sortPlugins(plugins) {
+function sortDependencies(plugins) {
var byTypes = plugins.groupBy(pluginType);
- return byTypes.get(TYPE_PLUGIN, Immutable.OrderedMap())
- .merge(
- byTypes.get(TYPE_THEME, Immutable.OrderedMap())
- );
+ return byTypes.get(TYPE_PLUGIN, Immutable.List())
+ .concat(byTypes.get(TYPE_THEME, Immutable.List()));
}
-module.exports = sortPlugins; \ No newline at end of file
+module.exports = sortDependencies; \ No newline at end of file