diff options
author | Samy Pesse <samypesse@gmail.com> | 2016-05-02 22:02:45 +0200 |
---|---|---|
committer | Samy Pesse <samypesse@gmail.com> | 2016-05-02 22:02:45 +0200 |
commit | 41e687255717c43d1bf2745e7b806057c7de16ae (patch) | |
tree | 6be8992936b0c0ec006fc46d5f7577791494aba1 | |
parent | 8de0d6186e8a10cdd5a3efe9a4cf0afcae734223 (diff) | |
parent | 30c96c37c2145a28710e2875c677d37156fdaa92 (diff) | |
download | gitbook-41e687255717c43d1bf2745e7b806057c7de16ae.zip gitbook-41e687255717c43d1bf2745e7b806057c7de16ae.tar.gz gitbook-41e687255717c43d1bf2745e7b806057c7de16ae.tar.bz2 |
Merge branch 'fix/plugins_deps'
-rw-r--r-- | lib/models/__tests__/plugin.js | 2 | ||||
-rw-r--r-- | lib/models/__tests__/pluginDependency.js | 47 | ||||
-rw-r--r-- | lib/models/config.js | 28 | ||||
-rw-r--r-- | lib/models/plugin.js | 13 | ||||
-rw-r--r-- | lib/models/pluginDependency.js | 115 | ||||
-rw-r--r-- | lib/modifiers/config/addPlugin.js | 13 | ||||
-rw-r--r-- | lib/modifiers/config/removePlugin.js | 12 | ||||
-rw-r--r-- | lib/parse/parseConfig.js | 4 | ||||
-rw-r--r-- | lib/plugins/__tests__/listAll.js | 53 | ||||
-rw-r--r-- | lib/plugins/listAll.js | 43 | ||||
-rw-r--r-- | lib/plugins/listForBook.js | 2 | ||||
-rw-r--r-- | lib/utils/promise.js | 5 | ||||
-rw-r--r-- | package.json | 5 |
13 files changed, 249 insertions, 93 deletions
diff --git a/lib/models/__tests__/plugin.js b/lib/models/__tests__/plugin.js index 81d9d51..b229664 100644 --- a/lib/models/__tests__/plugin.js +++ b/lib/models/__tests__/plugin.js @@ -1,5 +1,3 @@ -jest.autoMockOff(); - describe('Plugin', function() { var Plugin = require('../plugin'); diff --git a/lib/models/__tests__/pluginDependency.js b/lib/models/__tests__/pluginDependency.js new file mode 100644 index 0000000..8aa55fb --- /dev/null +++ b/lib/models/__tests__/pluginDependency.js @@ -0,0 +1,47 @@ +describe('PluginDependency', function() { + var PluginDependency = require('../pluginDependency'); + + describe('createFromString', function() { + it('must parse name', function() { + var plugin = PluginDependency.createFromString('hello'); + expect(plugin.getName()).toBe('hello'); + expect(plugin.getVersion()).toBe('*'); + }); + + it('must parse state', function() { + var plugin = PluginDependency.createFromString('-hello'); + expect(plugin.getName()).toBe('hello'); + expect(plugin.isEnabled()).toBe(false); + }); + + describe('Version', function() { + it('must parse version', function() { + var plugin = PluginDependency.createFromString('hello@1.0.0'); + expect(plugin.getName()).toBe('hello'); + expect(plugin.getVersion()).toBe('1.0.0'); + }); + + it('must parse semver', function() { + var plugin = PluginDependency.createFromString('hello@>=4.0.0'); + expect(plugin.getName()).toBe('hello'); + expect(plugin.getVersion()).toBe('>=4.0.0'); + }); + }); + + describe('GIT Version', function() { + it('must handle HTTPS urls', function() { + var plugin = PluginDependency.createFromString('hello@git+https://github.com/GitbookIO/plugin-ga.git'); + expect(plugin.getName()).toBe('hello'); + expect(plugin.getVersion()).toBe('git+https://github.com/GitbookIO/plugin-ga.git'); + }); + + it('must handle SSH urls', function() { + var plugin = PluginDependency.createFromString('hello@git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); + expect(plugin.getName()).toBe('hello'); + expect(plugin.getVersion()).toBe('git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); + }); + }); + }); +}); + + diff --git a/lib/models/config.js b/lib/models/config.js index 6ee03e4..83dd6d4 100644 --- a/lib/models/config.js +++ b/lib/models/config.js @@ -2,6 +2,7 @@ var is = require('is'); var Immutable = require('immutable'); var File = require('./file'); +var PluginDependency = require('./pluginDependency'); var configDefault = require('../constants/configDefault'); var Config = Immutable.Record({ @@ -53,6 +54,33 @@ Config.prototype.setValue = function(keyPath, value) { }; /** + Return a list of plugin dependencies + + @return {List<PluginDependency>} +*/ +Config.prototype.getPluginDependencies = function() { + var plugins = this.getValue('plugins'); + + if (is.string(plugins)) { + return PluginDependency.listFromString(plugins); + } else { + return PluginDependency.listFromArray(plugins); + } +}; + +/** + Update the list of plugins dependencies + + @param {List<PluginDependency>} + @return {Config} +*/ +Config.prototype.setPluginDependencies = function(deps) { + var plugins = PluginDependency.listToArray(deps); + + return this.setValue('plugins', plugins); +}; + +/** Create a new config for a file @param {File} file diff --git a/lib/models/plugin.js b/lib/models/plugin.js index dd7bc90..23019aa 100644 --- a/lib/models/plugin.js +++ b/lib/models/plugin.js @@ -140,6 +140,19 @@ Plugin.createFromString = function(s) { }; /** + Create a plugin from a dependency + + @param {PluginDependency} + @return {Plugin} +*/ +Plugin.createFromDep = function(dep) { + return new Plugin({ + name: dep.getName(), + version: dep.getVersion() + }); +}; + +/** Return NPM id for a plugin name @param {String} diff --git a/lib/models/pluginDependency.js b/lib/models/pluginDependency.js new file mode 100644 index 0000000..bb8e4b4 --- /dev/null +++ b/lib/models/pluginDependency.js @@ -0,0 +1,115 @@ +var is = require('is'); +var Immutable = require('immutable'); + +var DEFAULT_VERSION = '*'; + +/* + PluginDependency represents the informations about a plugin + stored in config.plugins +*/ +var PluginDependency = Immutable.Record({ + name: String(), + + // Requirement version (ex: ">1.0.0") + version: String(DEFAULT_VERSION), + + // Is this plugin enabled or disabled? + enabled: Boolean(true) +}, 'PluginDependency'); + +PluginDependency.prototype.getName = function() { + return this.get('name'); +}; + +PluginDependency.prototype.getVersion = function() { + return this.get('version'); +}; + +PluginDependency.prototype.isEnabled = function() { + return this.get('enabled'); +}; + +/** + Create a plugin from a string + + @param {String} + @return {Plugin|undefined} +*/ +PluginDependency.createFromString = function(s) { + var parts = s.split('@'); + var name = parts[0]; + var version = parts.slice(1).join('@'); + var enabled = true; + + if (name[0] === '-') { + enabled = false; + name = name.slice(1); + } + + return new PluginDependency({ + name: name, + version: version || DEFAULT_VERSION, + enabled: enabled + }); +}; + +/** + Create a PluginDependency from a string + + @param {String} + @return {List<PluginDependency>} +*/ +PluginDependency.listFromString = function(s) { + var parts = s.split(','); + return PluginDependency.listFromArray(parts); +}; + +/** + Create a PluginDependency from an array + + @param {Array} + @return {List<PluginDependency>} +*/ +PluginDependency.listFromArray = function(arr) { + return Immutable.List(arr) + .map(function(entry) { + if (is.string(entry)) { + return PluginDependency.createFromString(entry); + } else { + return PluginDependency({ + name: entry.name, + version: entry.version + }); + } + }) + .filter(function(dep) { + return Boolean(dep.getName()); + }); +}; + +/** + Export plugin dependencies as an array + + @param {List<PluginDependency>} + @return {Array<String>} +*/ +PluginDependency.listToArray = function(arr) { + return arr + .map(function(dep) { + var result; + + if (dep.isEnabled()) { + result += '-'; + } + + result += dep.getName(); + if (dep.getVersion() !== DEFAULT_VERSION) { + result += '@' + dep.getVersion(); + } + + return result; + }) + .toJS(); +}; + +module.exports = PluginDependency; diff --git a/lib/modifiers/config/addPlugin.js b/lib/modifiers/config/addPlugin.js index 938b686..2a04a03 100644 --- a/lib/modifiers/config/addPlugin.js +++ b/lib/modifiers/config/addPlugin.js @@ -1,4 +1,4 @@ - +var PluginDependency = require('../../models/pluginDependency'); /** Add a plugin to a book's configuration @@ -9,10 +9,15 @@ */ function addPlugin(book, plugin, version) { var config = book.getConfig(); - var plugins = config.getValue('plugins', []); + var deps = config.getPluginDependencies(); + + var dep = PluginDependency({ + name: plugin, + version: version + }); - plugins = plugins.push('livereload'); - config = config.setValue('plugins', plugins); + deps = deps.push(dep); + config = config.setPluginDependencies(deps); return book.setConfig(config); } diff --git a/lib/modifiers/config/removePlugin.js b/lib/modifiers/config/removePlugin.js index 8c58f16..bc6bcc8 100644 --- a/lib/modifiers/config/removePlugin.js +++ b/lib/modifiers/config/removePlugin.js @@ -8,15 +8,13 @@ */ function removePlugin(book, pluginName) { var config = book.getConfig(); - var plugins = config.getValue('plugins', []); + var deps = config.getPluginDependencies(); - // Find index of this plugin - var index = plugins.findIndex(function(plugin) { - return plugin === pluginName; - }); - plugins = plugins.delete(index); - config = config.setValue('plugins', plugins); + deps = deps.filter(function(dep) { + return dep.getName() === pluginName; + }); + config = config.setPluginDependencies(deps); return book.setConfig(config); } diff --git a/lib/parse/parseConfig.js b/lib/parse/parseConfig.js index 3ab64b7..a1e9d69 100644 --- a/lib/parse/parseConfig.js +++ b/lib/parse/parseConfig.js @@ -45,10 +45,6 @@ function parseConfig(book) { values = validateConfig(values); - if (is.string(values.plugins)) { - values.plugins = values.plugins.split(','); - } - var config = Config.create(file, values); return book.set('config', config); }); diff --git a/lib/plugins/__tests__/listAll.js b/lib/plugins/__tests__/listAll.js index 71483a7..f9711a7 100644 --- a/lib/plugins/__tests__/listAll.js +++ b/lib/plugins/__tests__/listAll.js @@ -1,21 +1,10 @@ -jest.autoMockOff(); +var PluginDependency = require('../../models/pluginDependency'); +var listAll = require('../listAll'); describe('listAll', function() { - var listAll = require('../listAll'); - - it('must list from string', function() { - var plugins = listAll('ga,great'); - - expect(plugins.size).toBe(8); - - expect(plugins.has('ga')).toBe(true); - expect(plugins.has('great')).toBe(true); - - expect(plugins.has('search')).toBe(true); - }); - - it('must list from array', function() { - var plugins = listAll(['ga', 'great']); + it('must list default', function() { + var deps = PluginDependency.listFromString('ga,great'); + var plugins = listAll(deps); expect(plugins.size).toBe(8); @@ -25,34 +14,9 @@ describe('listAll', function() { expect(plugins.has('search')).toBe(true); }); - it('must parse version (semver)', function() { - var plugins = listAll(['ga@1.0.0', 'great@>=4.0.0']); - - expect(plugins.has('ga')).toBe(true); - expect(plugins.has('great')).toBe(true); - - var ga = plugins.get('ga'); - expect(ga.getVersion()).toBe('1.0.0'); - - var great = plugins.get('great'); - expect(great.getVersion()).toBe('>=4.0.0'); - }); - - it('must parse version (git)', function() { - var plugins = listAll(['ga@git+https://github.com/GitbookIO/plugin-ga.git', 'great@git+ssh://samy@github.com/GitbookIO/plugin-ga.git']); - - expect(plugins.has('ga')).toBe(true); - expect(plugins.has('great')).toBe(true); - - var ga = plugins.get('ga'); - expect(ga.getVersion()).toBe('git+https://github.com/GitbookIO/plugin-ga.git'); - - var great = plugins.get('great'); - expect(great.getVersion()).toBe('git+ssh://samy@github.com/GitbookIO/plugin-ga.git'); - }); - it('must list from array with -', function() { - var plugins = listAll(['ga', '-great']); + var deps = PluginDependency.listFromString('ga,-great'); + var plugins = listAll(deps); expect(plugins.size).toBe(7); @@ -61,7 +25,8 @@ describe('listAll', function() { }); it('must remove default plugins using -', function() { - var plugins = listAll(['ga', '-search']); + var deps = PluginDependency.listFromString('ga,-search'); + var plugins = listAll(deps); expect(plugins.size).toBe(6); diff --git a/lib/plugins/listAll.js b/lib/plugins/listAll.js index d7ce5f3..9b2a96b 100644 --- a/lib/plugins/listAll.js +++ b/lib/plugins/listAll.js @@ -1,4 +1,3 @@ -var is = require('is'); var Immutable = require('immutable'); var Plugin = require('../models/plugin'); @@ -8,43 +7,27 @@ var DEFAULT_PLUGINS = require('../constants/defaultPlugins'); /** List all plugins for a book - @param {List<Plugin|String>} + @param {List<PluginDependency>} deps @return {OrderedMap<Plugin>} */ -function listAll(plugins) { - if (is.string(plugins)) { - plugins = Immutable.List(plugins.split(',')); - } - - // Convert to an ordered map - plugins = plugins.map(function(plugin) { - if (is.string(plugin)) { - plugin = Plugin.createFromString(plugin); - } else { - plugin = new Plugin(plugin); - } - - return [plugin.getName(), plugin]; - }); - plugins = Immutable.OrderedMap(plugins); - +function listAll(deps) { // Extract list of plugins to disable (starting with -) - var toRemove = plugins.toList() + var toRemove = deps .filter(function(plugin) { - return plugin.getName()[0] === '-'; + return !plugin.isEnabled(); }) .map(function(plugin) { - return plugin.getName().slice(1); + return plugin.getName(); }); - // Remove the '-' - plugins = plugins.mapKeys(function(name) { - if (name[0] === '-') { - return name.slice(1); - } else { - return name; - } - }); + // 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); // Append default plugins DEFAULT_PLUGINS.forEach(function(pluginName) { diff --git a/lib/plugins/listForBook.js b/lib/plugins/listForBook.js index ce94678..5fb920f 100644 --- a/lib/plugins/listForBook.js +++ b/lib/plugins/listForBook.js @@ -10,7 +10,7 @@ var listAll = require('./listAll'); */ function listForBook(book) { var config = book.getConfig(); - var plugins = config.getValue('plugins'); + var plugins = config.getPluginDependencies(); return listAll(plugins); } diff --git a/lib/utils/promise.js b/lib/utils/promise.js index 19d7554..138546b 100644 --- a/lib/utils/promise.js +++ b/lib/utils/promise.js @@ -1,6 +1,11 @@ var Q = require('q'); var Immutable = require('immutable'); +// Debugging for long stack traces +if (global.__DEV__ || process.env.DEBUG) { + Q.longStackSupport = true; +} + /** Reduce an array to a promise diff --git a/package.json b/package.json index 48983ce..96d3d2f 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,9 @@ ], "jest": { "automock": false, - "setupTestFrameworkScriptFile": "<rootDir>/jest/customMatchers.js" + "setupTestFrameworkScriptFile": "<rootDir>/jest/customMatchers.js", + "globals": { + "__DEV__": true + } } } |