Require Dart 2.18, update lints, update CI, add dependabot (#222)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..71cdeea
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,10 @@
+# Set update schedule for GitHub Actions
+# See https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot
+
+version: 2
+updates:
+
+- package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index 0ca4263..c75daff 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -21,8 +21,8 @@
matrix:
sdk: [dev]
steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1.0
+ - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
+ - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d
with:
sdk: ${{ matrix.sdk }}
- id: install
@@ -47,10 +47,10 @@
# Add macos-latest and/or windows-latest if relevant for this package
os: [ubuntu-latest]
# Add stable if the package should also be tested on stable
- sdk: [2.12.0, dev]
+ sdk: [2.18.0, dev]
steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1.0
+ - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
+ - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d
with:
sdk: ${{ matrix.sdk }}
- id: install
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d3b5eb4..78adc8d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.3.2-dev
+
+* Require Dart 2.18
+
## 2.3.1
* Switch to using package:lints.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 106b824..a9dbdb5 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,32 +1,27 @@
+# https://dart.dev/guides/language/analysis-options
include: package:lints/recommended.yaml
linter:
rules:
- - avoid_null_checks_in_equality_operators
+ - always_declare_return_types
+ - avoid_dynamic_calls
- avoid_unused_constructor_parameters
- - await_only_futures
- - camel_case_types
- cancel_subscriptions
- comment_references
- - constant_identifier_names
- - control_flow_in_finally
- directives_ordering
- - empty_statements
- - hash_and_equals
- - implementation_imports
- - iterable_contains_unrelated_type
- - library_names
- - library_prefixes
- - list_remove_unrelated_type
- - non_constant_identifier_names
- - overridden_fields
+ - lines_longer_than_80_chars
+ - literal_only_boolean_expressions
+ - missing_whitespace_between_adjacent_strings
+ - no_adjacent_strings_in_list
+ - no_runtimeType_toString
+ - omit_local_variable_types
- package_api_docs
- - package_names
- - package_prefixed_library_names
- - prefer_final_fields
- - prefer_generic_function_type_aliases
- - prefer_typing_uninitialized_variables
+ - prefer_relative_imports
+ - prefer_single_quotes
- test_types_in_equals
- throw_in_finally
- - unnecessary_brace_in_string_interps
- - unrelated_type_equality_checks
+ - type_annotate_public_apis
+ - unawaited_futures
+ - unnecessary_await_in_return
+ - unnecessary_lambdas
+ - use_super_parameters
diff --git a/example/arg_parser/example.dart b/example/arg_parser/example.dart
index 9a231e8..2123cc4 100644
--- a/example/arg_parser/example.dart
+++ b/example/arg_parser/example.dart
@@ -55,7 +55,6 @@
allowedHelp: {
'vm': 'Run Dart code on the standalone dart vm.',
'd8': 'Run JavaScript from the command line using v8.',
- // TODO(antonm): rename flag.
'drt': 'Run Dart or JavaScript in the headless version of Chrome,\n'
'content shell.',
'dartium': 'Run Dart or JavaScript in Dartium.',
diff --git a/example/command_runner/draw.dart b/example/command_runner/draw.dart
index d14ed4a..3f0baec 100644
--- a/example/command_runner/draw.dart
+++ b/example/command_runner/draw.dart
@@ -34,7 +34,7 @@
@override
FutureOr<String>? run() {
final size = int.parse(argResults?['size'] ?? '20');
- final char = globalResults?['char']?[0] ?? '#';
+ final char = (globalResults?['char'] as String?)?[0] ?? '#';
return draw(size, size, char, (x, y) => true);
}
}
@@ -56,7 +56,7 @@
@override
FutureOr<String>? run() {
final size = 2 * int.parse(argResults?['radius'] ?? '10');
- final char = globalResults?['char']?[0] ?? '#';
+ final char = (globalResults?['char'] as String?)?[0] ?? '#';
return draw(size, size, char, (x, y) => x * x + y * y < 1);
}
}
@@ -94,7 +94,7 @@
@override
FutureOr<String>? run() {
final size = int.parse(argResults?['size'] ?? '20');
- final char = globalResults?['char']?[0] ?? '#';
+ final char = (globalResults?['char'] as String?)?[0] ?? '#';
return drawTriangle(size, size * sqrt(3) ~/ 2, char);
}
}
@@ -118,7 +118,7 @@
FutureOr<String>? run() {
final width = int.parse(argResults?['width'] ?? '50');
final height = int.parse(argResults?['height'] ?? '10');
- final char = globalResults?['char']?[0] ?? '#';
+ final char = (globalResults?['char'] as String?)?[0] ?? '#';
return drawTriangle(width, height, char);
}
}
@@ -126,9 +126,9 @@
String draw(
int width, int height, String char, bool Function(double, double) pixel) {
final out = StringBuffer();
- for (int y = 0; y <= height; ++y) {
+ for (var y = 0; y <= height; ++y) {
final ty = 2 * y / height - 1;
- for (int x = 0; x <= width; ++x) {
+ for (var x = 0; x <= width; ++x) {
final tx = 2 * x / width - 1;
out.write(pixel(tx, ty) ? char : ' ');
}
diff --git a/lib/command_runner.dart b/lib/command_runner.dart
index 007c597..e2c9192 100644
--- a/lib/command_runner.dart
+++ b/lib/command_runner.dart
@@ -52,13 +52,16 @@
var usagePrefix = 'Usage:';
var buffer = StringBuffer();
buffer.writeln(
- '$usagePrefix ${_wrap(invocation, hangingIndent: usagePrefix.length)}\n');
+ '$usagePrefix ${_wrap(invocation, hangingIndent: usagePrefix.length)}\n',
+ );
buffer.writeln(_wrap('Global options:'));
buffer.writeln('${argParser.usage}\n');
buffer.writeln(
- '${_getCommandUsage(_commands, lineLength: argParser.usageLineLength)}\n');
+ '${_getCommandUsage(_commands, lineLength: argParser.usageLineLength)}\n',
+ );
buffer.write(_wrap(
- 'Run "$executableName help <command>" for more information about a command.'));
+ 'Run "$executableName help <command>" for more information about a '
+ 'command.'));
if (usageFooter != null) {
buffer.write('\n${_wrap(usageFooter!)}');
}
diff --git a/lib/src/arg_parser_exception.dart b/lib/src/arg_parser_exception.dart
index 56ac851..d727d70 100644
--- a/lib/src/arg_parser_exception.dart
+++ b/lib/src/arg_parser_exception.dart
@@ -9,7 +9,6 @@
/// This will be empty if the error was on the root parser.
final List<String> commands;
- ArgParserException(String message, [Iterable<String>? commands])
- : commands = commands == null ? const [] : List.unmodifiable(commands),
- super(message);
+ ArgParserException(super.message, [Iterable<String>? commands])
+ : commands = commands == null ? const [] : List.unmodifiable(commands);
}
diff --git a/lib/src/help_command.dart b/lib/src/help_command.dart
index 9e2f5a3..f04d014 100644
--- a/lib/src/help_command.dart
+++ b/lib/src/help_command.dart
@@ -22,8 +22,6 @@
bool get hidden => true;
@override
- // TODO: Remove when https://github.com/dart-lang/linter/issues/2792 is fixed.
- // ignore: prefer_void_to_null
Null run() {
// Show the default help if no command was specified.
if (argResults!.rest.isEmpty) {
@@ -34,7 +32,7 @@
// Walk the command tree to show help for the selected command or
// subcommand.
var commands = runner!.commands;
- Command? command;
+ Command<T>? command;
var commandString = runner!.executableName;
for (var name in argResults!.rest) {
@@ -53,7 +51,7 @@
}
command = commands[name];
- commands = command!.subcommands as Map<String, Command<T>>;
+ commands = command!.subcommands;
commandString += ' $name';
}
diff --git a/lib/src/option.dart b/lib/src/option.dart
index 09e5d20..50a8628 100644
--- a/lib/src/option.dart
+++ b/lib/src/option.dart
@@ -13,7 +13,7 @@
String? valueHelp,
Iterable<String>? allowed,
Map<String, String>? allowedHelp,
- defaultsTo,
+ Object? defaultsTo,
Function? callback,
OptionType type,
{bool? negatable,
@@ -146,14 +146,14 @@
/// For single-valued options, it will be [defaultsTo] if set or `null`
/// otherwise. For multiple-valued options, it will be an empty list or a
/// list containing [defaultsTo] if set.
- dynamic valueOrDefault(value) {
+ dynamic valueOrDefault(Object? value) {
if (value != null) return value;
if (isMultiple) return defaultsTo ?? <String>[];
return defaultsTo;
}
@Deprecated('Use valueOrDefault instead.')
- dynamic getOrDefault(value) => valueOrDefault(value);
+ dynamic getOrDefault(Object? value) => valueOrDefault(value);
static final _invalidChars = RegExp(r'''[ \t\r\n"'\\/]''');
}
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index ed6e2c7..0862ce9 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -103,6 +103,7 @@
var callback = option.callback;
if (callback == null) return;
+ // ignore: avoid_dynamic_calls
callback(option.valueOrDefault(parsedOption));
});
@@ -320,7 +321,7 @@
return;
}
- var list = results.putIfAbsent(option.name, () => <String>[]);
+ var list = results.putIfAbsent(option.name, () => <String>[]) as List;
if (option.splitCommas) {
for (var element in value.split(',')) {
diff --git a/lib/src/usage.dart b/lib/src/usage.dart
index f583ece..d97cc2d 100644
--- a/lib/src/usage.dart
+++ b/lib/src/usage.dart
@@ -105,7 +105,8 @@
_write(2, '(defaults to on)');
}
} else if (option.isMultiple) {
- if (option.defaultsTo != null && option.defaultsTo.isNotEmpty) {
+ if (option.defaultsTo != null &&
+ (option.defaultsTo as Iterable).isNotEmpty) {
var defaults =
(option.defaultsTo as List).map((value) => '"$value"').join(', ');
_write(2, '(defaults to $defaults)');
@@ -137,9 +138,9 @@
String _allowedTitle(Option option, String allowed) {
var isDefault = option.defaultsTo is List
- ? option.defaultsTo.contains(allowed)
+ ? (option.defaultsTo as List).contains(allowed)
: option.defaultsTo == allowed;
- return ' [$allowed]' + (isDefault ? ' (default)' : '');
+ return ' [$allowed]${isDefault ? ' (default)' : ''}';
}
List<int> _calculateColumnWidths() {
@@ -234,7 +235,7 @@
String _buildAllowedList(Option option) {
var isDefault = option.defaultsTo is List
- ? option.defaultsTo.contains
+ ? (option.defaultsTo as List).contains
: (value) => value == option.defaultsTo;
var allowedBuffer = StringBuffer();
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 648e554..ae5e093 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -21,7 +21,9 @@
///
/// ```dart
/// var prefix = "Usage: ";
-/// print(prefix + wrapText(invocation, hangingIndent: prefix.length, length: 40));
+/// print(
+/// prefix + wrapText(invocation, hangingIndent: prefix.length, length: 40),
+/// );
/// ```
///
/// yields:
diff --git a/pubspec.yaml b/pubspec.yaml
index 4fdf565..e99e29b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,13 +1,13 @@
name: args
-version: 2.3.1
+version: 2.3.2-dev
description: >-
Library for defining parsers for parsing raw command-line arguments into a set
of options and values using GNU and POSIX style options.
repository: https://github.com/dart-lang/args
environment:
- sdk: '>=2.12.0 <3.0.0'
+ sdk: '>=2.18.0 <3.0.0'
dev_dependencies:
- lints: ^1.0.0
+ lints: ^2.0.0
test: ^1.16.0
diff --git a/test/parse_performance_test.dart b/test/parse_performance_test.dart
index 210f853..b099379 100644
--- a/test/parse_performance_test.dart
+++ b/test/parse_performance_test.dart
@@ -56,12 +56,15 @@
print('Parsed $baseSize elements in ${baseTime}ms, '
'${baseSize * multiplier} elements in ${largeTime}ms.');
- expect(largeTime, lessThan(baseTime * multiplier * 3),
- reason:
- 'Comparing large data set time ${largeTime}ms to small data set time '
- '${baseTime}ms. Data set increased ${multiplier}x, time is allowed to '
- 'increase up to ${multiplier * 3}x, but it increased '
- '${largeTime ~/ baseTime}x.');
+ expect(
+ largeTime,
+ lessThan(baseTime * multiplier * 3),
+ reason:
+ 'Comparing large data set time ${largeTime}ms to small data set time '
+ '${baseTime}ms. Data set increased ${multiplier}x, time is allowed to '
+ 'increase up to ${multiplier * 3}x, but it increased '
+ '${largeTime ~/ baseTime}x.',
+ );
}
int _time(void Function() function) {
diff --git a/test/test_utils.dart b/test/test_utils.dart
index c580d71..ab51146 100644
--- a/test/test_utils.dart
+++ b/test/test_utils.dart
@@ -10,8 +10,7 @@
@override
String get usageFooter => 'Also, footer!';
- CommandRunnerWithFooter(String executableName, String description)
- : super(executableName, description);
+ CommandRunnerWithFooter(super.executableName, super.description);
}
class CommandRunnerWithFooterAndWrapping extends CommandRunner {
@@ -25,12 +24,11 @@
ArgParser get argParser => _argParser;
final _argParser = ArgParser(usageLineLength: 40);
- CommandRunnerWithFooterAndWrapping(String executableName, String description)
- : super(executableName, description);
+ CommandRunnerWithFooterAndWrapping(super.executableName, super.description);
}
class FooCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'foo';
@@ -76,7 +74,7 @@
}
class Category1Command extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'bar';
@@ -97,7 +95,7 @@
}
class Category2Command extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'baz';
@@ -118,7 +116,7 @@
}
class Category2Command2 extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'baz2';
@@ -139,7 +137,7 @@
}
class MultilineCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'multiline';
@@ -157,7 +155,7 @@
}
class WrappingCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
ArgParser get argParser => _argParser;
@@ -180,7 +178,7 @@
}
class LongCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
ArgParser get argParser => _argParser;
@@ -190,11 +188,11 @@
final name = 'long';
@override
- final description = 'This command has a long description that needs to be '
- 'wrapped sometimes.\nIt has embedded newlines,\n'
- ' and indented lines that also need to be wrapped and have their '
- 'indentation preserved.\n' +
- ('0123456789' * 10);
+ final description =
+ 'This command has a long description that needs to be wrapped '
+ 'sometimes.\nIt has embedded newlines,\n'
+ ' and indented lines that also need to be wrapped and have their '
+ 'indentation preserved.\n${'0123456789' * 10}';
@override
final takesArguments = false;
@@ -211,7 +209,7 @@
}
class HiddenCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'hidden';
@@ -232,7 +230,7 @@
}
class HiddenCategorizedCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'hiddencategorized';
@@ -256,7 +254,7 @@
}
class AliasedCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'aliased';
@@ -277,7 +275,7 @@
}
class AsyncCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'async';
@@ -293,7 +291,7 @@
}
class AllowAnythingCommand extends Command {
- var hasRun = false;
+ bool hasRun = false;
@override
final name = 'allowAnything';
@@ -320,7 +318,7 @@
String get description => 'A command with a custom name';
}
-void throwsIllegalArg(function, {String? reason}) {
+void throwsIllegalArg(void Function() function, {String? reason}) {
expect(function, throwsArgumentError, reason: reason);
}
diff --git a/test/usage_test.dart b/test/usage_test.dart
index 6999724..1167186 100644
--- a/test/usage_test.dart
+++ b/test/usage_test.dart
@@ -322,15 +322,19 @@
parser.addFlag('longNewline',
help: 'The flag with a really long help text and newlines\n\nthat '
'will still be wrapped because it is really long.');
- parser.addFlag('solid',
- help:
- 'The-flag-with-no-whitespace-that-will-be-wrapped-by-splitting-a-word.');
+ parser.addFlag(
+ 'solid',
+ help: 'The-flag-with-no-whitespace-that-will-be-wrapped-by-splitting-a'
+ '-word.',
+ );
parser.addFlag('longWhitespace',
help:
- ' The flag with a really long help text and whitespace at the start.');
+ ' The flag with a really long help text and whitespace '
+ 'at the start.');
parser.addFlag('longTrailspace',
help:
- 'The flag with a really long help text and whitespace at the end. ');
+ 'The flag with a really long help text and whitespace at the end.'
+ ' ');
parser.addFlag('small1', help: ' a ');
parser.addFlag('small2', help: ' a');
parser.addFlag('small3', help: 'a ');
@@ -364,9 +368,11 @@
help:
'The flag with a really long help text and newlines\n\nthat will '
'still be wrapped because it is really long.');
- parser.addFlag('solid',
- help:
- 'The-flag-with-no-whitespace-that-will-be-wrapped-by-splitting-a-word.');
+ parser.addFlag(
+ 'solid',
+ help: 'The-flag-with-no-whitespace-that-will-be-wrapped-by-splitting-a-'
+ 'word.',
+ );
parser.addFlag('small1', help: ' a ');
parser.addFlag('small2', help: ' a');
parser.addFlag('small3', help: 'a ');
@@ -494,12 +500,11 @@
}
void validateUsage(ArgParser parser, String expected) {
- expected = unindentString(expected);
+ expected = _unindentString(expected);
expect(parser.usage, equals(expected));
}
-// TODO(rnystrom): Replace one in test_utils.
-String unindentString(String text) {
+String _unindentString(String text) {
var lines = text.split('\n');
// Count the indentation of the last line.
diff --git a/test/utils_test.dart b/test/utils_test.dart
index 50a4f9f..3cc45b8 100644
--- a/test/utils_test.dart
+++ b/test/utils_test.dart
@@ -7,13 +7,12 @@
const _lineLength = 40;
const _longLine = 'This is a long line that needs to be wrapped.';
-final _longLineWithNewlines = 'This is a long line with newlines that\n'
- 'needs to be wrapped.\n\n' +
- '0123456789' * 5;
+final _longLineWithNewlines =
+ 'This is a long line with newlines that\nneeds to be wrapped.\n\n'
+ '${'0123456789' * 5}';
final _indentedLongLineWithNewlines =
- ' This is an indented long line with newlines that\n'
- 'needs to be wrapped.\n\tAnd preserves tabs.\n \n ' +
- '0123456789' * 5;
+ ' This is an indented long line with newlines that\nneeds to be wrapped.'
+ '\n\tAnd preserves tabs.\n \n ${'0123456789' * 5}';
const _shortLine = 'Short line.';
const _indentedLongLine = ' This is an indented long line that needs to be '
'wrapped and indentation preserved.';
@@ -42,7 +41,7 @@
0123456789'''));
});
test('refuses to wrap to a column smaller than 10 characters', () {
- expect(wrapText('$_longLine ' + '0123456789' * 4, length: 1), equals('''
+ expect(wrapText('$_longLine ${'0123456789' * 4}', length: 1), equals('''
This is a
long line
that needs
@@ -104,13 +103,14 @@
Short line.'''));
});
test(
- 'handles hangingIndent with two unwrapped lines and the second is empty.',
- () {
- expect(wrapText('$_shortLine\n', length: _lineLength, hangingIndent: 6),
- equals('''
+ 'handles hangingIndent with two unwrapped lines and the second is empty.',
+ () {
+ expect(wrapText('$_shortLine\n', length: _lineLength, hangingIndent: 6),
+ equals('''
Short line.
'''));
- });
+ },
+ );
test('honors hangingIndent parameter on already indented line.', () {
expect(wrapText(_indentedLongLine, length: _lineLength, hangingIndent: 6),
equals('''
@@ -151,7 +151,7 @@
test('refuses to wrap to a column smaller than 10 characters', () {
expect(
- wrapTextAsLines('$_longLine ' + '0123456789' * 4, length: 1),
+ wrapTextAsLines('$_longLine ${'0123456789' * 4}', length: 1),
equals([
'This is a',
'long line',