Skip to content
This repository was archived by the owner on Oct 17, 2024. It is now read-only.

Commit 36407ea

Browse files
authored
adjust the validation of mandatory options (#246)
* adjust the validation of mandatory options * typo
1 parent f0f6cd2 commit 36407ea

7 files changed

+37
-13
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 2.4.2
2+
3+
* Change the validation of `mandatory` options; they now perform validation when
4+
the value is retrieved (from the `ArgResults` object), instead of when the
5+
args are parsed.
6+
17
## 2.4.1
28

39
* Add a `CONTRIBUTING.md` file; move the publishing automation docs from the

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
Parses raw command-line arguments into a set of options and values.
66

7-
This library supports [GNU][] and [POSIX][] style options, and it works
8-
in both server-side and client-side apps.
7+
This library supports [GNU][] and [POSIX][] style options, and it works in both
8+
server-side and client-side apps.
99

1010
## Defining options
1111

@@ -78,8 +78,8 @@ The callbacks for all options are called whenever a set of arguments is parsed.
7878
If an option isn't provided in the args, its callback is passed the default
7979
value, or `null` if no default value is set.
8080

81-
If an option is `mandatory` but not provided, the parser throws an
82-
[`ArgParserException`][ArgParserException].
81+
If an option is `mandatory` but not provided, the results object throws an
82+
[`ArgumentError`][ArgumentError] on retrieval.
8383

8484
```dart
8585
parser.addOption('mode', mandatory: true);

lib/src/arg_results.dart

+6-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ class ArgResults {
6565
throw ArgumentError('Could not find an option named "$name".');
6666
}
6767

68-
return _parser.options[name]!.valueOrDefault(_parsed[name]);
68+
final option = _parser.options[name]!;
69+
if (option.mandatory && !_parsed.containsKey(name)) {
70+
throw ArgumentError('Option $name is mandatory.');
71+
}
72+
73+
return option.valueOrDefault(_parsed[name]);
6974
}
7075

7176
/// The names of the available options.

lib/src/parser.dart

+5-4
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,15 @@ class Parser {
9595
_grammar.options.forEach((name, option) {
9696
var parsedOption = _results[name];
9797

98-
// Check if an option was mandatory and exist
99-
// if not throw an exception
98+
var callback = option.callback;
99+
if (callback == null) return;
100+
101+
// Check if an option is mandatory and was passed; if not, throw an
102+
// exception.
100103
if (option.mandatory && parsedOption == null) {
101104
throw ArgParserException('Option $name is mandatory.');
102105
}
103106

104-
var callback = option.callback;
105-
if (callback == null) return;
106107
// ignore: avoid_dynamic_calls
107108
callback(option.valueOrDefault(parsedOption));
108109
});

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: args
2-
version: 2.4.1
2+
version: 2.4.2
33
description: >-
44
Library for defining parsers for parsing raw command-line arguments into a set
55
of options and values using GNU and POSIX style options.

test/command_runner_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ Run "test help" to see global options.'''));
736736
runner.addCommand(subcommand);
737737
expect(
738738
() => runner.run([subcommand.name]),
739-
throwsA(isA<UsageException>().having((e) => e.message, 'message',
739+
throwsA(isA<ArgumentError>().having((e) => e.message, 'message',
740740
contains('Option mandatory-option is mandatory'))));
741741
expect(await runner.run([subcommand.name, '--mandatory-option', 'foo']),
742742
'foo');

test/parse_test.dart

+14-2
Original file line numberDiff line numberDiff line change
@@ -514,14 +514,17 @@ void main() {
514514
test('throw if no args', () {
515515
var parser = ArgParser();
516516
parser.addOption('username', mandatory: true);
517-
throwsFormat(parser, []);
517+
var results = parser.parse([]);
518+
expect(() => results['username'], throwsA(isA<ArgumentError>()));
518519
});
519520

520521
test('throw if no mandatory args', () {
521522
var parser = ArgParser();
522523
parser.addOption('test');
523524
parser.addOption('username', mandatory: true);
524-
throwsFormat(parser, ['--test', 'test']);
525+
var results = parser.parse(['--test', 'test']);
526+
expect(results['test'], equals('test'));
527+
expect(() => results['username'], throwsA(isA<ArgumentError>()));
525528
});
526529

527530
test('parse successfully', () {
@@ -530,6 +533,15 @@ void main() {
530533
var results = parser.parse(['--test', 'test']);
531534
expect(results['test'], equals('test'));
532535
});
536+
537+
test('throws when value retrieved', () {
538+
var parser = ArgParser();
539+
parser.addFlag('help', abbr: 'h', negatable: false);
540+
parser.addOption('test', mandatory: true);
541+
var results = parser.parse(['-h']);
542+
expect(results['help'], true);
543+
expect(() => results['test'], throwsA(isA<ArgumentError>()));
544+
});
533545
});
534546
});
535547

0 commit comments

Comments
 (0)