Skip to content
This repository has been archived by the owner on Apr 16, 2022. It is now read-only.

Commit

Permalink
Updated usage prompt for a better CLI experience (#136)
Browse files Browse the repository at this point in the history
* Updated "--help" to account for the supported commands and to be shown by default in cases where the required arguments are not provided.

* Fixed coding style for "index.ts"

* Fixed punctuation and capitalization in error messages.

* Fixed usage text for both commands.

* Update CHANGELOG.md
  • Loading branch information
RazzM13 authored and martysweet committed Apr 23, 2018
1 parent b4df9ad commit b296496
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 103 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Versioning](http://semver.org/spec/v2.0.0.html).
- Merge PR #135, fixing parts.join exception when !Join was called on non-array
- Merge PR #141, allowing lists of values to be specified on the command line

### Changed
- Merge PR #136, updated usage prompt for a better CLI experience

## [1.6.0] - 2018-04-05
### Fixed
- Merge PR #120, fixing dependency issue with "@types/colors"
Expand Down
224 changes: 123 additions & 101 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
*/

import program = require('commander');
import docsBaseImport = require('./docs');
import validatorBaseImport = require('./validator');

require('colors');
const util = require('util');
let version = require('../package').version;
let firstArg: string | undefined = undefined
let secondArg: string = undefined!;

/**
* Used for parsing comma separated commandline argument values whilst, taking into account backslash escapes.
Expand All @@ -28,120 +30,140 @@ function list(val: string) {
});
}

function doNoCommand() {
console.error('\n', 'No command provided!');
process.exit(1);
}

function doNoArgument() {
console.error('\n', 'Missing required argument!');
process.exit(1);
}

program
.version(version)
.arguments('<cmd> <file>')
.action(function() {
program.help();
doNoCommand();
})
.on('--help', function() {
doNoCommand();
});

program
.command('validate')
.usage('<file> [options]')
.option('-p, --parameters <items>', 'List of params', list)
.option('-p, --pseudo <items>', 'List of pseudo overrides', list)
// https://github.com/tj/commander.js/issues/108
// might get fixed by https://github.com/tj/commander.js/issues/691
// as a workaround, we can actually leave this out. It defaults to true and the unparsed parameter will be ignored.
// .option('--guess-parameters', 'Guess any parameters that are not explicitely passed in and have no Default. This is the default behaviour.')
.option('--guess-parameters', 'Guess any parameters that are not explicitely passed in and have no Default. This is the default behaviour.')
.option('-G, --no-guess-parameters', 'Fail validation if a parameter with no Default is not passed')
.option('-g, --only-guess-parameters <items>', 'Guess the provided parameters, and fail validation if a parameter with no Default is passed', list)
.option('-v, --verbose', 'Verbose error messages')
.action(function (arg1, arg2) {
firstArg = arg1;
secondArg = arg2;
});

.action(function(file, cmd) {
// Patch for CommanderJS bug that defaults this to true
if (cmd.parent.rawArgs.indexOf('--guess-parameters') != -1) {
cmd.guessParameters = true;
}

program.parse(process.argv);
const validator = require('./validator') as typeof validatorBaseImport;
if(cmd.parameters) {
for(let param of cmd.parameters) {
// Set the parameter
let kv = param.split('=');
validator.addParameterValue(kv[0], kv[1]);
}
}

if (typeof firstArg === 'undefined') {
console.error('no command given!');
process.exit(1);
}
if(cmd.pseudo) {
for(let pseudo of cmd.pseudo) {
// Set the parameter
let kv = pseudo.split('=');
validator.addPseudoValue(kv[0], kv[1]);
}
}

import validatorBaseImport = require('./validator');
import docsBaseImport = require('./docs');
let guessParameters: string[] | undefined;
if (cmd.guessParameters === false) {
guessParameters = [];
} else if (cmd.onlyGuessParameters) {
guessParameters = cmd.onlyGuessParameters;
} else {
guessParameters = undefined;
}

if(firstArg == "validate"){
const options = {
guessParameters
};

let result = Object();
try {
result = validator.validateFile(file, options);
} catch(err) {
let error: string = function(msg: string, errors: any) {
for (let error of Object.keys(errors)) {
if (RegExp(error).test(msg)) {
return errors[error];
}
}
return errors[''];
}(err.message, {
'Could not find file .*. Check the input path.': 'No such file.',
'': 'Unable to parse template! Use --verbose for more information.'
});
console.log(error);
if (cmd.verbose) {
console.error(err);
}
process.exit(1);
}

const validator = require('./validator') as typeof validatorBaseImport;
// Show the errors
console.log((result['errors']['info'].length + " infos").grey);
for(let info of result['errors']['info']) {
console.log('Resource: '+ info['resource'].grey);
console.log('Message: '+ info['message'].grey);
console.log('Documentation: '+ info['documentation'].grey + '\n');
}

if(program.parameters){
for(let param of program.parameters){
// Set the parameter
let kv = param.split('=');
validator.addParameterValue(kv[0], kv[1]);
console.log((result['errors']['warn'].length + " warn").yellow);
for(let warn of result['errors']['warn']) {
console.log('Resource: ' + warn['resource'].yellow);
console.log('Message: ' + warn['message'].yellow);
console.log('Documentation: ' + warn['documentation'].yellow + '\n');
}
}

if(program.pseudo){
for(let pseudo of program.pseudo){
// Set the parameter
let kv = pseudo.split('=');
validator.addPseudoValue(kv[0], kv[1]);
console.log((result['errors']['crit'].length + " crit").red);
for(let crit of result['errors']['crit']) {
console.log('Resource: ' + crit['resource'].red);
console.log('Message: ' + crit['message'].red);
console.log('Documentation: ' + crit['documentation'].red + '\n');
}
}

let guessParameters: string[] | undefined;
if (program.guessParameters === false) {
guessParameters = [];
} else if (program.onlyGuessParameters) {
guessParameters = program.onlyGuessParameters;
} else {
guessParameters = undefined;
}

const options = {
guessParameters
};

let result = Object();
try {
result = validator.validateFile(secondArg, options);
} catch(err) {
let error: string = function(msg: string, errors: any) {
for (let error of Object.keys(errors)) {
if (RegExp(error).test(msg)) {
return errors[error];
}

if(result['templateValid'] === false) {
console.log('Template invalid!'.red.bold);
process.exit(1);
} else {
console.log('Template valid!'.green);
process.exit(0);
}
return errors[''];
}(err.message, {
'Could not find file .*. Check the input path.': 'No such file.',
'': 'Unable to parse template! Use --verbose for more information.'
});
console.log(error);
if (program.verbose) {
console.error(err);
}
process.exit(1);
}

// Show the errors
console.log((result['errors']['info'].length + " infos").grey);
for(let info of result['errors']['info']){
console.log('Resource: '+ info['resource'].grey);
console.log('Message: '+ info['message'].grey);
console.log('Documentation: '+ info['documentation'].grey + '\n');
}

console.log((result['errors']['warn'].length + " warn").yellow);
for(let warn of result['errors']['warn']){
console.log('Resource: ' + warn['resource'].yellow);
console.log('Message: ' + warn['message'].yellow);
console.log('Documentation: ' + warn['documentation'].yellow + '\n');
}

console.log((result['errors']['crit'].length + " crit").red);
for(let crit of result['errors']['crit']){
console.log('Resource: ' + crit['resource'].red);
console.log('Message: ' + crit['message'].red);
console.log('Documentation: ' + crit['documentation'].red + '\n');
}

if(result['templateValid'] === false){
console.log('Template invalid!'.red.bold);
process.exit(1)
}else{
console.log('Template valid!'.green);
process.exit(0)
}

}else if(firstArg == "docs"){
const docs = require('./docs') as typeof docsBaseImport;
console.log(docs.getDoc(secondArg))
})
.on('--help', function() {
doNoArgument();
});

program
.command('docs')
.usage('<reference> [options]')
.action(function(reference) {
const docs = require('./docs') as typeof docsBaseImport;
console.log(docs.getDoc(reference));
})
.on('--help', function() {
doNoArgument();
});

if (process.argv.length < 4) {
process.argv.push('--help');
}

program.parse(process.argv);
4 changes: 2 additions & 2 deletions src/test/indexTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ describe('index', () => {

it('no parameters', (done) => {
exec('node lib/index.js', function(error, stdout, stderr) {
expect(stderr).to.contain('no command given!');
expect(stderr).to.contain('No command provided!');
done();
});
}).timeout(5000);;

it('missing file parameter', (done) => {
exec('node lib/index.js validate', function(error, stdout, stderr) {
expect(stderr).to.contain('missing required argument');
expect(stderr).to.contain('Missing required argument!');
done();
});
}).timeout(5000);;
Expand Down

0 comments on commit b296496

Please sign in to comment.