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

Commit

Permalink
adjust the validation of mandatory options (#246)
Browse files Browse the repository at this point in the history
* adjust the validation of mandatory options

* typo
  • Loading branch information
devoncarew authored May 31, 2023
1 parent f0f6cd2 commit 36407ea
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.4.2

* Change the validation of `mandatory` options; they now perform validation when
the value is retrieved (from the `ArgResults` object), instead of when the
args are parsed.

## 2.4.1

* Add a `CONTRIBUTING.md` file; move the publishing automation docs from the
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

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

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

## Defining options

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

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

```dart
parser.addOption('mode', mandatory: true);
Expand Down
7 changes: 6 additions & 1 deletion lib/src/arg_results.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ class ArgResults {
throw ArgumentError('Could not find an option named "$name".');
}

return _parser.options[name]!.valueOrDefault(_parsed[name]);
final option = _parser.options[name]!;
if (option.mandatory && !_parsed.containsKey(name)) {
throw ArgumentError('Option $name is mandatory.');
}

return option.valueOrDefault(_parsed[name]);
}

/// The names of the available options.
Expand Down
9 changes: 5 additions & 4 deletions lib/src/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,15 @@ class Parser {
_grammar.options.forEach((name, option) {
var parsedOption = _results[name];

// Check if an option was mandatory and exist
// if not throw an exception
var callback = option.callback;
if (callback == null) return;

// Check if an option is mandatory and was passed; if not, throw an
// exception.
if (option.mandatory && parsedOption == null) {
throw ArgParserException('Option $name is mandatory.');
}

var callback = option.callback;
if (callback == null) return;
// ignore: avoid_dynamic_calls
callback(option.valueOrDefault(parsedOption));
});
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: args
version: 2.4.1
version: 2.4.2
description: >-
Library for defining parsers for parsing raw command-line arguments into a set
of options and values using GNU and POSIX style options.
Expand Down
2 changes: 1 addition & 1 deletion test/command_runner_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ Run "test help" to see global options.'''));
runner.addCommand(subcommand);
expect(
() => runner.run([subcommand.name]),
throwsA(isA<UsageException>().having((e) => e.message, 'message',
throwsA(isA<ArgumentError>().having((e) => e.message, 'message',
contains('Option mandatory-option is mandatory'))));
expect(await runner.run([subcommand.name, '--mandatory-option', 'foo']),
'foo');
Expand Down
16 changes: 14 additions & 2 deletions test/parse_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -514,14 +514,17 @@ void main() {
test('throw if no args', () {
var parser = ArgParser();
parser.addOption('username', mandatory: true);
throwsFormat(parser, []);
var results = parser.parse([]);
expect(() => results['username'], throwsA(isA<ArgumentError>()));
});

test('throw if no mandatory args', () {
var parser = ArgParser();
parser.addOption('test');
parser.addOption('username', mandatory: true);
throwsFormat(parser, ['--test', 'test']);
var results = parser.parse(['--test', 'test']);
expect(results['test'], equals('test'));
expect(() => results['username'], throwsA(isA<ArgumentError>()));
});

test('parse successfully', () {
Expand All @@ -530,6 +533,15 @@ void main() {
var results = parser.parse(['--test', 'test']);
expect(results['test'], equals('test'));
});

test('throws when value retrieved', () {
var parser = ArgParser();
parser.addFlag('help', abbr: 'h', negatable: false);
parser.addOption('test', mandatory: true);
var results = parser.parse(['-h']);
expect(results['help'], true);
expect(() => results['test'], throwsA(isA<ArgumentError>()));
});
});
});

Expand Down

0 comments on commit 36407ea

Please sign in to comment.