start smarter CLI logic

This commit is contained in:
Philipp Kunz 2015-11-05 21:43:34 +01:00
parent d6cbefce2c
commit 5611ad03aa
8 changed files with 188 additions and 74 deletions

View File

@ -10,6 +10,20 @@ nodejs wrapper for CLI related tasks
npm install smartcli npm install smartcli
### Usage ### Usage
this plugin tries to establish some logic in which CLI tools work.
take the following commandline input:
```
mytool function argument1 argument2 --option1 option1Value --option2 option2Value
```
* 'mytool' obviously is the tool (like git)
* function is the main thing the tool shall do (like commit)
* option is an option you can add (like -m for message)
* optionValue is the referenced option value (like a commit message)
```js ```js
var smartcli = require("smartcli"); var smartcli = require("smartcli");

View File

@ -26,10 +26,11 @@
}, },
"homepage": "https://github.com/pushrocks/smartcli", "homepage": "https://github.com/pushrocks/smartcli",
"dependencies": { "dependencies": {
"beautylog": "0.0.15", "beautylog": "1.0.2",
"cliff": "^0.1.10", "cliff": "^0.1.10",
"inquirer": "^0.10.1", "inquirer": "^0.11.0",
"yargs": "^3.26.0" "smartparam": "0.0.5",
"yargs": "^3.29.0"
}, },
"devDependencies": { "devDependencies": {
"gulp": "3.9.0", "gulp": "3.9.0",

View File

@ -1,76 +1,29 @@
/// <reference path="typings/tsd.d.ts" /> /// <reference path="typings/tsd.d.ts" />
/// <reference path="./interfaces.ts" /> /// <reference path="./smartcli.plugins.ts" />
/// <reference path="./smartcli.interfaces.ts" />
/// <reference path="./smartcli.checks.ts" />
/// <reference path="./smartcli.getters.ts" />
var path = require("path"); var plugins = smartcliPlugins.init(); //get all the required npm modules under plugins
var beautylog = require("beautylog");
var cliff = require("cliff");
var inquirer = require("inquirer");
var argv = require('yargs').argv;
//define the smartcli object //define the smartcli object
var smartcli:any = {}; var smartcli:any = {};
//add plugins from above for direct use //add plugins from above for direct use
smartcli.inquirer = inquirer; smartcli.inquirer = plugins.inquirer; //inquirer is for asking questions
smartcli.cliff = cliff; smartcli.cliff = plugins.cliff; // formats cli output
smartcli.argv = argv; smartcli.argv = plugins.argv; //argv gets initial cli commands and options.
/* ------------------------------------------------------------------------------ //init checks. Checks return boolean. That means they can be used as question with an answer of yes or no.
*----------------------- initial call CLI args -----------------------------
*----------------------------------------------------------------------------- */
// commands smartcliChecks.init(); // is defined in smartcli.checks.ts
smartcli.checkCommand = function(commandString:string):boolean {
if (argv._.indexOf(commandString) != -1) {
return true
}
return false;
};
smartcli.getCommands = function ():string[] {
return argv._;
};
// options
smartcli.getOption = function(optionName:string):CliOption {
if (argv.hasOwnProperty(optionName)) {
return {
name:optionName,
specified: true,
value: argv[optionName] //we already know from the "if" above that the value is available.
};
}
return {
name:optionName,
specified: false,
value: false
}
};
smartcli.getOptions = function() {
var options = {};
for (var key in argv) {
if (key != "_") {
options['key'] = argv['key'];
}
}
return options;
};
/**
* returns Directory of cwd
* @returns {{path: string}}
*/
smartcli.getCwd = function():Directory {
return {
path: process.cwd()
}
};
@ -88,7 +41,7 @@ smartcli.getCwd = function():Directory {
*/ */
smartcli.getAnswer = function(questionString:string, cb) { smartcli.getAnswer = function(questionString:string, cb) {
if (typeof questionString != 'string') { if (typeof questionString != 'string') {
beautylog.error('no question specified'); plugins.beautylog.error('no question specified');
return null; return null;
} }
//make inquirer compatible question object //make inquirer compatible question object
@ -101,7 +54,7 @@ smartcli.getAnswer = function(questionString:string, cb) {
} }
}; };
inquirer.prompt([question],function(answers){ plugins.inquirer.prompt([question],function(answers){
var answer = answers.userFeedback; var answer = answers.userFeedback;
cb(answer); cb(answer);
}); });
@ -128,7 +81,7 @@ smartcli.getChoice = function(questionString:string, choiceOptions:string[], cb)
filter: function( val ) { return val.toLowerCase(); } filter: function( val ) { return val.toLowerCase(); }
}; };
inquirer.prompt(question,function(answers){ plugins.inquirer.prompt(question,function(answers){
var answer = answers.userFeedback; var answer = answers.userFeedback;
cb(answer); cb(answer);
}); });

