fix a null assertion error when there are missing mandatory args in commands (#199)
Fixes https://github.com/dart-lang/args/issues/197
The 2nd argument to ArgParserException is supposed to be the command chain that it was parsed from and not the option (note this is handled separately as well) - this was causing the command runner to throw a null assertion error later on by passing the name of the mandatory option as the command name, which doesn't exist as a command.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 37d6220..ab38339 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.1.1
+
+* Fix a bug with `mandatory` options which caused a null assertion failure when
+ used within a command.
+
## 2.1.0
* Add a `mandatory` argument to require the presence of an option.
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index de987a8..ed6e2c7 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -98,7 +98,7 @@
// Check if an option was mandatory and exist
// if not throw an exception
if (option.mandatory && parsedOption == null) {
- throw ArgParserException('Option $name is mandatory.', [name]);
+ throw ArgParserException('Option $name is mandatory.');
}
var callback = option.callback;
diff --git a/pubspec.yaml b/pubspec.yaml
index 5fe2b89..e3db8cd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: args
-version: 2.1.0
+version: 2.1.1
homepage: https://github.com/dart-lang/args
description: >-
Library for defining parsers for parsing raw command-line arguments into a set
diff --git a/test/command_runner_test.dart b/test/command_runner_test.dart
index f030adc..29dd9fa 100644
--- a/test/command_runner_test.dart
+++ b/test/command_runner_test.dart
@@ -462,4 +462,30 @@
Run "test help" to see global options.'''));
});
});
+
+ test('mandatory options in commands', () async {
+ var subcommand = _MandatoryOptionCommand();
+ runner.addCommand(subcommand);
+ expect(
+ () => runner.run([subcommand.name]),
+ throwsA(isA<UsageException>().having((e) => e.message, 'message',
+ contains('Option mandatory-option is mandatory'))));
+ expect(await runner.run([subcommand.name, '--mandatory-option', 'foo']),
+ 'foo');
+ });
+}
+
+class _MandatoryOptionCommand extends Command {
+ _MandatoryOptionCommand() {
+ argParser.addOption('mandatory-option', mandatory: true);
+ }
+
+ @override
+ String get description => 'A command with a mandatory option';
+
+ @override
+ String get name => 'mandatory-option-command';
+
+ @override
+ String run() => argResults!['mandatory-option'];
}