Use the recommended name for analysis_options
And add/fix a number of standard lints
diff --git a/.analysis_options b/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
- strong-mode: true
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..092773b
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,29 @@
+analyzer:
+ strong-mode: true
+linter:
+ rules:
+ # Errors
+ - avoid_empty_else
+ - comment_references
+ - control_flow_in_finally
+ - empty_statements
+ - hash_and_equals
+ - test_types_in_equals
+ - throw_in_finally
+ - unrelated_type_equality_checks
+ - valid_regexps
+
+ # Style
+ - annotate_overrides
+ - avoid_init_to_null
+ - avoid_return_types_on_setters
+ - await_only_futures
+ - camel_case_types
+ - empty_catches
+ - empty_constructor_bodies
+ - library_names
+ - library_prefixes
+ - non_constant_identifier_names
+ - prefer_is_not_empty
+ - slash_for_doc_comments
+ - type_init_formals
diff --git a/lib/command_runner.dart b/lib/command_runner.dart
index bbf08ae..2fe1517 100644
--- a/lib/command_runner.dart
+++ b/lib/command_runner.dart
@@ -15,7 +15,7 @@
export 'src/usage_exception.dart';
-/// A class for invoking [Commands] based on raw command-line arguments.
+/// A class for invoking [Command]s based on raw command-line arguments.
///
/// The type argument `T` represents the type returned by [Command.run] and
/// [CommandRunner.run]; it can be ommitted if you're not using the return
@@ -31,7 +31,7 @@
/// A single-line template for how to invoke this executable.
///
- /// Defaults to "$executableName <command> [arguments]". Subclasses can
+ /// Defaults to "$executableName <command> `arguments`". Subclasses can
/// override this for a more specific template.
String get invocation => "$executableName <command> [arguments]";
@@ -217,7 +217,7 @@
String get summary => description.split("\n").first;
/// A single-line template for how to invoke this command (e.g. `"pub get
- /// [package]"`).
+ /// `package`"`).
String get invocation {
var parents = [name];
for (var command = parent; command != null; command = command.parent) {
@@ -233,7 +233,7 @@
/// The command's parent command, if this is a subcommand.
///
- /// This will be `null` until [Command.addSubcommmand] has been called with
+ /// This will be `null` until [addSubcommand] has been called with
/// this command.
Command<T> get parent => _parent;
Command<T> _parent;
diff --git a/lib/src/arg_parser_exception.dart b/lib/src/arg_parser_exception.dart
index f4129d6..5ce0eab 100644
--- a/lib/src/arg_parser_exception.dart
+++ b/lib/src/arg_parser_exception.dart
@@ -2,7 +2,7 @@
// 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.
-/// An exception thrown by [ArgParser].
+/// An exception thrown by `ArgParser`.
class ArgParserException extends FormatException {
/// The command(s) that were parsed before discovering the error.
///
diff --git a/lib/src/arg_results.dart b/lib/src/arg_results.dart
index 20349da..744686d 100644
--- a/lib/src/arg_results.dart
+++ b/lib/src/arg_results.dart
@@ -8,7 +8,7 @@
/// Creates a new [ArgResults].
///
-/// Since [ArgResults] doesn't have a public constructor, this lets [Parser]
+/// Since [ArgResults] doesn't have a public constructor, this lets [ArgParser]
/// get to it. This function isn't exported to the public API of the package.
ArgResults newArgResults(
ArgParser parser,
diff --git a/lib/src/help_command.dart b/lib/src/help_command.dart
index 104327c..b119431 100644
--- a/lib/src/help_command.dart
+++ b/lib/src/help_command.dart
@@ -8,11 +8,17 @@
///
/// This command displays help information for the various subcommands.
class HelpCommand<T> extends Command<T> {
+ @override
final name = "help";
+
+ @override
String get description =>
"Display help information for ${runner.executableName}.";
+
+ @override
String get invocation => "${runner.executableName} help [command]";
+ @override
T run() {
// Show the default help if no command was specified.
if (argResults.rest.isEmpty) {
diff --git a/lib/src/option.dart b/lib/src/option.dart
index 5eb0efb..3ff7fe8 100644
--- a/lib/src/option.dart
+++ b/lib/src/option.dart
@@ -6,7 +6,7 @@
/// Creates a new [Option].
///
-/// Since [Option] doesn't have a public constructor, this lets [ArgParser]
+/// Since [Option] doesn't have a public constructor, this lets `ArgParser`
/// get to it. This function isn't exported to the public API of the package.
Option newOption(
String name,
@@ -137,7 +137,7 @@
///
/// --output text --output xml
///
- /// In the parsed [ArgResults], a multiple-valued option will always return
+ /// In the parsed `ArgResults`, a multiple-valued option will always return
/// a list, even if one or no values were passed.
static const MULTIPLE = const OptionType._("OptionType.MULTIPLE");
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index 6c2ee40..82b74ce 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -7,9 +7,9 @@
import 'arg_results.dart';
import 'option.dart';
-final _SOLO_OPT = new RegExp(r'^-([a-zA-Z0-9])$');
-final _ABBR_OPT = new RegExp(r'^-([a-zA-Z0-9]+)(.*)$');
-final _LONG_OPT = new RegExp(r'^--([a-zA-Z\-_0-9]+)(=(.*))?$');
+final _soloOpt = new RegExp(r'^-([a-zA-Z0-9])$');
+final _abbrOpt = new RegExp(r'^-([a-zA-Z0-9]+)(.*)$');
+final _longOpt = new RegExp(r'^--([a-zA-Z\-_0-9]+)(=(.*))?$');
/// The actual argument parsing class.
///
@@ -47,7 +47,7 @@
/// Parses the arguments. This can only be called once.
ArgResults parse() {
var arguments = args.toList();
- var commandResults = null;
+ ArgResults commandResults;
// Parse the args.
while (args.length > 0) {
@@ -120,7 +120,7 @@
/// We treat this differently than collapsed abbreviations (like "-abc") to
/// handle the possible value that may follow it.
bool parseSoloOption() {
- var soloOpt = _SOLO_OPT.firstMatch(current);
+ var soloOpt = _soloOpt.firstMatch(current);
if (soloOpt == null) return false;
var option = grammar.findByAbbreviation(soloOpt[1]);
@@ -146,7 +146,7 @@
/// (like "-abc") or a single abbreviation with the value directly attached
/// to it (like "-mrelease").
bool parseAbbreviation(Parser innermostCommand) {
- var abbrOpt = _ABBR_OPT.firstMatch(current);
+ var abbrOpt = _abbrOpt.firstMatch(current);
if (abbrOpt == null) return false;
// If the first character is the abbreviation for a non-flag option, then
@@ -206,7 +206,7 @@
/// Tries to parse the current argument as a long-form named option, which
/// may include a value like "--mode=release" or "--mode release".
bool parseLongOption() {
- var longOpt = _LONG_OPT.firstMatch(current);
+ var longOpt = _longOpt.firstMatch(current);
if (longOpt == null) return false;
var name = longOpt[1];
diff --git a/lib/src/usage_exception.dart b/lib/src/usage_exception.dart
index 2d8e112..7d783db 100644
--- a/lib/src/usage_exception.dart
+++ b/lib/src/usage_exception.dart
@@ -8,5 +8,6 @@
UsageException(this.message, this.usage);
+ @override
String toString() => "$message\n\n$usage";
}
diff --git a/test/utils.dart b/test/utils.dart
index a874eee..d9e4f70 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -9,6 +9,7 @@
import 'package:test/test.dart';
class CommandRunnerWithFooter extends CommandRunner {
+ @override
String get usageFooter => "Also, footer!";
CommandRunnerWithFooter(String executableName, String description)
@@ -18,55 +19,88 @@
class FooCommand extends Command {
var hasRun = false;
+ @override
final name = "foo";
+
+ @override
final description = "Set a value.";
+
+ @override
final takesArguments = false;
+ @override
void run() {
hasRun = true;
}
}
class ValueCommand extends Command<int> {
+ @override
final name = "foo";
+
+ @override
final description = "Return a value.";
+
+ @override
final takesArguments = false;
+ @override
int run() => 12;
}
class AsyncValueCommand extends Command<String> {
+ @override
final name = "foo";
+
+ @override
final description = "Return a future.";
+
+ @override
final takesArguments = false;
+ @override
Future<String> run() async => "hi";
}
class MultilineCommand extends Command {
var hasRun = false;
+ @override
final name = "multiline";
+
+ @override
final description = "Multi\nline.";
+
+ @override
final takesArguments = false;
+ @override
void run() {
hasRun = true;
}
}
class MultilineSummaryCommand extends MultilineCommand {
+ @override
String get summary => description;
}
class HiddenCommand extends Command {
var hasRun = false;
+ @override
final name = "hidden";
+
+ @override
final description = "Set a value.";
+
+ @override
final hidden = true;
+
+ @override
final takesArguments = false;
+ @override
void run() {
hasRun = true;
}
@@ -75,11 +109,19 @@
class AliasedCommand extends Command {
var hasRun = false;
+ @override
final name = "aliased";
+
+ @override
final description = "Set a value.";
+
+ @override
final takesArguments = false;
+
+ @override
final aliases = const ["alias", "als"];
+ @override
void run() {
hasRun = true;
}
@@ -88,10 +130,16 @@
class AsyncCommand extends Command {
var hasRun = false;
+ @override
final name = "async";
+
+ @override
final description = "Set a value asynchronously.";
+
+ @override
final takesArguments = false;
+ @override
Future run() => new Future.value().then((_) => hasRun = true);
}