Add ArgParser.allowAnything(). (#71)
Closes #70
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f5c8c6..2a0f614 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.13.8
+
+* Add `new ArgParser.allowAnything()`. This allows any input, without parsing
+ any options.
+
## 0.13.7
* Add explicit support for forwarding the value returned by `Command.run()` to
diff --git a/lib/src/allow_anything_parser.dart b/lib/src/allow_anything_parser.dart
new file mode 100644
index 0000000..450920c
--- /dev/null
+++ b/lib/src/allow_anything_parser.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'arg_parser.dart';
+import 'arg_results.dart';
+import 'option.dart';
+import 'parser.dart';
+
+/// An ArgParser that treats *all input* as non-option arguments.
+class AllowAnythingParser implements ArgParser {
+ Map<String, Option> get options => const {};
+ Map<String, ArgParser> get commands => const {};
+ bool get allowTrailingOptions => false;
+ bool get allowsAnything => true;
+
+ ArgParser addCommand(String name, [ArgParser parser]) {
+ throw new UnsupportedError(
+ "ArgParser.allowAnything().addCommands() isn't supported.");
+ }
+
+ void addFlag(String name,
+ {String abbr,
+ String help,
+ bool defaultsTo: false,
+ bool negatable: true,
+ void callback(bool value),
+ bool hide: false}) {
+ throw new UnsupportedError(
+ "ArgParser.allowAnything().addFlag() isn't supported.");
+ }
+
+ void addOption(String name,
+ {String abbr,
+ String help,
+ String valueHelp,
+ List<String> allowed,
+ Map<String, String> allowedHelp,
+ String defaultsTo,
+ void callback(value),
+ bool allowMultiple: false,
+ bool splitCommas,
+ bool hide: false}) {
+ throw new UnsupportedError(
+ "ArgParser.allowAnything().addOption() isn't supported.");
+ }
+
+ void addSeparator(String text) {
+ throw new UnsupportedError(
+ "ArgParser.allowAnything().addSeparator() isn't supported.");
+ }
+
+ ArgResults parse(List<String> args) =>
+ new Parser(null, this, args.toList()).parse();
+
+ String getUsage() => usage;
+
+ String get usage => "";
+
+ getDefault(String option) {
+ throw new ArgumentError('No option named $option');
+ }
+
+ Option findByAbbreviation(String abbr) => null;
+}
diff --git a/lib/src/arg_parser.dart b/lib/src/arg_parser.dart
index 44ceb64..69de95a 100644
--- a/lib/src/arg_parser.dart
+++ b/lib/src/arg_parser.dart
@@ -4,6 +4,7 @@
import 'dart:collection';
+import 'allow_anything_parser.dart';
import 'arg_results.dart';
import 'option.dart';
import 'parser.dart';
@@ -29,6 +30,10 @@
/// arguments.
final bool allowTrailingOptions;
+ /// Whether or not this parser treats unrecognized options as non-option
+ /// arguments.
+ bool get allowsAnything => false;
+
/// Creates a new ArgParser.
///
/// If [allowTrailingOptions] is set, the parser will continue parsing even
@@ -36,8 +41,15 @@
/// This allows options to be specified after regular arguments. Defaults to
/// `false`.
factory ArgParser({bool allowTrailingOptions: false}) =>
- new ArgParser._(<String, Option>{}, <String, ArgParser>{},
- allowTrailingOptions: allowTrailingOptions);
+ new ArgParser._({}, {}, allowTrailingOptions: allowTrailingOptions);
+
+ /// Creates a new ArgParser that treats *all input* as non-option arguments.
+ ///
+ /// This is intended to allow arguments to be passed through to child
+ /// processes without needing to be redefined in the parent.
+ ///
+ /// Options may not be defined for this parser.
+ factory ArgParser.allowAnything() = AllowAnythingParser;
ArgParser._(Map<String, Option> options, Map<String, ArgParser> commands,
{bool allowTrailingOptions: false})
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index 82b74ce..c1bcc84 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -47,6 +47,11 @@
/// Parses the arguments. This can only be called once.
ArgResults parse() {
var arguments = args.toList();
+ if (grammar.allowsAnything) {
+ return newArgResults(
+ grammar, const {}, commandName, null, arguments, arguments);
+ }
+
ArgResults commandResults;
// Parse the args.
diff --git a/pubspec.yaml b/pubspec.yaml
index e1a6b05..10531e4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: args
-version: 0.13.7
+version: 0.13.8-dev
author: "Dart Team <misc@dartlang.org>"
homepage: https://github.com/dart-lang/args
description: >
diff --git a/test/allow_anything_test.dart b/test/allow_anything_test.dart
new file mode 100644
index 0000000..7e229af
--- /dev/null
+++ b/test/allow_anything_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import 'package:args/args.dart';
+
+import 'utils.dart';
+
+void main() {
+ group('new ArgParser.allowAnything()', () {
+ ArgParser parser;
+ setUp(() {
+ parser = new ArgParser.allowAnything();
+ });
+
+ test('exposes empty values', () {
+ expect(parser.options, isEmpty);
+ expect(parser.commands, isEmpty);
+ expect(parser.allowTrailingOptions, isFalse);
+ expect(parser.allowsAnything, isTrue);
+ expect(parser.usage, isEmpty);
+ expect(parser.getUsage(), isEmpty);
+ expect(parser.findByAbbreviation("a"), isNull);
+ });
+
+ test('mutation methods throw errors', () {
+ expect(() => parser.addCommand("command"), throwsUnsupportedError);
+ expect(() => parser.addFlag("flag"), throwsUnsupportedError);
+ expect(() => parser.addOption("option"), throwsUnsupportedError);
+ expect(() => parser.addSeparator("==="), throwsUnsupportedError);
+ });
+
+ test('getDefault() throws an error', () {
+ expect(() => parser.getDefault('option'), throwsArgumentError);
+ });
+
+ test('parses all values as rest arguments', () {
+ var results = parser.parse(['--foo', '-abc', '--', 'bar']);
+ expect(results.options, isEmpty);
+ expect(results.rest, equals(['--foo', '-abc', '--', 'bar']));
+ expect(results.arguments, equals(['--foo', '-abc', '--', 'bar']));
+ expect(results.command, isNull);
+ expect(results.name, isNull);
+ });
+
+ test('works as a subcommand', () {
+ var commandParser = new ArgParser()..addCommand('command', parser);
+ var results =
+ commandParser.parse(['command', '--foo', '-abc', '--', 'bar']);
+ expect(results.command.options, isEmpty);
+ expect(results.command.rest, equals(['--foo', '-abc', '--', 'bar']));
+ expect(results.command.arguments, equals(['--foo', '-abc', '--', 'bar']));
+ expect(results.command.name, equals('command'));
+ });
+ });
+}