mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 05:37:51 +00:00
Implement Yargs Command plugin
This commit is contained in:
parent
f1a76db5f5
commit
7610fe87cc
48
lib/yargs-command/yargs-command.coffee
Normal file
48
lib/yargs-command/yargs-command.coffee
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
yargs = require('yargs')
|
||||||
|
_ = require('lodash')
|
||||||
|
|
||||||
|
commandIndexBySignature = (command) ->
|
||||||
|
query = { signature: command.signature }
|
||||||
|
return _.findIndex(@command._commands, query)
|
||||||
|
|
||||||
|
isArgVariable = (word) ->
|
||||||
|
return /^(<.*>|\[.*\])$/.test(word)
|
||||||
|
|
||||||
|
splitSignature = (signature) ->
|
||||||
|
return signature.split(' ')
|
||||||
|
|
||||||
|
commandApplies = (command, args) ->
|
||||||
|
args._ ?= {}
|
||||||
|
splittedCommandSignature = splitSignature(command.signature)
|
||||||
|
if splittedCommandSignature.length isnt args._.length
|
||||||
|
return false
|
||||||
|
|
||||||
|
for word in splittedCommandSignature
|
||||||
|
index = splittedCommandSignature.indexOf(word)
|
||||||
|
|
||||||
|
if not isArgVariable(word) and word isnt args._[index]
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
run = ->
|
||||||
|
signature = splitSignature(@command._matchedCommand.signature)
|
||||||
|
parameters = _.difference(@argv._, signature)
|
||||||
|
@command._matchedCommand.action.apply(this, parameters)
|
||||||
|
|
||||||
|
module.exports = (signature, action) ->
|
||||||
|
command = { signature, action }
|
||||||
|
|
||||||
|
@command._commands ?= []
|
||||||
|
@command.run ?= _.bind(run, this)
|
||||||
|
|
||||||
|
commandIndex = commandIndexBySignature.call(this, command)
|
||||||
|
if commandIndex is -1
|
||||||
|
@command._commands.push(command)
|
||||||
|
else
|
||||||
|
@command._commands.splice(commandIndex, 1, command)
|
||||||
|
|
||||||
|
if commandApplies(command, @argv)
|
||||||
|
@command._matchedCommand = command
|
||||||
|
|
||||||
|
return this
|
110
lib/yargs-command/yargs-command.spec.coffee
Normal file
110
lib/yargs-command/yargs-command.spec.coffee
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
chai = require('chai')
|
||||||
|
sinon = require('sinon')
|
||||||
|
chai.use(require('chai-things'))
|
||||||
|
chai.use(require('sinon-chai'))
|
||||||
|
expect = chai.expect
|
||||||
|
|
||||||
|
_ = require('lodash')
|
||||||
|
yargs = require('yargs')
|
||||||
|
yargs.command = require('./yargs-command')
|
||||||
|
|
||||||
|
COMMANDS =
|
||||||
|
appList:
|
||||||
|
signature: 'app list <id>'
|
||||||
|
action: (id) -> "App List: #{id}"
|
||||||
|
action2: (id) -> "App List: #{id}!"
|
||||||
|
deviceList:
|
||||||
|
signature: 'device list <id>'
|
||||||
|
action: (id) -> "Device: #{id}"
|
||||||
|
|
||||||
|
ARGS =
|
||||||
|
appList:
|
||||||
|
_: [ 'app', 'list', '7' ]
|
||||||
|
deviceList:
|
||||||
|
_: [ 'device', 'list', '7' ]
|
||||||
|
noMatch:
|
||||||
|
_: [ 'foo', 'bar', 'baz' ]
|
||||||
|
|
||||||
|
# Hacky way to check that both functions are equal based
|
||||||
|
# on what they returns, as mocha crashes when trying equal
|
||||||
|
# or deep equal directly on the functions for some reason
|
||||||
|
areFunctionsEqual = (fn1, fn2) ->
|
||||||
|
return fn1.toString() is fn2.toString()
|
||||||
|
|
||||||
|
describe 'Yargs Command:', ->
|
||||||
|
|
||||||
|
cleanUpYargs = ->
|
||||||
|
yargs.command._commands = [] if yargs.command._commands
|
||||||
|
yargs.argv = {}
|
||||||
|
delete yargs.command._matchedCommand
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
cleanUpYargs()
|
||||||
|
|
||||||
|
afterEach ->
|
||||||
|
cleanUpYargs()
|
||||||
|
|
||||||
|
it 'should expose a public command function', ->
|
||||||
|
expect(yargs.command).to.be.an.instanceof(Function)
|
||||||
|
|
||||||
|
it 'should return yargs to enable chaining', ->
|
||||||
|
result = yargs.command(COMMANDS.appList.signature, COMMANDS.appList.action)
|
||||||
|
expect(result).to.equal(yargs)
|
||||||
|
|
||||||
|
it 'should contain an empty _commands array', ->
|
||||||
|
expect(yargs.command._commands).to.deep.equal([])
|
||||||
|
|
||||||
|
it 'should push a command to _commands', ->
|
||||||
|
yargs.command(COMMANDS.appList.signature, COMMANDS.appList.action)
|
||||||
|
expect(yargs.command._commands).to.contain.something.that.deep.equals
|
||||||
|
signature: COMMANDS.appList.signature
|
||||||
|
action: COMMANDS.appList.action
|
||||||
|
|
||||||
|
describe 'if adding the same command signature twice', ->
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
yargs.command(COMMANDS.appList.signature, COMMANDS.appList.action)
|
||||||
|
yargs.command(COMMANDS.appList.signature, COMMANDS.appList.action2)
|
||||||
|
|
||||||
|
it 'should contain only one command', ->
|
||||||
|
expect(yargs.command._commands).to.have.length(1)
|
||||||
|
|
||||||
|
it 'should make the last action override the first one', ->
|
||||||
|
firstCommandAction = yargs.command._commands[0].action
|
||||||
|
expect(areFunctionsEqual(firstCommandAction, COMMANDS.appList.action2)).to.be.true
|
||||||
|
|
||||||
|
describe 'given various registered commands', ->
|
||||||
|
|
||||||
|
registerCommands = ->
|
||||||
|
yargs.command(COMMANDS.appList.signature, COMMANDS.appList.action)
|
||||||
|
yargs.command(COMMANDS.deviceList.signature, COMMANDS.deviceList.action)
|
||||||
|
|
||||||
|
testCommand = (name) ->
|
||||||
|
yargs.argv = ARGS[name]
|
||||||
|
registerCommands()
|
||||||
|
matchedCommand = yargs.command._matchedCommand
|
||||||
|
expect(matchedCommand.signature).to.equal(COMMANDS[name].signature)
|
||||||
|
|
||||||
|
it 'should choose the right command', ->
|
||||||
|
for command in [
|
||||||
|
'appList'
|
||||||
|
'deviceList'
|
||||||
|
]
|
||||||
|
testCommand(command)
|
||||||
|
|
||||||
|
it 'should be undefined if no match', ->
|
||||||
|
yargs.argv = ARGS.noMatch
|
||||||
|
registerCommands()
|
||||||
|
expect(yargs.command._matchedCommand).to.not.exist
|
||||||
|
|
||||||
|
it 'should have a run public function', ->
|
||||||
|
expect(yargs.command.run).to.be.an.instanceof(Function)
|
||||||
|
|
||||||
|
describe '#run()', ->
|
||||||
|
|
||||||
|
it 'should call the action with the correct parameters', ->
|
||||||
|
yargs.argv = ARGS.appList
|
||||||
|
callback = sinon.spy()
|
||||||
|
yargs.command(COMMANDS.appList.signature, callback)
|
||||||
|
yargs.command.run()
|
||||||
|
expect(callback).to.have.been.calledWith(_.last(ARGS.appList._))
|
@ -23,7 +23,10 @@
|
|||||||
"gulp-coffeelint": "~0.4.0",
|
"gulp-coffeelint": "~0.4.0",
|
||||||
"nock": "~0.48.2",
|
"nock": "~0.48.2",
|
||||||
"mock-fs": "~2.3.2",
|
"mock-fs": "~2.3.2",
|
||||||
"chai-as-promised": "~4.1.1"
|
"chai-as-promised": "~4.1.1",
|
||||||
|
"chai-things": "~0.2.0",
|
||||||
|
"sinon": "~1.12.1",
|
||||||
|
"sinon-chai": "~2.6.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"request": "~2.47.0",
|
"request": "~2.47.0",
|
||||||
@ -37,6 +40,7 @@
|
|||||||
"open": "0.0.5",
|
"open": "0.0.5",
|
||||||
"inquirer": "~0.8.0",
|
"inquirer": "~0.8.0",
|
||||||
"cliff": "~0.1.9",
|
"cliff": "~0.1.9",
|
||||||
"underscore.string": "~2.4.0"
|
"underscore.string": "~2.4.0",
|
||||||
|
"yargs": "~1.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user