Skip to content

Commit

Permalink
Adds support for hidden commands and plugins.
Browse files Browse the repository at this point in the history
  • Loading branch information
skellock committed Jan 2, 2017
1 parent d0c6f86 commit 2ccaab9
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 127 deletions.
12 changes: 10 additions & 2 deletions docs/runtime.md
Expand Up @@ -19,7 +19,7 @@ await build()
.load('~/Desktop/movie/quote')
.load('~/Desktop/movie/credits')
.loadAll('~/Downloads/VariousMoviePlugins')
.loadAll('./node_modules', 'movies-*')
.loadAll('./node_modules', { matching: 'movies-*', hidden: true })
.token('commandName', 'cliCommand')
.token('commandDescription', 'cliDescription')
.token('extensionName', 'contextExtension')
Expand Down Expand Up @@ -81,9 +81,17 @@ You can also load all immediate sub-directories located within it a directory.
Load all supports a `fs-jetpack` [matching pattern](https://github.com/szwacz/fs-jetpack#findpath-searchoptions) so you can filter out a subset of directories instead of just all.

```js
.loadAll('node_modules', 'movies-*')
.loadAll('node_modules', { matching: 'movies-*' })
```

If you would like to keep plugins hidden and not available at the command line:

```js
.loadAll('node_modules', { matching: 'movies-*', hidden: true })
```

When plugins are hidden they can still be run directly from the runtime.


# Finishing Configuration

Expand Down
8 changes: 0 additions & 8 deletions packages/gluegun/src/cli/banner.txt

This file was deleted.

90 changes: 0 additions & 90 deletions packages/gluegun/src/cli/index.js

This file was deleted.

7 changes: 7 additions & 0 deletions packages/gluegun/src/cli/print-commands.js
Expand Up @@ -17,6 +17,11 @@ const { isBlank } = require('../utils/string-utils')
*/
const hasLoadStateError = propEq('loadState', 'error')

/**
* Is this a hidden command?
*/
const isHidden = propEq('hidden', true)

/**
* Gets the list of plugins.
*
Expand All @@ -27,6 +32,7 @@ function getListOfPlugins (context) {
return pipe(
dotPath('runtime.plugins'),
reject(hasLoadStateError),
reject(isHidden),
reject(plugin => context.runtime.defaultPlugin && context.runtime.defaultPlugin.name === plugin.name),
sortBy(prop('name')),
map(plugin => [
Expand All @@ -47,6 +53,7 @@ function getListOfCommands (context, plugin) {
return pipe(
prop('commands'),
reject(hasLoadStateError),
reject(isHidden),
map(command => [
command.name,
replace('$BRAND', context.runtime.brand, command.description || '-')
Expand Down
34 changes: 18 additions & 16 deletions packages/gluegun/src/domain/builder.js
Expand Up @@ -53,9 +53,9 @@ class Builder {
// the plugins get loaded last
this.loads.forEach(entry => {
switch (entry.type) {
case 'loadDefault': runtime.loadDefault(entry.value); break
case 'load': runtime.load(entry.value); break
case 'loadAll': runtime.loadAll(entry.value, entry.matching); break
case 'loadDefault': runtime.loadDefault(entry.value, entry.options); break
case 'load': runtime.load(entry.value, entry.options); break
case 'loadAll': runtime.loadAll(entry.value, entry.options); break
}
})

Expand Down Expand Up @@ -87,34 +87,36 @@ class Builder {
/**
* Add a plugin to the list.
*
* @value {string} The plugin directory.
* @return {Builder} self.
* @param {string} value The plugin directory.
* @param {Object} options Additional loading options.
* @return {Builder} self.
*/
load (value) {
this.loads.push({ type: 'load', value })
load (value, options = {}) {
this.loads.push({ type: 'load', value, options })
return this
}

/**
* Add a default plugin to the list.
*
* @value {string} The default plugin directory.
* @return {Builder} self.
* @param {string} value The default plugin directory.
* @param {Object} options Additional loading options.
* @return {Builder} self.
*/
loadDefault (value) {
this.loads.push({ type: 'loadDefault', value })
loadDefault (value, options = {}) {
this.loads.push({ type: 'loadDefault', value, options })
return this
}

/**
* Add a plugin group to the list.
*
* @value {string} The directory with sub-directories.
* @matching {string} An optional jetpack glob matching to match.
* @return {Builder} self.
* @param {string} value The directory with sub-directories.
* @param {Object} options Additional loading options.
* @return {Builder} self.
*/
loadAll (value, matching) {
this.loads.push({ type: 'loadAll', value, matching })
loadAll (value, options = {}) {
this.loads.push({ type: 'loadAll', value, options })
return this
}

Expand Down
1 change: 1 addition & 0 deletions packages/gluegun/src/domain/command.js
Expand Up @@ -31,6 +31,7 @@ class Command {
this.loadState = 'none'
this.errorState = 'none'
this.exception = null
this.hidden = false
}

}
Expand Down
1 change: 1 addition & 0 deletions packages/gluegun/src/domain/plugin.js
Expand Up @@ -31,6 +31,7 @@ class Plugin {
this.defaults = {}
this.directory = null
this.errorMessage = null
this.hidden = false
/**
* A list of commands.
*/
Expand Down
20 changes: 12 additions & 8 deletions packages/gluegun/src/domain/runtime.js
Expand Up @@ -15,6 +15,7 @@ const {
append,
forEach,
isNil,
dissoc,
map,
is
} = require('ramda')
Expand Down Expand Up @@ -199,16 +200,18 @@ class Runtime {
* Loads a plugin from a directory.
*
* @param {string} directory The directory to load from.
* @param {Object} options Additional loading options.
* @return {Plugin} A plugin.
*/
load (directory) {
load (directory, options = {}) {
const { brand, extensionNameToken, commandNameToken, commandDescriptionToken } = this

const plugin = loadPluginFromDirectory(directory, {
extensionNameToken,
commandNameToken,
commandDescriptionToken,
brand
brand,
hidden: options['hidden']
})

this.plugins = append(plugin, this.plugins)
Expand All @@ -223,10 +226,11 @@ class Runtime {
* Loads a plugin from a directory and sets it as the default.
*
* @param {string} directory The directory to load from.
* @param {Object} options Additional loading options.
* @return {Plugin} A plugin.
*/
loadDefault (directory) {
const plugin = this.load(directory)
loadDefault (directory, options = {}) {
const plugin = this.load(directory, options)
this.defaultPlugin = plugin
return plugin
}
Expand All @@ -235,14 +239,14 @@ class Runtime {
* Loads a bunch of plugins from the immediate sub-directories of a directory.
*
* @param {string} directory The directory to grab from.
* @param {string} matching A jetpack matching pattern to filter the list.
* @param {Object} options Addition loading options.
* @return {Plugin[]} A bunch of plugins
*/
loadAll (directory, matching = '*') {
loadAll (directory, options = {}) {
if (isBlank(directory) || !isDirectory(directory)) return []
return pipe(
dir => subdirectories(dir, false, matching),
map(this.load)
dir => subdirectories(dir, false, options['matching']),
map(dir => this.load(dir, dissoc('matching', options)))
)(directory)
}

Expand Down
8 changes: 7 additions & 1 deletion packages/gluegun/src/loaders/toml-plugin-loader.js
Expand Up @@ -4,7 +4,7 @@ const loadCommandFromFile = require('./command-loader')
const loadExtensionFromFile = require('./extension-loader')
const { isNotDirectory } = require('../utils/filesystem-utils')
const { isBlank } = require('../utils/string-utils')
const { map, contains, __ } = require('ramda')
const { assoc, map, contains, __ } = require('ramda')
const toml = require('toml')

/**
Expand All @@ -28,12 +28,15 @@ function loadFromDirectory (directory, options = {}) {
brand = 'gluegun',
commandFilePattern = '*.js',
extensionFilePattern = '*.js',
hidden = false,
commandNameToken,
commandDescriptionToken,
extensionNameToken,
name
} = options

plugin.hidden = Boolean(options.hidden)

if (!isBlank(name)) {
plugin.name = name
}
Expand Down Expand Up @@ -115,6 +118,9 @@ function loadFromDirectory (directory, options = {}) {
plugin.loadState = 'ok'
plugin.errorState = 'none'

// set the hidden bit
plugin.commands = map(assoc('hidden', hidden), plugin.commands)

return plugin
}

Expand Down
2 changes: 1 addition & 1 deletion packages/gluegun/test/domain/builder.test.js
Expand Up @@ -12,7 +12,7 @@ test('the gauntlet', t => {
// plugins
.loadDefault(`${__dirname}/../fixtures/good-plugins/threepack`)
.load(`${__dirname}/../fixtures/good-plugins/simplest`)
.loadAll(`${__dirname}/../fixtures/good-plugins`)
.loadAll(`${__dirname}/../fixtures/good-plugins`, { hidden: true })

// events
.on('start', () => {})
Expand Down
1 change: 1 addition & 0 deletions packages/gluegun/test/domain/command.test.js
Expand Up @@ -8,6 +8,7 @@ test('default state', t => {
t.falsy(command.file)
t.falsy(command.description)
t.falsy(command.run)
t.is(command.hidden, false)
t.is(command.loadState, 'none')
t.is(command.errorState, 'none')
})
1 change: 1 addition & 0 deletions packages/gluegun/test/domain/plugin.test.js
Expand Up @@ -8,6 +8,7 @@ test('default state', t => {
t.is(plugin.errorState, 'none')
t.falsy(plugin.directory)
t.falsy(plugin.name)
t.is(plugin.hidden, false)
t.deepEqual(plugin.commands, [])
t.deepEqual(plugin.extensions, [])
t.deepEqual(plugin.defaults, {})
Expand Down
7 changes: 7 additions & 0 deletions packages/gluegun/test/domain/runtime-load.test.js
Expand Up @@ -8,6 +8,13 @@ test('load a directory', t => {
t.is(r.plugins.length, 2)
})

test('hides commands', t => {
const r = new Runtime()
r.load(`${__dirname}/../fixtures/good-plugins/threepack`, { hidden: true })
t.is(r.plugins.length, 1)
t.true(r.plugins[0].commands[2].hidden)
})

test('allows plugins with broken dirs', t => {
const r = new Runtime()
r.load(__filename)
Expand Down
16 changes: 15 additions & 1 deletion packages/gluegun/test/domain/runtime-loadAll.test.js
Expand Up @@ -4,7 +4,21 @@ const Runtime = require('../../src/domain/runtime')
test('loads all sub-directories', t => {
const r = new Runtime()
r.loadAll(`${__dirname}/../fixtures/good-plugins`)
t.is(r.plugins.length, 10)

t.is(r.plugins.length, 11)
})

test('matches sub-directories', t => {
const r = new Runtime()
r.loadAll(`${__dirname}/../fixtures/good-plugins`, { matching: 'blank-*' })
t.is(r.plugins.length, 1)
})

test('hides commands', t => {
const r = new Runtime()
r.loadAll(`${__dirname}/../fixtures/good-plugins`, { matching: 'threepack', hidden: true })
t.is(r.plugins.length, 1)
t.true(r.plugins[0].commands[2].hidden)
})

test('loadAll ignores bad directories', t => {
Expand Down

0 comments on commit 2ccaab9

Please sign in to comment.