blob: e2229bdc949eafdbed0148bf1d4163379bbf08b1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var argv = require('argv'),
prompt = require('inquirer'),
lister = require('./commands/list'),
options = require('./options'),
rewriter = require('./rewriter'),
columnify = require('columnify');
var commandHandlers; // defined below. helping out jshint here
var help = {
handler: function help() {
console.log('The available commands are:');
console.log();
var grouped = {};
for (var x in commandHandlers) {
if (commandHandlers.hasOwnProperty(x)) {
var already = grouped[commandHandlers[x].description];
if (already) {
grouped[commandHandlers[x].description] = already + ', ' + x;
} else {
grouped[commandHandlers[x].description] = x;
}
}
}
var pruned = [];
for (var d in grouped) {
if (grouped.hasOwnProperty(d)) {
pruned.push({ command: grouped[d], description: d });
}
}
console.log(columnify(pruned, { minWidth: 18 }));
},
description: 'Print this help text'
};
var attach = {
handler: rewriter.attach,
enumerate: lister.list,
description: 'Attach to an action',
synchronous: true,
options: [{ name: 'all', short: 'a', type: 'string', description: 'Instrument the action, plus any rules or sequences in which it takes part' }]
};
var detach = {
handler: rewriter.detach,
description: 'Detatch from an action',
synchronous: true
};
var exit = {
handler: function(wskprops) {
console.log('Cleaning up');
rewriter.clean(wskprops, process.exit); // note: clean versus detachAll
},
description: 'Quit the debugger',
synchronous: true
};
var invoke = {
handler: rewriter.invoke,
description: 'Invoke an action',
needsEventBus: true,
synchronous: true
};
var fire = {
handler: require('./commands/fire').fire,
description: 'Fire a trigger',
synchronous: true
};
var list = {
handler: lister.listToConsole,
description: 'List available actions',
synchronous: true,
options: [{ name: 'full', short: 'f', type: 'string', description: 'Show all actions, including debugging artifacts' }]
};
var inspect = {
handler: require('./commands/inspect').inspect,
description: 'Inspect the details of an OpenWhisk action',
synchronous: true
};
var clean = {
handler: rewriter.clean,
description: 'Clean up debugging artifacts',
synchronous: true
};
var create = {
handler: require('./commands/create').create,
description: 'Create an action',
synchronous: true
};
var createTrigger = {
handler: require('./commands/create-trigger').create,
description: 'Create a trigger',
synchronous: true
};
var createRule = {
handler: require('./commands/create-rule').create,
description: 'Create a rule',
synchronous: true
};
var deleteAction = {
handler: require('./commands/delete').deleteAction,
description: 'Delete an action',
synchronous: true
};
var deleteTrigger = {
handler: require('./commands/delete-trigger').delete,
description: 'Delete a trigger',
synchronous: true
};
var deleteRule = {
handler: require('./commands/delete-rule').delete,
description: 'Delete a rule',
synchronous: true
};
var diff = {
handler: require('./commands/diff').diff,
description: 'Show the pending diffs of a given action',
synchronous: true
};
var publish = {
handler: require('./commands/publish').publish,
description: 'Publish pending changes to a given action',
synchronous: true
};
var cli = {
handler: options.update.bind(undefined, 'use-cli-debugger', undefined),
description: 'Use the CLI debugger, when available',
synchronous: true
};
commandHandlers = {
list: list,
l: list,
cli: cli,
invoke: invoke,
i: invoke,
inspect: inspect,
ins: inspect,
get: inspect,
fire: fire,
f: fire,
attach: attach,
a: attach,
detach: detach,
d: detach,
diff: diff,
publish: publish,
p: publish,
exit: exit,
quit: exit,
e: exit,
q: exit,
clean: clean,
c: clean,
create: create,
'create-trigger': createTrigger,
'create-rule': createRule,
delete: deleteAction,
'delete-trigger': deleteTrigger,
'delete-rule': deleteRule,
help: help,
h: help,
'?': help
};
/**
* This is the read-eval-print loop.
*
* @param wskprops is a map that provides the user's NAMESPACE and AUTH settings
* @param eventBus will be used to post and listen for inter-function communication
* @param attachTo if the user requested to attach to an action on launch
*
*/
function repl(wskprops, eventBus, attachTo) {
function handleReplCommand(response) {
if (response.command.length === 0) {
// user hit return;
return repl(wskprops, eventBus);
}
var commandLine = response.command.split(/\s+/);
var command = commandLine.shift();
var handler = commandHandlers[command];
var options;
if (handler.options) {
argv.clear();
argv.description = 'Usage: ' + command + ' [options]';
argv.options.help.example = '';
argv.options.help.onset = (args) => {
argv.help(args.mod);
};
options = argv.option(handler.options).run(commandLine).options;
}
if (handler.synchronous) {
// the second parameter is the call back to the repl
// when done with the synchronous operation
commandLine.unshift(repl.bind(undefined, wskprops, eventBus));
}
if (handler.options) {
commandLine.unshift(options);
}
if (handler.needsEventBus) {
commandLine.unshift(eventBus);
}
// the first parameter is wskprops
commandLine.unshift(wskprops);
commandLine.push(response.command);
// call to the handler!
try {
handler.handler.apply(undefined, commandLine);
} catch (e) {
console.error(e);
}
if (!handler.synchronous) {
// if async, then restart the repl right away
repl(wskprops, eventBus);
}
} /* end of handleReplCommand */
if (attachTo) {
handleReplCommand({ command: 'attach ' + attachTo });
} else {
prompt.prompt([{
name: 'command', message: '(wskdb)',
prefixMessage: '', // override the default question mark prefix
validate: function(line) {
var commandLine = line.split(/\s+/);
return line.length === 0 || commandHandlers[commandLine[0]] ? true : 'Invalid command';
}
}]).then(handleReplCommand);
}
}
exports.repl = repl;