View File

@ -1,11 +0,0 @@
/// <reference path="index.ts" />
interface CliOption {
name: string;
specified:boolean;
value: any;
}
interface Directory {
path: string;
}

52
ts/smartcli.checks.ts Normal file
View File

@ -0,0 +1,52 @@
/// <reference path="./index.ts" />
module smartcliChecks {
export function init() {
/**
* checks for a special command string and returns true if found.
* @param commandString
* @returns {boolean}
*/
smartcli.checkCommand = function(commandString:string):boolean {
if (plugins.argv._.indexOf(commandString) == 0) {
return true
}
return false;
};
smartcli.checkCommandArgument = function(level:number):boolean {
if(plugins.argv._.length == (level + 1)) {
return true;
}
return false;
};
/**
* checks if a command is present, returns true if yes, false if no.
* @returns {boolean}
*/
smartcli.checkCommandPresence = function():boolean {
if(plugins.argv._.length < 0){
return true;
}
return false;
}
/**
* checks for a specific option string, returns true if yes, returns false if no
* @returns {boolean}
*/
smartcli.checkOption = function(optionString):boolean {
if(plugins.smartparam.exists(plugins.argv, optionString)) {
return true;
}
return false;
};
smartcli.checkOptionsPresence = function():boolean {
if (plugins.argv.indexOf() != -1) {
return true
}
return false;
};
}
}

67
ts/smartcli.getters.ts Normal file
View File

@ -0,0 +1,67 @@
/// <reference path="./index.ts" />
module smartcliGetters {
export function init() {
smartcli.getCommand = function(commandString):CliCommand {
var cliCommand = {
specified: smartcli.checkCommand(commandString),
name: commandString,
arguments: smartcli.getCommandArgument(1)
}
return cliCommand;
};
smartcli.getCommandArgument = function(argumentLevel):CommandArgument {
var commandArgument = {
specified
};
return commandArgument;
};
/**
* returns complete command object
* @returns {any}
*/
smartcli.getCommands = function ():string[] {
return plugins.argv._;
};
// options
smartcli.getOption = function(optionName:string):CliOption {
if (plugins.argv.hasOwnProperty(optionName)) {
return {
name:optionName,
specified: true,
value: plugins.argv[optionName] //we already know from the "if" above that the value is available.
};
}
return {
name:optionName,
specified: false,
value: false
}
};
smartcli.getOptions = function() {
var options = {};
for (var key in plugins.argv) {
if (key != "_") {
options['key'] = plugins.argv['key'];
}
}
return options;
};
/**
* returns Directory of cwd
* @returns {{path: string}}
*/
smartcli.getCwd = function():Directory {
return {
path: process.cwd()
}
};
}
}

24
ts/smartcli.interfaces.ts Normal file
View File

@ -0,0 +1,24 @@
/// <reference path="index.ts" />
interface CliOption {
name: string;
specified:boolean;
value: any;
}
interface Directory {
path: string;
}
interface CliCommand {
specified: boolean;
name: string;
second: string;
third: string;
fourth: string;
}
interface CliCommandArgument {
specified:boolean;
name:string;
}

14
ts/smartcli.plugins.ts Normal file
View File

@ -0,0 +1,14 @@
/// <reference path="./index.ts" />
module smartcliPlugins {
var plugins:any = {};
export function init() {
plugins.path = require("path");
plugins.beautylog = require("beautylog")("os");
plugins.cliff = require("cliff");
plugins.inquirer = require("inquirer");
plugins.smartparam = require("smartparam");
plugins.argv = require('yargs').argv;
return plugins;
}
}