1 // validation-type-stuff, missing params,
2 // bad implications, custom checks.
3 module.exports = function (yargs, usage, y18n) {
8 // validate appropriate # of non-option
9 // arguments were provided, i.e., '_'.
10 self.nonOptionCount = function (argv) {
11 var demanded = yargs.getDemanded()
12 var _s = argv._.length
14 if (demanded._ && (_s < demanded._.count || _s > demanded._.max)) {
15 if (demanded._.msg !== undefined) {
16 usage.fail(demanded._.msg)
17 } else if (_s < demanded._.count) {
19 __('Not enough non-option arguments: got %s, need at least %s', argv._.length, demanded._.count)
23 __('Too many non-option arguments: got %s, maximum of %s', argv._.length, demanded._.max)
29 // make sure that any args that require an
30 // value (--foo=bar), have a value.
31 self.missingArgumentValue = function (argv) {
32 var defaultValues = [true, false, '']
33 var options = yargs.getOptions()
35 if (options.requiresArg.length > 0) {
36 var missingRequiredArgs = []
38 options.requiresArg.forEach(function (key) {
41 // if a value is explicitly requested,
42 // flag argument as missing if it does not
43 // look like foo=bar was entered.
44 if (~defaultValues.indexOf(value) ||
45 (Array.isArray(value) && !value.length)) {
46 missingRequiredArgs.push(key)
50 if (missingRequiredArgs.length > 0) {
52 'Missing argument value: %s',
53 'Missing argument values: %s',
54 missingRequiredArgs.length,
55 missingRequiredArgs.join(', ')
61 // make sure all the required arguments are present.
62 self.requiredArguments = function (argv) {
63 var demanded = yargs.getDemanded()
66 Object.keys(demanded).forEach(function (key) {
67 if (!argv.hasOwnProperty(key)) {
68 missing = missing || {}
69 missing[key] = demanded[key]
75 Object.keys(missing).forEach(function (key) {
76 var msg = missing[key].msg
77 if (msg && customMsgs.indexOf(msg) < 0) {
82 var customMsg = customMsgs.length ? '\n' + customMsgs.join('\n') : ''
85 'Missing required argument: %s',
86 'Missing required arguments: %s',
87 Object.keys(missing).length,
88 Object.keys(missing).join(', ') + customMsg
93 // check for unknown arguments (strict-mode).
94 self.unknownArguments = function (argv, aliases) {
96 var descriptions = usage.getDescriptions()
97 var demanded = yargs.getDemanded()
100 Object.keys(aliases).forEach(function (key) {
101 aliases[key].forEach(function (alias) {
102 aliasLookup[alias] = key
106 Object.keys(argv).forEach(function (key) {
107 if (key !== '$0' && key !== '_' &&
108 !descriptions.hasOwnProperty(key) &&
109 !demanded.hasOwnProperty(key) &&
110 !aliasLookup.hasOwnProperty(key)) {
115 if (unknown.length > 0) {
117 'Unknown argument: %s',
118 'Unknown arguments: %s',
125 // validate arguments limited to enumerated choices
126 self.limitedChoices = function (argv) {
127 var options = yargs.getOptions()
130 if (!Object.keys(options.choices).length) return
132 Object.keys(argv).forEach(function (key) {
133 if (key !== '$0' && key !== '_' &&
134 options.choices.hasOwnProperty(key)) {
135 [].concat(argv[key]).forEach(function (value) {
136 // TODO case-insensitive configurability
137 if (options.choices[key].indexOf(value) === -1) {
138 invalid[key] = (invalid[key] || []).concat(value)
144 var invalidKeys = Object.keys(invalid)
146 if (!invalidKeys.length) return
148 var msg = __('Invalid values:')
149 invalidKeys.forEach(function (key) {
151 'Argument: %s, Given: %s, Choices: %s',
153 usage.stringifiedValues(invalid[key]),
154 usage.stringifiedValues(options.choices[key])
160 // custom checks, added using the `check` option on yargs.
162 self.check = function (f) {
166 self.customChecks = function (argv, aliases) {
167 checks.forEach(function (f) {
169 var result = f(argv, aliases)
171 usage.fail(__('Argument check failed: %s', f.toString()))
172 } else if (typeof result === 'string') {
176 usage.fail(err.message ? err.message : err)
181 // check implications, argument foo implies => argument bar.
183 self.implies = function (key, value) {
184 if (typeof key === 'object') {
185 Object.keys(key).forEach(function (k) {
186 self.implies(k, key[k])
192 self.getImplied = function () {
196 self.implications = function (argv) {
199 Object.keys(implied).forEach(function (key) {
202 var value = implied[key]
204 // convert string '1' to number 1
206 key = isNaN(num) ? key : num
208 if (typeof key === 'number') {
209 // check length of argv._
210 key = argv._.length >= key
211 } else if (key.match(/^--no-.+/)) {
212 // check if key doesn't exist
213 key = key.match(/^--no-(.+)/)[1]
216 // check if key exists
221 value = isNaN(num) ? value : num
223 if (typeof value === 'number') {
224 value = argv._.length >= value
225 } else if (value.match(/^--no-.+/)) {
226 value = value.match(/^--no-(.+)/)[1]
233 implyFail.push(origKey)
237 if (implyFail.length) {
238 var msg = __('Implications failed:') + '\n'
240 implyFail.forEach(function (key) {
241 msg += (' ' + key + ' -> ' + implied[key])