1
0
Fork 0

feat: add cli help (fixes #7)

This commit is contained in:
ssube 2019-06-17 08:04:58 -05:00
parent e6c2da540e
commit 721f85f606
4 changed files with 124 additions and 68 deletions

View File

@ -50,7 +50,9 @@ export default {
'Schema', 'Schema',
'Type', 'Type',
], ],
'node_modules/yargs-parser/index.js': ['detailed'], 'node_modules/yargs/index.js': [
'usage',
]
}, },
}), }),
typescript({ typescript({

View File

@ -17,14 +17,13 @@
"bunyan": "^1.8.12", "bunyan": "^1.8.12",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"noicejs": "^2.5.2", "noicejs": "^2.5.2"
"yargs-parser": "^13.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/bunyan": "^1.8.6", "@types/bunyan": "^1.8.6",
"@types/js-yaml": "^3.12.1", "@types/js-yaml": "^3.12.1",
"@types/lodash": "^4.14.134", "@types/lodash": "^4.14.134",
"@types/yargs-parser": "^13.0.0", "@types/yargs": "^13.0.0",
"jsonpath-plus": "^0.20.1", "jsonpath-plus": "^0.20.1",
"rollup": "^1.15.5", "rollup": "^1.15.5",
"rollup-plugin-commonjs": "^10.0.0", "rollup-plugin-commonjs": "^10.0.0",
@ -33,6 +32,7 @@
"rollup-plugin-replace": "^2.2.0", "rollup-plugin-replace": "^2.2.0",
"rollup-plugin-typescript2": "^0.21.1", "rollup-plugin-typescript2": "^0.21.1",
"standard-version": "^6.0.1", "standard-version": "^6.0.1",
"typescript": "^3.5.2" "typescript": "^3.5.2",
"yargs": "^13.2.4"
} }
} }

View File

@ -1,5 +1,5 @@
import { createLogger } from 'bunyan'; import { createLogger } from 'bunyan';
import { detailed, Options } from 'yargs-parser'; import { Options, usage } from 'yargs';
import { loadConfig } from 'src/config'; import { loadConfig } from 'src/config';
import { YamlParser } from 'src/parser/YamlParser'; import { YamlParser } from 'src/parser/YamlParser';
@ -11,63 +11,75 @@ import { VisitorContext } from 'src/visitor/context';
const CONFIG_ARGS_NAME = 'config-name'; const CONFIG_ARGS_NAME = 'config-name';
const CONFIG_ARGS_PATH = 'config-path'; const CONFIG_ARGS_PATH = 'config-path';
const MAIN_ARGS: Options = { const RULE_OPTION: Options = {
alias: { default: [],
'count': ['c'], type: 'array',
'dest': ['d'],
'format': ['f'],
'includeTag': ['t', 'tag'],
'mode': ['m'],
'source': ['s'],
},
array: [
CONFIG_ARGS_PATH,
'excludeLevel',
'excludeName',
'excludeTag',
'includeLevel',
'includeName',
'includeTag',
'rules',
],
boolean: [
'coerce',
'count',
],
count: ['v'],
default: {
[CONFIG_ARGS_NAME]: `.${VERSION_INFO.app.name}.yml`,
[CONFIG_ARGS_PATH]: [],
'coerce': false,
'count': false,
'dest': '-',
'excludeLevel': [],
'excludeName': [],
'excludeTag': [],
'format': 'yaml',
'includeLevel': [],
'includeName': [],
'includeTag': [],
'mode': 'check',
'rules': [],
'source': '-',
},
envPrefix: VERSION_INFO.app.name,
string: [
'mode',
],
}; };
const MAIN_ARGS = usage(`Usage: $0 <mode> [options]`)
.option(CONFIG_ARGS_NAME, {
default: `.${VERSION_INFO.app.name}.yml`,
type: 'string',
})
.option(CONFIG_ARGS_PATH, {
default: [],
type: 'array',
})
.option('coerce', {
default: false,
type: 'boolean',
})
.option('count', {
alias: ['c'],
default: false,
type: 'boolean',
})
.option('dest', {
alias: ['d'],
default: '-',
type: 'string',
})
.option('format', {
alias: ['f'],
default: 'yaml',
type: 'string',
})
.option('mode', {
alias: ['m'],
default: 'check',
type: 'string',
})
.option('rules', {
alias: ['r'],
default: [],
type: 'array',
})
.option('source', {
alias: ['s'],
default: '-',
type: 'string',
})
.option('excludeLevel', RULE_OPTION)
.option('excludeName', RULE_OPTION)
.option('excludeTag', RULE_OPTION)
.option('includeLevel', RULE_OPTION)
.option('includeName', RULE_OPTION)
.option('includeTag', {
...RULE_OPTION,
alias: ['t', 'tag'],
})
.help();
const STATUS_SUCCESS = 0; const STATUS_SUCCESS = 0;
const STATUS_ERROR = 1; const STATUS_ERROR = 1;
export async function main(argv: Array<string>): Promise<number> { export async function main(argv: Array<string>): Promise<number> {
const args = detailed(argv, MAIN_ARGS); const args = MAIN_ARGS.argv;
const config = await loadConfig(args.argv[CONFIG_ARGS_NAME], ...args.argv[CONFIG_ARGS_PATH]); const config = await loadConfig(args[CONFIG_ARGS_NAME], ...args[CONFIG_ARGS_PATH]);
const logger = createLogger(config.data.logger); const logger = createLogger(config.data.logger);
logger.info(VERSION_INFO, 'version info'); logger.info(VERSION_INFO, 'version info');
logger.info({ args: args.argv }, 'main arguments'); logger.info({ args }, 'main arguments');
// const schema = new Schema(); // const schema = new Schema();
const result = { errors: [], valid: true }; // schema.match(config); const result = { errors: [], valid: true }; // schema.match(config);
@ -76,20 +88,20 @@ export async function main(argv: Array<string>): Promise<number> {
return STATUS_ERROR; return STATUS_ERROR;
} }
const rules = await loadRules(args.argv.rules); const rules = await loadRules(args.rules);
const source = await loadSource(args.argv.source); const source = await loadSource(args.source);
const parser = new YamlParser(); const parser = new YamlParser();
const data = parser.parse(source); const data = parser.parse(source);
const activeRules = await resolveRules(rules, args.argv as any); const activeRules = await resolveRules(rules, args as any);
const ctx = new VisitorContext({ const ctx = new VisitorContext({
coerce: args.argv.coerce, coerce: args.coerce,
defaults: args.argv.mode === 'fix', defaults: args.mode === 'fix',
logger, logger,
}); });
switch (args.argv.mode) { switch (args.mode) {
case 'check': case 'check':
case 'fix': case 'fix':
for (const rule of activeRules) { for (const rule of activeRules) {
@ -101,12 +113,12 @@ export async function main(argv: Array<string>): Promise<number> {
} }
break; break;
default: default:
ctx.error({ mode: args.argv.mode }, 'unsupported mode'); ctx.error({ mode: args.mode }, 'unsupported mode');
} }
if (ctx.errors.length > 0) { if (ctx.errors.length > 0) {
logger.error({ errors: ctx.errors }, 'some rules failed'); logger.error({ errors: ctx.errors }, 'some rules failed');
if (args.argv.count) { if (args.count) {
return Math.min(ctx.errors.length, 255); return Math.min(ctx.errors.length, 255);
} else { } else {
return STATUS_ERROR; return STATUS_ERROR;
@ -114,7 +126,7 @@ export async function main(argv: Array<string>): Promise<number> {
} else { } else {
logger.info('all rules passed'); logger.info('all rules passed');
const output = parser.dump(data); const output = parser.dump(data);
await writeSource(args.argv.dest, output); await writeSource(args.dest, output);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }

View File

@ -36,11 +36,18 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/yargs-parser@^13.0.0": "@types/yargs-parser@*":
version "13.0.0" version "13.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0"
integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw==
"@types/yargs@^13.0.0":
version "13.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.0.tgz#d2acb3bec0047d8f648ebacdab6b928a900c42c4"
integrity sha512-hY0o+kcz9M6kH32NUeb6VURghqMuCVkiUx+8Btsqhj4Hhov/hVGUx9DmBJeIkzlp1uAQK4wngQBCjqWdUUkFyA==
dependencies:
"@types/yargs-parser" "*"
JSONStream@^1.0.4: JSONStream@^1.0.4:
version "1.3.5" version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@ -79,7 +86,7 @@ ansi-regex@^4.1.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
ansi-styles@^3.2.1: ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1" version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
@ -275,6 +282,15 @@ cliui@^4.0.0:
strip-ansi "^4.0.0" strip-ansi "^4.0.0"
wrap-ansi "^2.0.0" wrap-ansi "^2.0.0"
cliui@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
dependencies:
string-width "^3.1.0"
strip-ansi "^5.2.0"
wrap-ansi "^5.1.0"
code-point-at@^1.0.0: code-point-at@^1.0.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
@ -2171,7 +2187,7 @@ string-width@^2.1.1:
is-fullwidth-code-point "^2.0.0" is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0" strip-ansi "^4.0.0"
string-width@^3.0.0: string-width@^3.0.0, string-width@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
@ -2213,7 +2229,7 @@ strip-ansi@^4.0.0:
dependencies: dependencies:
ansi-regex "^3.0.0" ansi-regex "^3.0.0"
strip-ansi@^5.1.0: strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
@ -2422,6 +2438,15 @@ wrap-ansi@^2.0.0:
string-width "^1.0.1" string-width "^1.0.1"
strip-ansi "^3.0.1" strip-ansi "^3.0.1"
wrap-ansi@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
dependencies:
ansi-styles "^3.2.0"
string-width "^3.0.0"
strip-ansi "^5.0.0"
wrappy@1: wrappy@1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@ -2437,7 +2462,7 @@ y18n@^4.0.0:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yargs-parser@^13.0.0, yargs-parser@^13.1.1: yargs-parser@^13.0.0, yargs-parser@^13.1.0:
version "13.1.1" version "13.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
@ -2461,3 +2486,20 @@ yargs@13.2.2:
which-module "^2.0.0" which-module "^2.0.0"
y18n "^4.0.0" y18n "^4.0.0"
yargs-parser "^13.0.0" yargs-parser "^13.0.0"
yargs@^13.2.4:
version "13.2.4"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"
integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
dependencies:
cliui "^5.0.0"
find-up "^3.0.0"
get-caller-file "^2.0.1"
os-locale "^3.1.0"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^3.0.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.1.0"