From 76475973c39ede6bd3ca8a77032fbbd07682ab77 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Fri, 13 Mar 2026 15:40:48 -0600 Subject: [PATCH 1/6] Dart format updates for dart_style 3+ --- lib/src/tools/format_tool.dart | 46 ++++++++++- lib/src/utils/pubspec_lock.dart | 17 ++++ .../format/has_dart_style_v2/pubspec.yaml | 4 + .../format/has_dart_style_v3/pubspec.yaml | 4 + test/tools/format_tool_test.dart | 82 ++++++++++++++++++- 5 files changed, 145 insertions(+), 8 deletions(-) create mode 100644 test/tools/fixtures/format/has_dart_style_v2/pubspec.yaml create mode 100644 test/tools/fixtures/format/has_dart_style_v3/pubspec.yaml diff --git a/lib/src/tools/format_tool.dart b/lib/src/tools/format_tool.dart index 1e0f1a69..f94ba815 100644 --- a/lib/src/tools/format_tool.dart +++ b/lib/src/tools/format_tool.dart @@ -7,6 +7,8 @@ import 'package:io/ansi.dart'; import 'package:io/io.dart' show ExitCode; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; +import 'package:pub_semver/pub_semver.dart'; +import 'package:yaml/yaml.dart'; import '../dart_dev_tool.dart'; import '../utils/arg_results_utils.dart'; @@ -17,6 +19,7 @@ import '../utils/logging.dart'; import '../utils/organize_directives/organize_directives_in_paths.dart'; import '../utils/package_is_immediate_dependency.dart'; import '../utils/process_declaration.dart'; +import '../utils/pubspec_lock.dart'; import '../utils/run_process_and_ensure_exit.dart'; final _log = Logger('Format'); @@ -320,6 +323,8 @@ Iterable buildArgs( FormatMode? mode, { ArgResults? argResults, List? configuredFormatterArgs, + bool passWriteArgForOverwrite = true, + bool passLatestLanguageVersion = false, }) { final args = [ ...executableArgs, @@ -331,8 +336,9 @@ Iterable buildArgs( '-n', '--set-exit-if-changed', ], - if (mode == FormatMode.overwrite) '-w', + if (mode == FormatMode.overwrite && passWriteArgForOverwrite) '-w', if (mode == FormatMode.dryRun) '-n', + if (passLatestLanguageVersion) '--language-version=latest', // 2. Statically configured args from [FormatTool.formatterArgs] ...?configuredFormatterArgs, @@ -360,7 +366,9 @@ Iterable buildArgs( /// included, it will be added. Iterable buildArgsForDartFormat( Iterable executableArgs, FormatMode? mode, - {ArgResults? argResults, List? configuredFormatterArgs}) { + {ArgResults? argResults, + List? configuredFormatterArgs, + bool passLatestLanguageVersion = false}) { final args = [ ...executableArgs, @@ -369,6 +377,7 @@ Iterable buildArgsForDartFormat( // 1. Mode flag(s), if configured if (mode == FormatMode.check) ...['-o', 'none', '--set-exit-if-changed'], if (mode == FormatMode.dryRun) ...['-o', 'none'], + if (passLatestLanguageVersion) '--language-version=latest', // 2. Statically configured args from [FormatTool.formatterArgs] ...?configuredFormatterArgs, @@ -467,14 +476,21 @@ FormatExecution buildExecution( final dartFormatter = buildFormatProcess(formatter); Iterable args; + final dartStyleSupportsWriteArg = + formatter != Formatter.dartStyle || _dartStyleVersionSupportsWriteArg(path: path); + final passLatestLanguageVersion = + formatter == Formatter.dartStyle && !dartStyleSupportsWriteArg; if (formatter == Formatter.dartFormat) { args = buildArgsForDartFormat(dartFormatter.args, mode, argResults: context.argResults, - configuredFormatterArgs: configuredFormatterArgs); + configuredFormatterArgs: configuredFormatterArgs, + passLatestLanguageVersion: dartSemverVersion.major >= 3); } else { args = buildArgs(dartFormatter.args, mode, argResults: context.argResults, - configuredFormatterArgs: configuredFormatterArgs); + configuredFormatterArgs: configuredFormatterArgs, + passWriteArgForOverwrite: dartStyleSupportsWriteArg, + passLatestLanguageVersion: passLatestLanguageVersion); } logCommand(dartFormatter.executable, inputs.includedFiles, args, verbose: context.verbose); @@ -515,6 +531,28 @@ ProcessDeclaration buildFormatProcess([Formatter? formatter]) { } } +/// Returns `true` if the resolved `dart_style` version supports `-w`. +/// +/// `dart_style` removed support for `-w` starting in version `3.0.0`. +/// If we cannot determine a resolved version from `pubspec.lock`, we preserve +/// legacy behavior and continue passing `-w`. +bool _dartStyleVersionSupportsWriteArg({String? path}) { + final dartStyleVersion = _resolvedDependencyVersionFromPubspecLock('dart_style', path: path); + if (dartStyleVersion == null) return true; + return dartStyleVersion < Version.parse('3.0.0'); +} + +Version? _resolvedDependencyVersionFromPubspecLock(String dependency, {String? path}) { + final lockFilePath = p.join(path ?? p.current, 'pubspec.lock'); + final lockFile = File(lockFilePath); + if (!lockFile.existsSync()) return null; + + final lockDocument = loadYamlDocument(lockFile.readAsStringSync()); + final dependencyVersion = getDependencyVersion(lockDocument, dependency); + if (dependencyVersion == null) return null; + return Version.parse(dependencyVersion); +} + /// Logs the dart formatter command that will be run by [FormatTool] so that /// consumers can run it directly for debugging purposes. /// diff --git a/lib/src/utils/pubspec_lock.dart b/lib/src/utils/pubspec_lock.dart index 74d780d9..f31a55d8 100644 --- a/lib/src/utils/pubspec_lock.dart +++ b/lib/src/utils/pubspec_lock.dart @@ -17,6 +17,23 @@ String? _getPubSpecLockPackageSource( return null; } +/// Index into the pubspecLock to locate the resolved version for the given +/// package. +String? getDependencyVersion(YamlDocument pubSpecLock, String packageName) { + final contents = pubSpecLock.contents; + if (contents is YamlMap) { + final packages = contents['packages']; + if (packages is YamlMap) { + final specificDependency = packages[packageName]; + if (specificDependency is YamlMap) { + final version = specificDependency['version']; + if (version is String) return version; + } + } + } + return null; +} + /// Return a mapping of package name to dependency 'type', using the pubspec /// lock document. If a package cannot be located in the pubspec lock document, /// it will map to null. diff --git a/test/tools/fixtures/format/has_dart_style_v2/pubspec.yaml b/test/tools/fixtures/format/has_dart_style_v2/pubspec.yaml new file mode 100644 index 00000000..5c799270 --- /dev/null +++ b/test/tools/fixtures/format/has_dart_style_v2/pubspec.yaml @@ -0,0 +1,4 @@ +name: has_dart_style_v2 + +dependencies: + dart_style: ^2.0.0 diff --git a/test/tools/fixtures/format/has_dart_style_v3/pubspec.yaml b/test/tools/fixtures/format/has_dart_style_v3/pubspec.yaml new file mode 100644 index 00000000..4e47af9f --- /dev/null +++ b/test/tools/fixtures/format/has_dart_style_v3/pubspec.yaml @@ -0,0 +1,4 @@ +name: has_dart_style_v3 + +dependencies: + dart_style: ^3.0.0 diff --git a/test/tools/format_tool_test.dart b/test/tools/format_tool_test.dart index fa9d52dd..5b5f65ba 100644 --- a/test/tools/format_tool_test.dart +++ b/test/tools/format_tool_test.dart @@ -5,6 +5,7 @@ import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:dart_dev/src/dart_dev_tool.dart'; import 'package:dart_dev/src/tools/format_tool.dart'; +import 'package:dart_dev/src/utils/dart_semver_version.dart'; import 'package:dart_dev/src/utils/executables.dart' as exe; import 'package:glob/glob.dart'; import 'package:io/io.dart'; @@ -108,6 +109,21 @@ void main() { orderedEquals(['a', 'b', '-w'])); }); + test('mode=overwrite without write arg', () { + expect( + buildArgs(['a', 'b'], FormatMode.overwrite, + passWriteArgForOverwrite: false), + orderedEquals(['a', 'b'])); + }); + + test('adds latest language version flag when configured', () { + expect( + buildArgs(['a', 'b'], FormatMode.overwrite, + passWriteArgForOverwrite: false, + passLatestLanguageVersion: true), + orderedEquals(['a', 'b', '--language-version=latest'])); + }); + test('mode=dry-run', () { expect(buildArgs(['a', 'b'], FormatMode.dryRun), orderedEquals(['a', 'b', '-n'])); @@ -153,6 +169,13 @@ void main() { orderedEquals(['a', 'b', '-o', 'none', '--set-exit-if-changed'])); }); + test('adds latest language version flag when configured', () { + expect( + buildArgsForDartFormat(['a', 'b'], FormatMode.overwrite, + passLatestLanguageVersion: true), + orderedEquals(['a', 'b', '--language-version=latest'])); + }); + test('combines configured args with cli args (in that order)', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); @@ -292,7 +315,13 @@ void main() { buildExecution(context, formatter: Formatter.dartFormat); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dart); - expect(execution.formatProcess!.args, orderedEquals(['format', '.'])); + expect( + execution.formatProcess!.args, + orderedEquals([ + 'format', + if (dartSemverVersion.major >= 3) '--language-version=latest', + '.', + ])); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); @@ -327,6 +356,39 @@ void main() { expect(execution.directiveOrganization, isNull); }); + test('dart_style:format in overwrite mode passes -w for dart_style <3.0.0', + () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + defaultMode: FormatMode.overwrite, + path: 'test/tools/fixtures/format/has_dart_style_v2', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect(execution.formatProcess!.args, + orderedEquals(['run', 'dart_style:format', '-w', '.'])); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }); + + test( + 'dart_style:format in overwrite mode omits -w for dart_style >=3.0.0', + () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + defaultMode: FormatMode.overwrite, + path: 'test/tools/fixtures/format/has_dart_style_v3', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect(execution.formatProcess!.args, + orderedEquals(['run', 'dart_style:format', '--language-version=latest', '.'])); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }); + test('dartFormat with args', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); @@ -338,8 +400,15 @@ void main() { expect(execution.formatProcess!.executable, exe.dart); expect( execution.formatProcess!.args, - orderedEquals( - ['format', '--fix', '--follow-links', '--indent', '2', '.'])); + orderedEquals([ + 'format', + if (dartSemverVersion.major >= 3) '--language-version=latest', + '--fix', + '--follow-links', + '--indent', + '2', + '.', + ])); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); @@ -352,7 +421,12 @@ void main() { test('and logs the test subprocess for dart format', () { expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('${exe.dart} format .')))); + emitsThrough(infoLogOf(contains([ + exe.dart, + 'format', + if (dartSemverVersion.major >= 3) '--language-version=latest', + '.', + ].join(' '))))); buildExecution(DevToolExecutionContext(), formatter: Formatter.dartFormat); From d377e60a680356b85c3652812d677f3c19ee5a95 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Fri, 13 Mar 2026 16:00:57 -0600 Subject: [PATCH 2/6] language version is configurable --- doc/tools/format-tool.md | 18 +++++ lib/src/tools/format_tool.dart | 81 ++++++++++++++++--- lib/src/utils/format_tool_builder.dart | 19 +++++ lib/src/utils/pubspec_lock.dart | 2 +- .../dart_format_configured/lib/main.dart | 3 + .../dart_format_configured/pubspec.yaml | 10 +++ .../tool/dart_dev/config.dart | 9 +++ .../format_tool_functional_test.dart | 21 +++++ test/tools/format_tool_test.dart | 55 ++++++++++++- test/utils/format_tool_builder_test.dart | 18 ++++- 10 files changed, 221 insertions(+), 15 deletions(-) create mode 100644 test/functional/fixtures/format/language_version/dart_format_configured/lib/main.dart create mode 100644 test/functional/fixtures/format/language_version/dart_format_configured/pubspec.yaml create mode 100644 test/functional/fixtures/format/language_version/dart_format_configured/tool/dart_dev/config.dart diff --git a/doc/tools/format-tool.md b/doc/tools/format-tool.md index 0a747c9e..9802ded0 100644 --- a/doc/tools/format-tool.md +++ b/doc/tools/format-tool.md @@ -79,6 +79,24 @@ dartfmt -w --fix . ---------------------------- ``` +### Configuring the formatter language version + +For formatters that support `--language-version`, you can configure the value +used by `dart_dev`. + +```dart +// tool/dart_dev/config.dart +import 'package:dart_dev/dart_dev.dart'; + +final config = { + 'format': FormatTool() + ..languageVersion = '3.0' +}; +``` + +If `languageVersion` is not configured, `dart_dev` will use `latest` only in +the cases where it decides the formatter needs an explicit language version. + ### Excluding files from formatting ```dart diff --git a/lib/src/tools/format_tool.dart b/lib/src/tools/format_tool.dart index f94ba815..2eded101 100644 --- a/lib/src/tools/format_tool.dart +++ b/lib/src/tools/format_tool.dart @@ -74,6 +74,12 @@ class FormatTool extends DevTool { /// Run `dartfmt -h -v` or `dart format -h -v` to see all available args. List? formatterArgs; + /// The language version to pass to formatters that support + /// `--language-version`. + /// + /// If null, `latest` will be used when dart_dev decides the flag is needed. + String? languageVersion; + /// If the formatter should also organize imports and exports. /// /// By default, this is disabled. @@ -119,6 +125,7 @@ class FormatTool extends DevTool { defaultMode: defaultMode, exclude: exclude, formatter: formatter, + languageVersion: languageVersion, organizeDirectives: organizeDirectives, ); if (formatExecution.exitCode != null) { @@ -324,7 +331,7 @@ Iterable buildArgs( ArgResults? argResults, List? configuredFormatterArgs, bool passWriteArgForOverwrite = true, - bool passLatestLanguageVersion = false, + String? languageVersion, }) { final args = [ ...executableArgs, @@ -338,7 +345,7 @@ Iterable buildArgs( ], if (mode == FormatMode.overwrite && passWriteArgForOverwrite) '-w', if (mode == FormatMode.dryRun) '-n', - if (passLatestLanguageVersion) '--language-version=latest', + if (languageVersion != null) '--language-version=$languageVersion', // 2. Statically configured args from [FormatTool.formatterArgs] ...?configuredFormatterArgs, @@ -368,7 +375,7 @@ Iterable buildArgsForDartFormat( Iterable executableArgs, FormatMode? mode, {ArgResults? argResults, List? configuredFormatterArgs, - bool passLatestLanguageVersion = false}) { + String? languageVersion}) { final args = [ ...executableArgs, @@ -377,7 +384,7 @@ Iterable buildArgsForDartFormat( // 1. Mode flag(s), if configured if (mode == FormatMode.check) ...['-o', 'none', '--set-exit-if-changed'], if (mode == FormatMode.dryRun) ...['-o', 'none'], - if (passLatestLanguageVersion) '--language-version=latest', + if (languageVersion != null) '--language-version=$languageVersion', // 2. Statically configured args from [FormatTool.formatterArgs] ...?configuredFormatterArgs, @@ -421,6 +428,7 @@ FormatExecution buildExecution( FormatMode? defaultMode, List? exclude, Formatter? formatter, + String? languageVersion, bool organizeDirectives = false, String? path, }) { @@ -478,19 +486,20 @@ FormatExecution buildExecution( Iterable args; final dartStyleSupportsWriteArg = formatter != Formatter.dartStyle || _dartStyleVersionSupportsWriteArg(path: path); - final passLatestLanguageVersion = - formatter == Formatter.dartStyle && !dartStyleSupportsWriteArg; + final formatterLanguageVersion = + _formatterLanguageVersion(formatter, dartStyleSupportsWriteArg, + configuredLanguageVersion: languageVersion); if (formatter == Formatter.dartFormat) { args = buildArgsForDartFormat(dartFormatter.args, mode, argResults: context.argResults, configuredFormatterArgs: configuredFormatterArgs, - passLatestLanguageVersion: dartSemverVersion.major >= 3); + languageVersion: formatterLanguageVersion); } else { args = buildArgs(dartFormatter.args, mode, argResults: context.argResults, configuredFormatterArgs: configuredFormatterArgs, passWriteArgForOverwrite: dartStyleSupportsWriteArg, - passLatestLanguageVersion: passLatestLanguageVersion); + languageVersion: formatterLanguageVersion); } logCommand(dartFormatter.executable, inputs.includedFiles, args, verbose: context.verbose); @@ -538,8 +547,31 @@ ProcessDeclaration buildFormatProcess([Formatter? formatter]) { /// legacy behavior and continue passing `-w`. bool _dartStyleVersionSupportsWriteArg({String? path}) { final dartStyleVersion = _resolvedDependencyVersionFromPubspecLock('dart_style', path: path); - if (dartStyleVersion == null) return true; - return dartStyleVersion < Version.parse('3.0.0'); + if (dartStyleVersion != null) { + return dartStyleVersion < Version.parse('3.0.0'); + } + + final dartStyleConstraint = + _declaredDependencyConstraintFromPubspec('dart_style', path: path); + if (dartStyleConstraint != null) { + return dartStyleConstraint.allows(Version.parse('2.99.99')); + } + + return true; +} + +String? _formatterLanguageVersion( + Formatter? formatter, + bool dartStyleSupportsWriteArg, { + String? configuredLanguageVersion, +}) { + if (formatter == Formatter.dartStyle && !dartStyleSupportsWriteArg) { + return configuredLanguageVersion ?? 'latest'; + } + if (formatter == Formatter.dartFormat && dartSemverVersion.major >= 3) { + return configuredLanguageVersion ?? 'latest'; + } + return null; } Version? _resolvedDependencyVersionFromPubspecLock(String dependency, {String? path}) { @@ -553,6 +585,35 @@ Version? _resolvedDependencyVersionFromPubspecLock(String dependency, {String? p return Version.parse(dependencyVersion); } +VersionConstraint? _declaredDependencyConstraintFromPubspec( + String dependency, { + String? path, + }) { + final pubspecPath = p.join(path ?? p.current, 'pubspec.yaml'); + final pubspecFile = File(pubspecPath); + if (!pubspecFile.existsSync()) return null; + + final pubspecDocument = loadYamlDocument(pubspecFile.readAsStringSync()); + final pubspecContents = pubspecDocument.contents; + if (pubspecContents is! YamlMap) return null; + + for (final sectionName in [ + 'dependencies', + 'dev_dependencies', + 'dependency_overrides', + ]) { + final section = pubspecContents[sectionName]; + if (section is! YamlMap) continue; + + final dependencySpec = section[dependency]; + if (dependencySpec is String) { + return VersionConstraint.parse(dependencySpec); + } + } + + return null; +} + /// Logs the dart formatter command that will be run by [FormatTool] so that /// consumers can run it directly for debugging purposes. /// diff --git a/lib/src/utils/format_tool_builder.dart b/lib/src/utils/format_tool_builder.dart index 58c55460..f703adac 100644 --- a/lib/src/utils/format_tool_builder.dart +++ b/lib/src/utils/format_tool_builder.dart @@ -99,6 +99,18 @@ class FormatToolBuilder extends GeneralizingAstVisitor { KnownErrorOutcome.failedToParseOrganizeDirective); } } + + final languageVersion = getCascadeByProperty('languageVersion'); + if (languageVersion != null) { + final valueExpression = languageVersion.rightHandSide; + if (valueExpression is StringLiteral && + valueExpression.stringValue != null) { + typedFormatDevTool.languageVersion = valueExpression.stringValue; + } else { + logWarningMessageFor( + KnownErrorOutcome.failedToParseLanguageVersion); + } + } } else if (typedFormatDevTool is OverReactFormatTool) { final lineLengthAssignment = getCascadeByProperty('lineLength'); if (lineLengthAssignment != null) { @@ -131,6 +143,7 @@ enum KnownErrorOutcome { failedToReconstructFormatterArgs, failedToParseFormatterArgs, failedToParseLineLength, + failedToParseLanguageVersion, failedToParseOrganizeDirective, } @@ -161,6 +174,12 @@ This is likely because the list is not a ListLiteral. errorMessage = '''Failed to parse the line-length configuration. This is likely because assignment does not use an IntegerLiteral. +'''; + break; + case KnownErrorOutcome.failedToParseLanguageVersion: + errorMessage = '''Failed to parse the languageVersion configuration. + +This is likely because assignment does not use a StringLiteral. '''; break; case KnownErrorOutcome.failedToParseOrganizeDirective: diff --git a/lib/src/utils/pubspec_lock.dart b/lib/src/utils/pubspec_lock.dart index f31a55d8..07e35e33 100644 --- a/lib/src/utils/pubspec_lock.dart +++ b/lib/src/utils/pubspec_lock.dart @@ -27,7 +27,7 @@ String? getDependencyVersion(YamlDocument pubSpecLock, String packageName) { final specificDependency = packages[packageName]; if (specificDependency is YamlMap) { final version = specificDependency['version']; - if (version is String) return version; + if (version != null) return version.toString(); } } } diff --git a/test/functional/fixtures/format/language_version/dart_format_configured/lib/main.dart b/test/functional/fixtures/format/language_version/dart_format_configured/lib/main.dart new file mode 100644 index 00000000..24493fea --- /dev/null +++ b/test/functional/fixtures/format/language_version/dart_format_configured/lib/main.dart @@ -0,0 +1,3 @@ +void main() { + print('hello'); +} diff --git a/test/functional/fixtures/format/language_version/dart_format_configured/pubspec.yaml b/test/functional/fixtures/format/language_version/dart_format_configured/pubspec.yaml new file mode 100644 index 00000000..f1d8dcfc --- /dev/null +++ b/test/functional/fixtures/format/language_version/dart_format_configured/pubspec.yaml @@ -0,0 +1,10 @@ +name: dart_dev_test_functional_format_language_version_dart_format +version: 0.0.0 +environment: + sdk: ">=2.19.0 <4.0.0" +dev_dependencies: + dart_dev: + path: ../../../../../../ + +workiva: + disable_core_checks: true diff --git a/test/functional/fixtures/format/language_version/dart_format_configured/tool/dart_dev/config.dart b/test/functional/fixtures/format/language_version/dart_format_configured/tool/dart_dev/config.dart new file mode 100644 index 00000000..78f82894 --- /dev/null +++ b/test/functional/fixtures/format/language_version/dart_format_configured/tool/dart_dev/config.dart @@ -0,0 +1,9 @@ +import 'package:dart_dev/dart_dev.dart'; +import 'package:glob/glob.dart'; + +final config = { + 'format': FormatTool() + ..formatter = Formatter.dartFormat + ..languageVersion = '3.0' + ..exclude = [Glob('tool/**')], +}; diff --git a/test/functional/format_tool_functional_test.dart b/test/functional/format_tool_functional_test.dart index 145e60b5..36352186 100644 --- a/test/functional/format_tool_functional_test.dart +++ b/test/functional/format_tool_functional_test.dart @@ -2,6 +2,7 @@ @Timeout(Duration(seconds: 20)) import 'dart:io'; +import 'package:dart_dev/src/utils/dart_semver_version.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; @@ -39,6 +40,26 @@ void main() { isNot(equals(sourceFile.contentsAfter)), ); }); + + test('passes configured languageVersion to dart format when supported', + () async { + const projectPath = + 'test/functional/fixtures/format/language_version/dart_format_configured/'; + + final process = await runDevToolFunctionalTest('format', projectPath); + final stdoutFuture = process.stdoutStream().toList(); + + await process.shouldExit(0); + + final stdout = (await stdoutFuture).join('\n'); + final expectedCommand = [ + 'dart format', + if (dartSemverVersion.major >= 3) '--language-version=3.0', + 'lib/main.dart', + ].join(' '); + + expect(stdout, contains(expectedCommand)); + }); }); } diff --git a/test/tools/format_tool_test.dart b/test/tools/format_tool_test.dart index 5b5f65ba..a90237db 100644 --- a/test/tools/format_tool_test.dart +++ b/test/tools/format_tool_test.dart @@ -120,10 +120,18 @@ void main() { expect( buildArgs(['a', 'b'], FormatMode.overwrite, passWriteArgForOverwrite: false, - passLatestLanguageVersion: true), + languageVersion: 'latest'), orderedEquals(['a', 'b', '--language-version=latest'])); }); + test('adds configured language version flag', () { + expect( + buildArgs(['a', 'b'], FormatMode.overwrite, + passWriteArgForOverwrite: false, + languageVersion: '3.0'), + orderedEquals(['a', 'b', '--language-version=3.0'])); + }); + test('mode=dry-run', () { expect(buildArgs(['a', 'b'], FormatMode.dryRun), orderedEquals(['a', 'b', '-n'])); @@ -172,10 +180,17 @@ void main() { test('adds latest language version flag when configured', () { expect( buildArgsForDartFormat(['a', 'b'], FormatMode.overwrite, - passLatestLanguageVersion: true), + languageVersion: 'latest'), orderedEquals(['a', 'b', '--language-version=latest'])); }); + test('adds configured language version flag', () { + expect( + buildArgsForDartFormat(['a', 'b'], FormatMode.overwrite, + languageVersion: '3.0'), + orderedEquals(['a', 'b', '--language-version=3.0'])); + }); + test('combines configured args with cli args (in that order)', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); @@ -389,6 +404,23 @@ void main() { expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); + test('dart_style:format uses configured language version for dart_style >=3.0.0', + () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + languageVersion: '3.0', + defaultMode: FormatMode.overwrite, + path: 'test/tools/fixtures/format/has_dart_style_v3', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect(execution.formatProcess!.args, + orderedEquals(['run', 'dart_style:format', '--language-version=3.0', '.'])); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }); + test('dartFormat with args', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); @@ -412,6 +444,25 @@ void main() { expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); + test('with dartFormat and configured language version', () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartFormat, + languageVersion: '3.0', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect( + execution.formatProcess!.args, + orderedEquals([ + 'format', + if (dartSemverVersion.major >= 3) '--language-version=3.0', + '.', + ])); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }); + test('and logs the test subprocess by default', () { expect(Logger.root.onRecord, emitsThrough(infoLogOf(contains('${exe.dartfmt} .')))); diff --git a/test/utils/format_tool_builder_test.dart b/test/utils/format_tool_builder_test.dart index 9f555544..5a2d1134 100644 --- a/test/utils/format_tool_builder_test.dart +++ b/test/utils/format_tool_builder_test.dart @@ -92,6 +92,18 @@ void main() { expect((visitor.formatDevTool as FormatTool).formatterArgs, orderedEquals(['-l', '120'])); }); + + test('detects languageVersion', () { + final visitor = FormatToolBuilder(); + + parseString(content: formatToolCascadeSrc(languageVersion: '3.0')) + .unit + .accept(visitor); + + expect(visitor.formatDevTool, isNotNull); + expect(visitor.formatDevTool, isA()); + expect((visitor.formatDevTool as FormatTool).languageVersion, '3.0'); + }); }); }); @@ -136,7 +148,8 @@ final config = { }; '''; -String formatToolCascadeSrc({String formatter = 'dartfmt'}) => +String formatToolCascadeSrc( + {String formatter = 'dartfmt', String? languageVersion}) => '''import 'package:dart_dev/dart_dev.dart'; import 'package:glob/glob.dart'; @@ -144,7 +157,8 @@ final config = { ...coreConfig, 'format': FormatTool() ..formatter = Formatter.$formatter - ..formatterArgs = ['-l', '120'], + ..formatterArgs = ['-l', '120'] +${languageVersion != null ? " ..languageVersion = '$languageVersion'" : ''}, }; '''; From cb3e16e2be365e34cb0076631f92683f9cc68acc Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Fri, 13 Mar 2026 16:06:21 -0600 Subject: [PATCH 3/6] dart 3 format --- lib/src/core_config.dart | 8 +- lib/src/dart_dev_runner.dart | 23 +- lib/src/dart_dev_tool.dart | 48 +- lib/src/events.dart | 7 +- lib/src/executable.dart | 104 +-- lib/src/tools/analyze_tool.dart | 73 +- lib/src/tools/compound_tool.dart | 220 +++--- lib/src/tools/format_tool.dart | 238 +++--- lib/src/tools/function_tool.dart | 19 +- lib/src/tools/over_react_format_tool.dart | 15 +- lib/src/tools/process_tool.dart | 75 +- lib/src/tools/test_tool.dart | 166 +++-- lib/src/tools/tuneup_check_tool.dart | 30 +- lib/src/tools/webdev_serve_tool.dart | 96 ++- .../utils/assert_no_args_after_separator.dart | 15 +- ...t_no_positional_args_before_separator.dart | 6 +- ...itional_args_nor_args_after_separator.dart | 16 +- lib/src/utils/cached_pubspec.dart | 9 +- lib/src/utils/dart_dev_paths.dart | 9 +- lib/src/utils/ensure_process_exit.dart | 7 +- lib/src/utils/exit_process_signals.dart | 6 +- lib/src/utils/format_tool_builder.dart | 34 +- ...obal_package_is_active_and_compatible.dart | 24 +- lib/src/utils/logging.dart | 23 +- .../organize_directives.dart | 36 +- .../organize_directives_in_paths.dart | 7 +- lib/src/utils/parse_flag_from_args.dart | 9 +- lib/src/utils/parse_imports.dart | 6 +- lib/src/utils/process_declaration.dart | 8 +- lib/src/utils/pubspec_lock.dart | 14 +- .../utils/run_process_and_ensure_exit.dart | 14 +- .../utils/start_process_and_ensure_exit.dart | 14 +- test/functional.dart | 67 +- .../analyze_tool_functional_test.dart | 8 +- test/functional/documentation_test.dart | 28 +- .../format_tool_functional_test.dart | 37 +- .../null_safety_functional_test.dart | 16 +- test/log_matchers.dart | 14 +- test/tools/analyze_tool_test.dart | 251 ++++--- test/tools/compound_tool_test.dart | 47 +- test/tools/format_tool_test.dart | 680 +++++++++++------- test/tools/function_tool_test.dart | 34 +- test/tools/process_tool_test.dart | 70 +- test/tools/shared_tool_tests.dart | 6 +- test/tools/test_tool_test.dart | 615 +++++++++------- test/tools/tuneup_check_tool_test.dart | 86 ++- test/tools/webdev_serve_tool_test.dart | 402 ++++++----- test/utils.dart | 36 +- test/utils/arg_results_utils_test.dart | 4 +- ...positional_args_before_separator_test.dart | 21 +- test/utils/dart_dev_paths_test.dart | 12 +- test/utils/format_tool_builder_test.dart | 68 +- test/utils/get_dart_version_comment_test.dart | 33 +- .../organize_directives_test.dart | 12 +- test/utils/parse_imports_test.dart | 23 +- test/utils/rest_args_with_separator_test.dart | 16 +- 56 files changed, 2433 insertions(+), 1532 deletions(-) diff --git a/lib/src/core_config.dart b/lib/src/core_config.dart index 0df31897..ceef7655 100644 --- a/lib/src/core_config.dart +++ b/lib/src/core_config.dart @@ -6,7 +6,7 @@ library dart_dev.src.core_config; import 'package:dart_dev/dart_dev.dart'; Map get coreConfig => { - 'analyze': AnalyzeTool(), - 'format': FormatTool(), - 'test': TestTool(), - }; + 'analyze': AnalyzeTool(), + 'format': FormatTool(), + 'test': TestTool(), +}; diff --git a/lib/src/dart_dev_runner.dart b/lib/src/dart_dev_runner.dart index c23f6323..fcee8e6d 100644 --- a/lib/src/dart_dev_runner.dart +++ b/lib/src/dart_dev_runner.dart @@ -11,7 +11,7 @@ import 'utils/version.dart'; class DartDevRunner extends CommandRunner { DartDevRunner(Map commands) - : super('dart_dev', 'Dart tool runner.') { + : super('dart_dev', 'Dart tool runner.') { // For backwards-compatibility, only add the `clean` command if it doesn't // conflict with any configured command. if (!commands.containsKey('clean')) { @@ -32,10 +32,17 @@ class DartDevRunner extends CommandRunner { }); argParser - ..addFlag('verbose', - abbr: 'v', negatable: false, help: 'Enables verbose logging.') - ..addFlag('version', - negatable: false, help: 'Prints the dart_dev version.'); + ..addFlag( + 'verbose', + abbr: 'v', + negatable: false, + help: 'Enables verbose logging.', + ) + ..addFlag( + 'version', + negatable: false, + help: 'Prints the dart_dev version.', + ); } @override @@ -60,7 +67,8 @@ class DartDevRunner extends CommandRunner { final exitCode = (await super.run(args)) ?? 0; stopwatch.stop(); await events.commandComplete( - events.CommandResult(args.toList(), exitCode, stopwatch.elapsed)); + events.CommandResult(args.toList(), exitCode, stopwatch.elapsed), + ); return exitCode; } } @@ -71,6 +79,7 @@ class CommandNameMismatch implements Exception { CommandNameMismatch(this.actual, this.expected); @override - String toString() => 'CommandNameMismatch: ' + String toString() => + 'CommandNameMismatch: ' 'Expected a "$expected" command but got one named "$actual".'; } diff --git a/lib/src/dart_dev_tool.dart b/lib/src/dart_dev_tool.dart index b2bf5174..c5658191 100644 --- a/lib/src/dart_dev_tool.dart +++ b/lib/src/dart_dev_tool.dart @@ -12,14 +12,21 @@ abstract class DevTool { DevTool(); factory DevTool.fromFunction( - FutureOr Function(DevToolExecutionContext context) function, - {ArgParser? argParser}) => - FunctionTool(function, argParser: argParser); - - factory DevTool.fromProcess(String executable, List args, - {ProcessStartMode? mode, String? workingDirectory}) => - ProcessTool(executable, args, - mode: mode, workingDirectory: workingDirectory); + FutureOr Function(DevToolExecutionContext context) function, { + ArgParser? argParser, + }) => FunctionTool(function, argParser: argParser); + + factory DevTool.fromProcess( + String executable, + List args, { + ProcessStartMode? mode, + String? workingDirectory, + }) => ProcessTool( + executable, + args, + mode: mode, + workingDirectory: workingDirectory, + ); /// The argument parser for this tool, if needed. /// @@ -79,12 +86,12 @@ abstract class DevTool { /// or not global verbose mode is enabled, and the [usageException] utility /// function from [Command]. class DevToolExecutionContext { - DevToolExecutionContext( - {this.argResults, - this.commandName, - void Function(String message)? usageException, - this.verbose = false}) - : _usageException = usageException; + DevToolExecutionContext({ + this.argResults, + this.commandName, + void Function(String message)? usageException, + this.verbose = false, + }) : _usageException = usageException; final void Function(String message)? _usageException; @@ -113,13 +120,12 @@ class DevToolExecutionContext { String? commandName, void Function(String message)? usageException, bool? verbose, - }) => - DevToolExecutionContext( - argResults: argResults ?? this.argResults, - commandName: commandName ?? this.commandName, - usageException: usageException ?? this.usageException, - verbose: verbose ?? this.verbose, - ); + }) => DevToolExecutionContext( + argResults: argResults ?? this.argResults, + commandName: commandName ?? this.commandName, + usageException: usageException ?? this.usageException, + verbose: verbose ?? this.verbose, + ); /// Calling this will throw a [UsageException] with [message] that should be /// caught by [CommandRunner] and used to set the exit code accordingly and diff --git a/lib/src/events.dart b/lib/src/events.dart index 403df573..4f437005 100644 --- a/lib/src/events.dart +++ b/lib/src/events.dart @@ -1,8 +1,11 @@ import 'dart:async'; Future commandComplete(CommandResult result) async { - await Future.wait(_commandCompleteListeners - .map((listener) => Future.value(listener(result)))); + await Future.wait( + _commandCompleteListeners.map( + (listener) => Future.value(listener(result)), + ), + ); } void onCommandComplete(FutureOr Function(CommandResult result) callback) { diff --git a/lib/src/executable.dart b/lib/src/executable.dart index 531fbfa3..aee242a7 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart @@ -41,14 +41,19 @@ Future run(List args) async { final oldDevDartExists = File(_paths.legacyConfig).existsSync(); if (!configExists) { - log.fine('No custom `${_paths.config}` file found; ' - 'using default config.'); + log.fine( + 'No custom `${_paths.config}` file found; ' + 'using default config.', + ); } if (oldDevDartExists) { - log.warning(yellow.wrap( + log.warning( + yellow.wrap( 'dart_dev v3 now expects configuration to be at `${_paths.config}`,\n' 'but `${_paths.legacyConfig}` still exists. View the guide to see how to upgrade:\n' - 'https://github.com/Workiva/dart_dev/blob/master/doc/v3-upgrade-guide.md')); + 'https://github.com/Workiva/dart_dev/blob/master/doc/v3-upgrade-guide.md', + ), + ); } if (args.contains('hackFastFormat') && !oldDevDartExists) { @@ -57,13 +62,10 @@ Future run(List args) async { } final processArgs = generateRunScript(); - final process = await Process.start( - processArgs.first, - [ - if (processArgs.length > 1) ...processArgs.sublist(1), - ...args, - ], - mode: ProcessStartMode.inheritStdio); + final process = await Process.start(processArgs.first, [ + if (processArgs.length > 1) ...processArgs.sublist(1), + ...args, + ], mode: ProcessStartMode.inheritStdio); ensureProcessExit(process); exitCode = await process.exitCode; } @@ -75,17 +77,19 @@ Future handleFastFormat(List args) async { final configFile = File(_paths.config); if (configFile.existsSync()) { final toolBuilder = FormatToolBuilder(); - parseString(content: configFile.readAsStringSync()) - .unit - .accept(toolBuilder); + parseString( + content: configFile.readAsStringSync(), + ).unit.accept(toolBuilder); formatTool = toolBuilder .formatDevTool; // could be null if no custom `format` entry found if (formatTool == null && toolBuilder.failedToDetectAKnownFormatter) { exitCode = ExitCode.config.code; - log.severe('Failed to reconstruct the format tool\'s configuration.\n\n' - 'This is likely because dart_dev expects either the FormatTool class or the\n' - 'OverReactFormatTool class.'); + log.severe( + 'Failed to reconstruct the format tool\'s configuration.\n\n' + 'This is likely because dart_dev expects either the FormatTool class or the\n' + 'OverReactFormatTool class.', + ); return; } } @@ -116,27 +120,31 @@ bool _allPackagesAreImportedImmutably(Iterable packageNames) { File pubspecLockFile = File('pubspec.lock'); if (!pubspecLockFile.existsSync()) return false; final pubSpecLock = loadYamlDocument(pubspecLockFile.readAsStringSync()); - return getDependencySources(pubSpecLock, packageNames) - .values - .every((source) => source == 'hosted' || source == 'git'); + return getDependencySources( + pubSpecLock, + packageNames, + ).values.every((source) => source == 'hosted' || source == 'git'); } /// Return null iff it is not possible to account for all /// recompilation-necessitating factors in the digest. String? _computeRunScriptDigest() { - final currentPackageName = - Pubspec.parse(File('pubspec.yaml').readAsStringSync()).name; + final currentPackageName = Pubspec.parse( + File('pubspec.yaml').readAsStringSync(), + ).name; final configFile = File(_paths.config); var configHasRelativeImports = false; if (configFile.existsSync()) { final configImports = parseImports(configFile.readAsStringSync()); configHasRelativeImports = configImports.any((i) => !i.contains(':')); - final configHasSamePackageImports = - configImports.any((i) => i.startsWith('package:$currentPackageName')); + final configHasSamePackageImports = configImports.any( + (i) => i.startsWith('package:$currentPackageName'), + ); if (configHasSamePackageImports) { log.fine( - 'Skipping compilation because ${_paths.config} imports from its own package.'); + 'Skipping compilation because ${_paths.config} imports from its own package.', + ); // If the config imports from its own source files, we don't have a way of // efficiently tracking changes that would require recompilation of this @@ -148,7 +156,8 @@ String? _computeRunScriptDigest() { final packageNames = computePackageNamesFromImports(configImports); if (!_allPackagesAreImportedImmutably(packageNames)) { log.fine( - 'Skipping compilation because ${_paths.config} imports non-hosted packages.'); + 'Skipping compilation because ${_paths.config} imports non-hosted packages.', + ); _deleteRunExecutableAndDigest(); return null; } @@ -162,11 +171,14 @@ String? _computeRunScriptDigest() { if (packageConfig.existsSync()) ...packageConfig.readAsBytesSync(), if (configFile.existsSync()) ...configFile.readAsBytesSync(), if (configHasRelativeImports) - for (final file in Glob('tool/**.dart', recursive: true) - .listSync() - .whereType() - .where((f) => p.canonicalize(f.path) != p.canonicalize(_paths.config)) - .sortedBy((f) => f.path)) + for (final file + in Glob('tool/**.dart', recursive: true) + .listSync() + .whereType() + .where( + (f) => p.canonicalize(f.path) != p.canonicalize(_paths.config), + ) + .sortedBy((f) => f.path)) ...file.readAsBytesSync(), ]); return base64.encode(digest.bytes); @@ -190,9 +202,12 @@ List generateRunScript() { // Generate a digest of inputs to the run script. We use this to determine // whether we need to recompile the executable. String? encodedDigest; - logTimedSync(log, 'Computing run script digest', - () => encodedDigest = _computeRunScriptDigest(), - level: Level.FINE); + logTimedSync( + log, + 'Computing run script digest', + () => encodedDigest = _computeRunScriptDigest(), + level: Level.FINE, + ); if (encodedDigest != null && (!runExecutableDigest.existsSync() || @@ -210,7 +225,7 @@ List generateRunScript() { 'exe', _paths.runScript, '-o', - _paths.runExecutable + _paths.runExecutable, ]; final result = Process.runSync(Platform.executable, args); if (result.exitCode == 0) { @@ -220,7 +235,8 @@ List generateRunScript() { // Compilation failed. Dump some logs for debugging, but note to the // user that dart_dev should still work. log.warning( - 'Could not compile run script; dart_dev will continue without precompilation.'); + 'Could not compile run script; dart_dev will continue without precompilation.', + ); log.fine('CMD: ${Platform.executable} ${args.join(" ")}'); log.fine('STDOUT:\n${result.stdout}'); log.fine('STDERR:\n${result.stderr}'); @@ -258,9 +274,10 @@ void main(List args) async { } Future runWithConfig( - // ignore: library_private_types_in_public_api - List args, - _ConfigGetter configGetter) async { + // ignore: library_private_types_in_public_api + List args, + _ConfigGetter configGetter, +) async { attachLoggerToStdio(args); try { @@ -278,8 +295,10 @@ Future runWithConfig( stderr ..writeln('Invalid "${_paths.config}" in ${p.absolute(p.current)}') ..writeln() - ..writeln('It should provide a `Map config;` getter,' - ' but it either does not exist or threw unexpectedly:') + ..writeln( + 'It should provide a `Map config;` getter,' + ' but it either does not exist or threw unexpectedly:', + ) ..writeln(' $error') ..writeln() ..writeln('For more info: https://github.com/Workiva/dart_dev'); @@ -307,7 +326,8 @@ Future runWithConfig( DevTool chooseDefaultFormatTool({String? path}) { final pubspec = cachedPubspec(path: path); const orf = 'over_react_format'; - final hasOverReactFormat = pubspec.dependencies.containsKey(orf) || + final hasOverReactFormat = + pubspec.dependencies.containsKey(orf) || pubspec.devDependencies.containsKey(orf) || pubspec.dependencyOverrides.containsKey(orf); diff --git a/lib/src/tools/analyze_tool.dart b/lib/src/tools/analyze_tool.dart index d5ace692..37987d92 100644 --- a/lib/src/tools/analyze_tool.dart +++ b/lib/src/tools/analyze_tool.dart @@ -66,9 +66,12 @@ class AnalyzeTool extends DevTool { @override final ArgParser argParser = ArgParser() - ..addOption('analyzer-args', - help: 'Args to pass to the "dartanalyzer" or "dart analyze" process.\n' - 'Run "dartanalyzer -h -v" or `dart analyze -h -v" to see all available options.'); + ..addOption( + 'analyzer-args', + help: + 'Args to pass to the "dartanalyzer" or "dart analyze" process.\n' + 'Run "dartanalyzer -h -v" or `dart analyze -h -v" to see all available options.', + ); @override String? description = 'Run static analysis on dart files in this package.'; @@ -76,14 +79,16 @@ class AnalyzeTool extends DevTool { @override FutureOr run([DevToolExecutionContext? context]) { return runProcessAndEnsureExit( - buildProcess( - context ?? DevToolExecutionContext(), - configuredAnalyzerArgs: analyzerArgs, - include: include, - useDartAnalyze: - !dartVersionHasDartanalyzer ? true : useDartAnalyze ?? false, - ), - log: _log); + buildProcess( + context ?? DevToolExecutionContext(), + configuredAnalyzerArgs: analyzerArgs, + include: include, + useDartAnalyze: !dartVersionHasDartanalyzer + ? true + : useDartAnalyze ?? false, + ), + log: _log, + ); } } @@ -97,11 +102,12 @@ class AnalyzeTool extends DevTool { /// /// If [verbose] is true and the verbose flag (`-v`) is not already included, it /// will be added. -Iterable buildArgs( - {ArgResults? argResults, - List? configuredAnalyzerArgs, - bool useDartAnalyze = false, - bool verbose = false}) { +Iterable buildArgs({ + ArgResults? argResults, + List? configuredAnalyzerArgs, + bool useDartAnalyze = false, + bool verbose = false, +}) { final args = [ // Combine all args that should be passed through to the analyzer in // this order: @@ -172,23 +178,32 @@ ProcessDeclaration buildProcess( if (argResults != null) { final analyzerUsed = useDartAnalyze ? 'dart analyze' : 'dartanalyzer'; assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName, - usageFooter: - 'Arguments can be passed to the "$analyzerUsed" process via ' - 'the --analyzer-args option.'); + argResults, + context.usageException, + commandName: context.commandName, + usageFooter: + 'Arguments can be passed to the "$analyzerUsed" process via ' + 'the --analyzer-args option.', + ); } var executable = useDartAnalyze ? exe.dart : exe.dartanalyzer; final args = buildArgs( - argResults: context.argResults, - configuredAnalyzerArgs: configuredAnalyzerArgs, - verbose: context.verbose, - useDartAnalyze: useDartAnalyze); + argResults: context.argResults, + configuredAnalyzerArgs: configuredAnalyzerArgs, + verbose: context.verbose, + useDartAnalyze: useDartAnalyze, + ); final entrypoints = buildEntrypoints(include: include, root: path); - logCommand(args, entrypoints, - verbose: context.verbose, useDartAnalyzer: useDartAnalyze); - return ProcessDeclaration(executable, [...args, ...entrypoints], - mode: ProcessStartMode.inheritStdio); + logCommand( + args, + entrypoints, + verbose: context.verbose, + useDartAnalyzer: useDartAnalyze, + ); + return ProcessDeclaration(executable, [ + ...args, + ...entrypoints, + ], mode: ProcessStartMode.inheritStdio); } /// Logs the `dartanalyzer` or `dart analyze` command that will be run by [AnalyzeTool] so that diff --git a/lib/src/tools/compound_tool.dart b/lib/src/tools/compound_tool.dart index 6095920e..fd93cb89 100644 --- a/lib/src/tools/compound_tool.dart +++ b/lib/src/tools/compound_tool.dart @@ -43,9 +43,9 @@ ArgResults takeOptionArgs(ArgParser parser, ArgResults results) => /// ..addTool(TestTool(), argMapper: takeAllArgs) /// }; ArgResults takeAllArgs(ArgParser parser, ArgResults results) => parser.parse([ - ...optionArgsOnly(results, allowedOptions: parser.options.keys), - ...restArgsWithSeparator(results), - ]); + ...optionArgsOnly(results, allowedOptions: parser.options.keys), + ...restArgsWithSeparator(results), +]); class CompoundTool extends DevTool with CompoundToolMixin {} @@ -80,8 +80,9 @@ mixin CompoundToolMixin on DevTool { int? code = 0; for (var i = 0; i < _specs.length; i++) { if (!shouldRunTool(_specs[i].when, code)) continue; - final newCode = - await _specs[i].tool.run(contextForTool(context, _specs[i])); + final newCode = await _specs[i].tool.run( + contextForTool(context, _specs[i]), + ); _log.fine('Step ${i + 1}/${_specs.length} done (code: $newCode)\n'); if (code == 0) { code = newCode; @@ -92,8 +93,10 @@ mixin CompoundToolMixin on DevTool { } } -List optionArgsOnly(ArgResults results, - {Iterable? allowedOptions}) { +List optionArgsOnly( + ArgResults results, { + Iterable? allowedOptions, +}) { final args = []; for (final option in results.options) { if (!results.wasParsed(option)) continue; @@ -111,7 +114,9 @@ List optionArgsOnly(ArgResults results, } DevToolExecutionContext contextForTool( - DevToolExecutionContext baseContext, DevToolSpec spec) { + DevToolExecutionContext baseContext, + DevToolSpec spec, +) { final argResults = baseContext.argResults; if (argResults == null) return baseContext; @@ -152,34 +157,40 @@ class CompoundArgParser implements ArgParser { for (final option in argParser.options.values) { if (option.isFlag) { - _compoundParser.addFlag(option.name, - abbr: option.abbr, - help: option.help, - defaultsTo: option.defaultsTo, - negatable: option.negatable!, - callback: (bool value) => option.callback?.call(value), - hide: option.hide); + _compoundParser.addFlag( + option.name, + abbr: option.abbr, + help: option.help, + defaultsTo: option.defaultsTo, + negatable: option.negatable!, + callback: (bool value) => option.callback?.call(value), + hide: option.hide, + ); } else if (option.isMultiple) { - _compoundParser.addMultiOption(option.name, - abbr: option.abbr, - help: option.help, - valueHelp: option.valueHelp, - allowed: option.allowed, - allowedHelp: option.allowedHelp, - defaultsTo: option.defaultsTo, - callback: (List values) => option.callback?.call(values), - splitCommas: option.splitCommas, - hide: option.hide); + _compoundParser.addMultiOption( + option.name, + abbr: option.abbr, + help: option.help, + valueHelp: option.valueHelp, + allowed: option.allowed, + allowedHelp: option.allowedHelp, + defaultsTo: option.defaultsTo, + callback: (List values) => option.callback?.call(values), + splitCommas: option.splitCommas, + hide: option.hide, + ); } else if (option.isSingle) { - _compoundParser.addOption(option.name, - abbr: option.abbr, - help: option.help, - valueHelp: option.valueHelp, - allowed: option.allowed, - allowedHelp: option.allowedHelp, - defaultsTo: option.defaultsTo, - callback: (String? value) => option.callback?.call(value), - hide: option.hide); + _compoundParser.addOption( + option.name, + abbr: option.abbr, + help: option.help, + valueHelp: option.valueHelp, + allowed: option.allowed, + allowedHelp: option.allowedHelp, + defaultsTo: option.defaultsTo, + callback: (String? value) => option.callback?.call(value), + hide: option.hide, + ); } } } @@ -227,8 +238,10 @@ class CompoundArgParser implements ArgParser { final buffer = StringBuffer() ..writeln() - ..writeln('This command is composed of multiple parts, each of which has ' - 'its own options.'); + ..writeln( + 'This command is composed of multiple parts, each of which has ' + 'its own options.', + ); for (final parser in _subParsers) { buffer ..writeln() @@ -259,71 +272,80 @@ class CompoundArgParser implements ArgParser { _compoundParser.addCommand(name, parser); @override - void addFlag(String name, - {String? abbr, - String? help, - bool? defaultsTo = false, - bool negatable = true, - void Function(bool value)? callback, - bool hide = false, - bool hideNegatedUsage = false, - List aliases = const []}) => - _compoundParser.addFlag(name, - abbr: abbr, - help: help, - defaultsTo: defaultsTo, - negatable: negatable, - // TODO once lower bound of args is 2.7.0 (requires Dart SDK 3.3.0), which adds hideNegatedUsage, forward this arg - // hideNegatedUsage: hideNegatedUsage, - callback: callback, - hide: hide, - aliases: aliases); + void addFlag( + String name, { + String? abbr, + String? help, + bool? defaultsTo = false, + bool negatable = true, + void Function(bool value)? callback, + bool hide = false, + bool hideNegatedUsage = false, + List aliases = const [], + }) => _compoundParser.addFlag( + name, + abbr: abbr, + help: help, + defaultsTo: defaultsTo, + negatable: negatable, + // TODO once lower bound of args is 2.7.0 (requires Dart SDK 3.3.0), which adds hideNegatedUsage, forward this arg + // hideNegatedUsage: hideNegatedUsage, + callback: callback, + hide: hide, + aliases: aliases, + ); @override - void addMultiOption(String name, - {String? abbr, - String? help, - String? valueHelp, - Iterable? allowed, - Map? allowedHelp, - Iterable? defaultsTo, - void Function(List values)? callback, - bool splitCommas = true, - bool hide = false, - List aliases = const []}) => - _compoundParser.addMultiOption(name, - abbr: abbr, - help: help, - valueHelp: valueHelp, - allowed: allowed, - allowedHelp: allowedHelp, - defaultsTo: defaultsTo, - callback: callback, - splitCommas: splitCommas, - hide: hide, - aliases: aliases); + void addMultiOption( + String name, { + String? abbr, + String? help, + String? valueHelp, + Iterable? allowed, + Map? allowedHelp, + Iterable? defaultsTo, + void Function(List values)? callback, + bool splitCommas = true, + bool hide = false, + List aliases = const [], + }) => _compoundParser.addMultiOption( + name, + abbr: abbr, + help: help, + valueHelp: valueHelp, + allowed: allowed, + allowedHelp: allowedHelp, + defaultsTo: defaultsTo, + callback: callback, + splitCommas: splitCommas, + hide: hide, + aliases: aliases, + ); @override - void addOption(String name, - {String? abbr, - String? help, - String? valueHelp, - Iterable? allowed, - Map? allowedHelp, - String? defaultsTo, - void Function(String?)? callback, - bool mandatory = false, - bool hide = false, - List aliases = const []}) => - _compoundParser.addOption(name, - abbr: abbr, - help: help, - valueHelp: valueHelp, - allowed: allowed, - allowedHelp: allowedHelp, - defaultsTo: defaultsTo, - callback: callback, - mandatory: mandatory, - hide: hide, - aliases: aliases); + void addOption( + String name, { + String? abbr, + String? help, + String? valueHelp, + Iterable? allowed, + Map? allowedHelp, + String? defaultsTo, + void Function(String?)? callback, + bool mandatory = false, + bool hide = false, + List aliases = const [], + }) => _compoundParser.addOption( + name, + abbr: abbr, + help: help, + valueHelp: valueHelp, + allowed: allowed, + allowedHelp: allowedHelp, + defaultsTo: defaultsTo, + callback: callback, + mandatory: mandatory, + hide: hide, + aliases: aliases, + ); } diff --git a/lib/src/tools/format_tool.dart b/lib/src/tools/format_tool.dart index 2eded101..5202e41b 100644 --- a/lib/src/tools/format_tool.dart +++ b/lib/src/tools/format_tool.dart @@ -92,23 +92,33 @@ class FormatTool extends DevTool { @override final ArgParser argParser = ArgParser() ..addSeparator('======== Formatter Mode') - ..addFlag('overwrite', - abbr: 'w', - negatable: false, - help: 'Overwrite input files with formatted output.') - ..addFlag('dry-run', - abbr: 'n', - negatable: false, - help: 'Show which files would be modified but make no changes.') - ..addFlag('check', - abbr: 'c', - negatable: false, - help: 'Check if changes need to be made and set the exit code ' - 'accordingly.\nImplies "--dry-run" and "--set-exit-if-changed".') + ..addFlag( + 'overwrite', + abbr: 'w', + negatable: false, + help: 'Overwrite input files with formatted output.', + ) + ..addFlag( + 'dry-run', + abbr: 'n', + negatable: false, + help: 'Show which files would be modified but make no changes.', + ) + ..addFlag( + 'check', + abbr: 'c', + negatable: false, + help: + 'Check if changes need to be made and set the exit code ' + 'accordingly.\nImplies "--dry-run" and "--set-exit-if-changed".', + ) ..addSeparator('======== Other Options') - ..addOption('formatter-args', - help: 'Args to pass to the "dartfmt" or "dart format" process.\n' - 'Run "dartfmt -h -v" or "dart format -h -v" to see all available options.'); + ..addOption( + 'formatter-args', + help: + 'Args to pass to the "dartfmt" or "dart format" process.\n' + 'Run "dartfmt -h -v" or "dart format -h -v" to see all available options.', + ); @override String? description = 'Format dart files in this package.'; @@ -150,8 +160,11 @@ class FormatTool extends DevTool { } // Similar to listSync() but does not recurse into hidden directories. - static List _listSyncWithoutHidden(Directory dir, - {required bool recursive, required bool followLinks}) { + static List _listSyncWithoutHidden( + Directory dir, { + required bool recursive, + required bool followLinks, + }) { var allEntries = []; dir.listSync(recursive: false, followLinks: followLinks).forEach((element) { final basename = p.basename(element.path); @@ -159,8 +172,13 @@ class FormatTool extends DevTool { allEntries.add(element); if (element is Directory) { - allEntries.addAll(_listSyncWithoutHidden(element, - recursive: recursive, followLinks: followLinks)); + allEntries.addAll( + _listSyncWithoutHidden( + element, + recursive: recursive, + followLinks: followLinks, + ), + ); } }); return allEntries; @@ -186,7 +204,8 @@ class FormatTool extends DevTool { }) { if (collapseDirectories != null) { _log.warning( - 'ignoring deprecated option "collapseDirectories": argv limitations are now solved by parallel invocations'); + 'ignoring deprecated option "collapseDirectories": argv limitations are now solved by parallel invocations', + ); } expandCwd ??= false; @@ -201,8 +220,11 @@ class FormatTool extends DevTool { final dir = Directory(root ?? '.'); - for (final entry in _listSyncWithoutHidden(dir, - recursive: true, followLinks: followLinks)) { + for (final entry in _listSyncWithoutHidden( + dir, + recursive: true, + followLinks: followLinks, + )) { final filename = p.relative(entry.path, from: dir.path); _log.finest('== Processing relative $filename ==\n'); @@ -229,10 +251,12 @@ class FormatTool extends DevTool { } class FormatterInputs { - FormatterInputs(this.includedFiles, - {@deprecated this.excludedFiles, - @deprecated this.hiddenDirectories, - @deprecated this.skippedLinks}); + FormatterInputs( + this.includedFiles, { + @deprecated this.excludedFiles, + @deprecated this.hiddenDirectories, + @deprecated this.skippedLinks, + }); final Set includedFiles; @@ -259,11 +283,11 @@ class FormatterInputs { /// output of step 1 (an instance of this class) with very simple unit tests. class FormatExecution { FormatExecution.exitEarly(this.exitCode) - : formatProcess = null, - directiveOrganization = null; + : formatProcess = null, + directiveOrganization = null; FormatExecution.process(this.formatProcess, [this.directiveOrganization]) - : exitCode = null; + : exitCode = null; /// If non-null, the execution is already complete and the [FormatTool] should /// exit with this code. @@ -339,10 +363,7 @@ Iterable buildArgs( // Combine all args that should be passed through to the dartfmt in this // order: // 1. Mode flag(s), if configured - if (mode == FormatMode.check) ...[ - '-n', - '--set-exit-if-changed', - ], + if (mode == FormatMode.check) ...['-n', '--set-exit-if-changed'], if (mode == FormatMode.overwrite && passWriteArgForOverwrite) '-w', if (mode == FormatMode.dryRun) '-n', if (languageVersion != null) '--language-version=$languageVersion', @@ -372,10 +393,12 @@ Iterable buildArgs( /// Finally, if [verbose] is true and the verbose flag (`-v`) is not already /// included, it will be added. Iterable buildArgsForDartFormat( - Iterable executableArgs, FormatMode? mode, - {ArgResults? argResults, - List? configuredFormatterArgs, - String? languageVersion}) { + Iterable executableArgs, + FormatMode? mode, { + ArgResults? argResults, + List? configuredFormatterArgs, + String? languageVersion, +}) { final args = [ ...executableArgs, @@ -434,81 +457,101 @@ FormatExecution buildExecution( }) { FormatMode? mode; - final useRestForInputs = (context.argResults?.rest.isNotEmpty ?? false) && + final useRestForInputs = + (context.argResults?.rest.isNotEmpty ?? false) && context.commandName == 'hackFastFormat'; final argResults = context.argResults; if (argResults != null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - allowRest: useRestForInputs, - commandName: context.commandName, - usageFooter: - 'Arguments can be passed to the "dartfmt" or "dart format" process via the ' - '--formatter-args option.'); + argResults, + context.usageException, + allowRest: useRestForInputs, + commandName: context.commandName, + usageFooter: + 'Arguments can be passed to the "dartfmt" or "dart format" process via the ' + '--formatter-args option.', + ); mode = validateAndParseMode(argResults, context.usageException); } mode ??= defaultMode; if (formatter == Formatter.dartStyle && !packageIsImmediateDependency('dart_style', path: path)) { - _log.severe(red.wrap('Cannot run "dart_style:format".\n')! + - yellow.wrap('You must either have a dependency on "dart_style" in ' + _log.severe( + red.wrap('Cannot run "dart_style:format".\n')! + + yellow.wrap( + 'You must either have a dependency on "dart_style" in ' 'pubspec.yaml or configure the format tool to use "dartfmt" ' 'instead.\n' 'Either add "dart_style" to your pubspec.yaml or configure the ' - 'format tool to use "dartfmt" instead.')!); + 'format tool to use "dartfmt" instead.', + )!, + ); return FormatExecution.exitEarly(ExitCode.config.code); } if (context.commandName == 'hackFastFormat' && !useRestForInputs) { - context.usageException('"hackFastFormat" must specify targets to format.\n' - 'hackFastFormat should only be used to format specific files. ' - 'Running the command over an entire project may format files that ' - 'would be excluded using the standard "format" command.'); + context.usageException( + '"hackFastFormat" must specify targets to format.\n' + 'hackFastFormat should only be used to format specific files. ' + 'Running the command over an entire project may format files that ' + 'would be excluded using the standard "format" command.', + ); } final inputs = useRestForInputs ? FormatterInputs({...?context.argResults?.rest}) - : FormatTool.getInputs( - exclude: exclude, - root: path, - ); + : FormatTool.getInputs(exclude: exclude, root: path); if (inputs.includedFiles.isEmpty) { - _log.severe('The formatter cannot run because no inputs could be found ' - 'with the configured includes and excludes.\n' - 'Please modify the excludes and/or includes in "tool/dart_dev/config.dart".'); + _log.severe( + 'The formatter cannot run because no inputs could be found ' + 'with the configured includes and excludes.\n' + 'Please modify the excludes and/or includes in "tool/dart_dev/config.dart".', + ); return FormatExecution.exitEarly(ExitCode.config.code); } final dartFormatter = buildFormatProcess(formatter); Iterable args; final dartStyleSupportsWriteArg = - formatter != Formatter.dartStyle || _dartStyleVersionSupportsWriteArg(path: path); - final formatterLanguageVersion = - _formatterLanguageVersion(formatter, dartStyleSupportsWriteArg, - configuredLanguageVersion: languageVersion); + formatter != Formatter.dartStyle || + _dartStyleVersionSupportsWriteArg(path: path); + final formatterLanguageVersion = _formatterLanguageVersion( + formatter, + dartStyleSupportsWriteArg, + configuredLanguageVersion: languageVersion, + ); if (formatter == Formatter.dartFormat) { - args = buildArgsForDartFormat(dartFormatter.args, mode, - argResults: context.argResults, + args = buildArgsForDartFormat( + dartFormatter.args, + mode, + argResults: context.argResults, configuredFormatterArgs: configuredFormatterArgs, - languageVersion: formatterLanguageVersion); + languageVersion: formatterLanguageVersion, + ); } else { - args = buildArgs(dartFormatter.args, mode, - argResults: context.argResults, - configuredFormatterArgs: configuredFormatterArgs, - passWriteArgForOverwrite: dartStyleSupportsWriteArg, - languageVersion: formatterLanguageVersion); + args = buildArgs( + dartFormatter.args, + mode, + argResults: context.argResults, + configuredFormatterArgs: configuredFormatterArgs, + passWriteArgForOverwrite: dartStyleSupportsWriteArg, + languageVersion: formatterLanguageVersion, + ); } - logCommand(dartFormatter.executable, inputs.includedFiles, args, - verbose: context.verbose); - - final formatProcess = ProcessDeclaration( + logCommand( dartFormatter.executable, - [...args, ...inputs.includedFiles], - mode: ProcessStartMode.inheritStdio, + inputs.includedFiles, + args, + verbose: context.verbose, ); + + final formatProcess = ProcessDeclaration(dartFormatter.executable, [ + ...args, + ...inputs.includedFiles, + ], mode: ProcessStartMode.inheritStdio); DirectiveOrganization? directiveOrganization; if (organizeDirectives) { directiveOrganization = DirectiveOrganization( @@ -516,10 +559,7 @@ FormatExecution buildExecution( check: mode == FormatMode.check, ); } - return FormatExecution.process( - formatProcess, - directiveOrganization, - ); + return FormatExecution.process(formatProcess, directiveOrganization); } /// Returns a representation of the process that will be run by [FormatTool] @@ -546,13 +586,18 @@ ProcessDeclaration buildFormatProcess([Formatter? formatter]) { /// If we cannot determine a resolved version from `pubspec.lock`, we preserve /// legacy behavior and continue passing `-w`. bool _dartStyleVersionSupportsWriteArg({String? path}) { - final dartStyleVersion = _resolvedDependencyVersionFromPubspecLock('dart_style', path: path); + final dartStyleVersion = _resolvedDependencyVersionFromPubspecLock( + 'dart_style', + path: path, + ); if (dartStyleVersion != null) { return dartStyleVersion < Version.parse('3.0.0'); } - final dartStyleConstraint = - _declaredDependencyConstraintFromPubspec('dart_style', path: path); + final dartStyleConstraint = _declaredDependencyConstraintFromPubspec( + 'dart_style', + path: path, + ); if (dartStyleConstraint != null) { return dartStyleConstraint.allows(Version.parse('2.99.99')); } @@ -574,7 +619,10 @@ String? _formatterLanguageVersion( return null; } -Version? _resolvedDependencyVersionFromPubspecLock(String dependency, {String? path}) { +Version? _resolvedDependencyVersionFromPubspecLock( + String dependency, { + String? path, +}) { final lockFilePath = p.join(path ?? p.current, 'pubspec.lock'); final lockFile = File(lockFilePath); if (!lockFile.existsSync()) return null; @@ -586,9 +634,9 @@ Version? _resolvedDependencyVersionFromPubspecLock(String dependency, {String? p } VersionConstraint? _declaredDependencyConstraintFromPubspec( - String dependency, { - String? path, - }) { + String dependency, { + String? path, +}) { final pubspecPath = p.join(path ?? p.current, 'pubspec.yaml'); final pubspecFile = File(pubspecPath); if (!pubspecFile.existsSync()) return null; @@ -620,8 +668,11 @@ VersionConstraint? _declaredDependencyConstraintFromPubspec( /// Unless [verbose] is true, the list of inputs will be abbreviated to avoid an /// unnecessarily long log. void logCommand( - String executable, Iterable inputs, Iterable args, - {bool verbose = false}) { + String executable, + Iterable inputs, + Iterable args, { + bool verbose = false, +}) { final exeAndArgs = '$executable ${args.join(' ')}'.trim(); if (inputs.length <= 5 || verbose) { logSubprocessHeader(_log, '$exeAndArgs ${inputs.join(' ')}'); @@ -639,14 +690,17 @@ void logCommand( /// /// If none of the mode flags were enabled, this returns `null`. FormatMode? validateAndParseMode( - ArgResults argResults, void Function(String message) usageException) { + ArgResults argResults, + void Function(String message) usageException, +) { final check = argResults['check'] ?? false; final dryRun = argResults['dry-run'] ?? false; final overwrite = argResults['overwrite'] ?? false; if (check && dryRun && overwrite) { usageException( - 'Cannot use --check and --dry-run and --overwrite at the same time.'); + 'Cannot use --check and --dry-run and --overwrite at the same time.', + ); } if (check && dryRun) { usageException('Cannot use --check and --dry-run at the same time.'); diff --git a/lib/src/tools/function_tool.dart b/lib/src/tools/function_tool.dart index a777346a..a7445fcc 100644 --- a/lib/src/tools/function_tool.dart +++ b/lib/src/tools/function_tool.dart @@ -13,10 +13,10 @@ import '../utils/assert_no_positional_args_nor_args_after_separator.dart'; /// Use [DevTool.fromFunction] to create [FunctionTool] instances. class FunctionTool extends DevTool { FunctionTool( - FutureOr Function(DevToolExecutionContext context) function, - {ArgParser? argParser}) - : _argParser = argParser, - _function = function; + FutureOr Function(DevToolExecutionContext context) function, { + ArgParser? argParser, + }) : _argParser = argParser, + _function = function; final FutureOr Function(DevToolExecutionContext context) _function; @@ -35,8 +35,10 @@ class FunctionTool extends DevTool { if (argResults != null) { if (argParser == null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName); + argResults, + context.usageException, + commandName: context.commandName, + ); } } final exitCode = await _function(context); @@ -44,8 +46,9 @@ class FunctionTool extends DevTool { return exitCode; } Logger('DartFunctionTool').warning( - '${context.commandName != null ? 'The ${context.commandName}' : 'This'}' - ' command did not return an exit code.'); + '${context.commandName != null ? 'The ${context.commandName}' : 'This'}' + ' command did not return an exit code.', + ); return ExitCode.software.code; } } diff --git a/lib/src/tools/over_react_format_tool.dart b/lib/src/tools/over_react_format_tool.dart index 1e33463c..32b09f45 100644 --- a/lib/src/tools/over_react_format_tool.dart +++ b/lib/src/tools/over_react_format_tool.dart @@ -28,10 +28,11 @@ class OverReactFormatTool extends DevTool { Iterable paths = context.argResults?.rest ?? []; if (paths.isEmpty) { context.usageException.call( - '"hackFastFormat" must specify targets to format.\n' - 'hackFastFormat should only be used to format specific files. ' - 'Running the command over an entire project may format files that ' - 'would be excluded using the standard "format" command.'); + '"hackFastFormat" must specify targets to format.\n' + 'hackFastFormat should only be used to format specific files. ' + 'Running the command over an entire project may format files that ' + 'would be excluded using the standard "format" command.', + ); } final args = [ 'run', @@ -39,8 +40,10 @@ class OverReactFormatTool extends DevTool { if (lineLength != null) '--line-length=$lineLength', if (organizeDirectives == true) '--organize-directives', ]; - final process = ProcessDeclaration(exe.dart, [...args, ...paths], - mode: ProcessStartMode.inheritStdio); + final process = ProcessDeclaration(exe.dart, [ + ...args, + ...paths, + ], mode: ProcessStartMode.inheritStdio); logCommand('dart', paths, args, verbose: context.verbose); return runProcessAndEnsureExit(process); } diff --git a/lib/src/tools/process_tool.dart b/lib/src/tools/process_tool.dart index ca5a8151..90900c0a 100644 --- a/lib/src/tools/process_tool.dart +++ b/lib/src/tools/process_tool.dart @@ -27,12 +27,15 @@ final _log = Logger('Process'); /// It is also possible to run this tool directly in a dart script: /// ProcessTool(exe, args).run(); class ProcessTool extends DevTool { - ProcessTool(String executable, List args, - {ProcessStartMode? mode, String? workingDirectory}) - : _args = args, - _executable = executable, - _mode = mode, - _workingDirectory = workingDirectory; + ProcessTool( + String executable, + List args, { + ProcessStartMode? mode, + String? workingDirectory, + }) : _args = args, + _executable = executable, + _mode = mode, + _workingDirectory = workingDirectory; final List _args; final String _executable; @@ -48,14 +51,21 @@ class ProcessTool extends DevTool { final argResults = context.argResults; if (argResults != null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName); + argResults, + context.usageException, + commandName: context.commandName, + ); } logSubprocessHeader(_log, '$_executable ${_args.join(' ')}'); _process = await startProcessAndEnsureExit( - ProcessDeclaration(_executable, _args, - mode: _mode, workingDirectory: _workingDirectory), - log: _log); + ProcessDeclaration( + _executable, + _args, + mode: _mode, + workingDirectory: _workingDirectory, + ), + log: _log, + ); return _process!.exitCode; } } @@ -67,15 +77,17 @@ class BackgroundProcessTool { final Duration? _delayAfterStart; final String? _workingDirectory; - BackgroundProcessTool(String executable, List args, - {ProcessStartMode? mode, - Duration? delayAfterStart, - String? workingDirectory}) - : _args = args, - _executable = executable, - _mode = mode, - _delayAfterStart = delayAfterStart, - _workingDirectory = workingDirectory; + BackgroundProcessTool( + String executable, + List args, { + ProcessStartMode? mode, + Duration? delayAfterStart, + String? workingDirectory, + }) : _args = args, + _executable = executable, + _mode = mode, + _delayAfterStart = delayAfterStart, + _workingDirectory = workingDirectory; Process? get process => _process; Process? _process; @@ -90,17 +102,24 @@ class BackgroundProcessTool { final argResults = context.argResults; if (argResults != null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName); + argResults, + context.usageException, + commandName: context.commandName, + ); } logSubprocessHeader(_log, '$_executable ${_args.join(' ')}'); - final mode = _mode ?? + final mode = + _mode ?? (context.verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal); - _process = await Process.start(_executable, _args, - mode: mode, workingDirectory: _workingDirectory); + _process = await Process.start( + _executable, + _args, + mode: mode, + workingDirectory: _workingDirectory, + ); ensureProcessExit(_process!); unawaited(_process!.exitCode.then((_) => _processHasExited = true)); @@ -121,8 +140,10 @@ class BackgroundProcessTool { final argResults = context.argResults; if (argResults != null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName); + argResults, + context.usageException, + commandName: context.commandName, + ); } _log.info('Stopping: $_executable ${_args.join(' ')}'); _process?.kill(); diff --git a/lib/src/tools/test_tool.dart b/lib/src/tools/test_tool.dart index 103a8bdc..f58d1e5f 100644 --- a/lib/src/tools/test_tool.dart +++ b/lib/src/tools/test_tool.dart @@ -50,48 +50,66 @@ class TestTool extends DevTool { @override final ArgParser argParser = ArgParser() ..addSeparator('======== Selecting Tests') - ..addMultiOption('name', - abbr: 'n', - help: 'A substring of the name of the test to run.\n' - 'Regular expression syntax is supported.\n' - 'If passed multiple times, tests must match all substrings.', - splitCommas: false) - ..addMultiOption('plain-name', - abbr: 'N', - help: 'A plain-text substring of the name of the test to run.\n' - 'If passed multiple times, tests must match all substrings.', - splitCommas: false) + ..addMultiOption( + 'name', + abbr: 'n', + help: + 'A substring of the name of the test to run.\n' + 'Regular expression syntax is supported.\n' + 'If passed multiple times, tests must match all substrings.', + splitCommas: false, + ) + ..addMultiOption( + 'plain-name', + abbr: 'N', + help: + 'A plain-text substring of the name of the test to run.\n' + 'If passed multiple times, tests must match all substrings.', + splitCommas: false, + ) ..addSeparator('======== Running Tests') - ..addMultiOption('preset', - abbr: 'P', help: 'The configuration preset(s) to use.') - ..addFlag('release', - help: 'Build with release mode defaults for builders.\n' - 'This only applies in projects that run tests with build_runner.') + ..addMultiOption( + 'preset', + abbr: 'P', + help: 'The configuration preset(s) to use.', + ) + ..addFlag( + 'release', + help: + 'Build with release mode defaults for builders.\n' + 'This only applies in projects that run tests with build_runner.', + ) ..addSeparator('======== Output') - ..addOption('reporter', - help: 'The runner used to print test results.', - allowed: [ - 'compact', - 'expanded', - 'json' - ], - allowedHelp: { - 'compact': 'A single line, updated continuously.', - 'expanded': 'A separate line for each update.', - 'json': 'A machine-readable format (see https://goo.gl/gBsV1a).' - }) + ..addOption( + 'reporter', + help: 'The runner used to print test results.', + allowed: ['compact', 'expanded', 'json'], + allowedHelp: { + 'compact': 'A single line, updated continuously.', + 'expanded': 'A separate line for each update.', + 'json': 'A machine-readable format (see https://goo.gl/gBsV1a).', + }, + ) ..addSeparator('======== Other Options') - ..addOption('test-stdout', - help: 'Write the test process stdout to this file path.') - ..addOption('test-args', - help: 'Args to pass to the test runner process.\n' - 'Run "dart test -h" to see all available options.') - ..addOption('build-args', - help: 'Args to pass to the build runner process.\n' - 'Run "dart run build_runner test -h" to see all available ' - 'options.\n' - 'Note: these args are only applicable if the current project ' - 'depends on "build_test".'); + ..addOption( + 'test-stdout', + help: 'Write the test process stdout to this file path.', + ) + ..addOption( + 'test-args', + help: + 'Args to pass to the test runner process.\n' + 'Run "dart test -h" to see all available options.', + ) + ..addOption( + 'build-args', + help: + 'Args to pass to the build runner process.\n' + 'Run "dart run build_runner test -h" to see all available ' + 'options.\n' + 'Note: these args are only applicable if the current project ' + 'depends on "build_test".', + ); /// The args to pass to the `dart run build_runner test` process that will be /// run by this command when the current project depends on `build_test`. @@ -117,8 +135,11 @@ class TestTool extends DevTool { @override FutureOr run([DevToolExecutionContext? context]) async { context ??= DevToolExecutionContext(); - final execution = buildExecution(context, - configuredBuildArgs: buildArgs, configuredTestArgs: testArgs); + final execution = buildExecution( + context, + configuredBuildArgs: buildArgs, + configuredTestArgs: testArgs, + ); return execution.exitCode ?? await runProcessAndEnsureExit(execution.process!, log: _log); } @@ -214,8 +235,10 @@ List buildArgs({ '--reporter=${singleOptionValue(argResults, 'reporter')!}', // 3. The -n|--name, -N|--plain-name, and -P|--preset options ...?multiOptionValue(argResults, 'name')?.map((v) => '--name=$v'), - ...?multiOptionValue(argResults, 'plain-name') - ?.map((v) => '--plain-name=$v'), + ...?multiOptionValue( + argResults, + 'plain-name', + )?.map((v) => '--plain-name=$v'), ...?multiOptionValue(argResults, 'preset')?.map((v) => '--preset=$v'), // 4. Args passed to --test-args ...?splitSingleOptionValue(argResults, 'test-args'), @@ -271,51 +294,66 @@ TestExecution buildExecution( String? path, }) { final argResults = context.argResults; - final hasBuildRunner = - packageIsImmediateDependency('build_runner', path: path); + final hasBuildRunner = packageIsImmediateDependency( + 'build_runner', + path: path, + ); final hasBuildTest = packageIsImmediateDependency('build_test', path: path); final useBuildRunner = hasBuildRunner && hasBuildTest; if (!useBuildRunner && argResults != null && argResults['build-args'] != null) { - context.usageException('Can only use --build-args in a project that has a ' - 'direct dependency on both "build_runner" and "build_test" in the ' - 'pubspec.yaml.'); + context.usageException( + 'Can only use --build-args in a project that has a ' + 'direct dependency on both "build_runner" and "build_test" in the ' + 'pubspec.yaml.', + ); } if (!useBuildRunner && (flagValue(argResults, 'release') ?? false)) { - _log.warning(yellow.wrap('The --release flag is only applicable in ' + _log.warning( + yellow.wrap( + 'The --release flag is only applicable in ' 'projects that run tests with build_runner, and this project does not.\n' - 'It will have no effect.')); + 'It will have no effect.', + ), + ); } if (!packageIsImmediateDependency('test', path: path)) { - _log.severe(red.wrap('Cannot run tests.\n')! + - yellow - .wrap('You must have a dependency on "test" in pubspec.yaml.\n')!); + _log.severe( + red.wrap('Cannot run tests.\n')! + + yellow.wrap( + 'You must have a dependency on "test" in pubspec.yaml.\n', + )!, + ); return TestExecution.exitEarly(ExitCode.config.code); } if (!useBuildRunner && configuredBuildArgs != null && configuredBuildArgs.isNotEmpty) { - _log.severe('This project is configured to run tests with buildArgs, but ' - 'is missing a direct dependency on "build_runner" or "build_test".\n' - 'Either remove these buildArgs in tool/dart_dev/config.dart or ensure ' - 'both "build_runner" and "build_test" are dependencies in the ' - 'pubspec.yaml.'); + _log.severe( + 'This project is configured to run tests with buildArgs, but ' + 'is missing a direct dependency on "build_runner" or "build_test".\n' + 'Either remove these buildArgs in tool/dart_dev/config.dart or ensure ' + 'both "build_runner" and "build_test" are dependencies in the ' + 'pubspec.yaml.', + ); return TestExecution.exitEarly(ExitCode.config.code); } final args = buildArgs( - argResults: argResults, - configuredBuildArgs: configuredBuildArgs, - configuredTestArgs: configuredTestArgs, - useBuildRunner: useBuildRunner, - verbose: context.verbose); + argResults: argResults, + configuredBuildArgs: configuredBuildArgs, + configuredTestArgs: configuredTestArgs, + useBuildRunner: useBuildRunner, + verbose: context.verbose, + ); logSubprocessHeader(_log, 'dart ${args.join(' ')}'.trim()); return TestExecution.process( - ProcessDeclaration(exe.dart, args, mode: ProcessStartMode.inheritStdio)); + ProcessDeclaration(exe.dart, args, mode: ProcessStartMode.inheritStdio), + ); } // NOTE: This currently depends on https://github.com/dart-lang/build/pull/2445 diff --git a/lib/src/tools/tuneup_check_tool.dart b/lib/src/tools/tuneup_check_tool.dart index 8b314fb2..bc57fced 100644 --- a/lib/src/tools/tuneup_check_tool.dart +++ b/lib/src/tools/tuneup_check_tool.dart @@ -54,13 +54,16 @@ class TuneupCheckTool extends DevTool { ..addFlag('ignore-infos', help: 'Ignore any info level issues.'); @override - String? description = 'Run static analysis on dart files in this package ' + String? description = + 'Run static analysis on dart files in this package ' 'using the tuneup tool.'; @override FutureOr run([DevToolExecutionContext? context]) async { - final execution = buildExecution(context ?? DevToolExecutionContext(), - configuredIgnoreInfos: ignoreInfos); + final execution = buildExecution( + context ?? DevToolExecutionContext(), + configuredIgnoreInfos: ignoreInfos, + ); return execution.exitCode ?? await runProcessAndEnsureExit(execution.process!, log: _log); } @@ -101,7 +104,8 @@ Iterable buildArgs({ bool? configuredIgnoreInfos, bool verbose = false, }) { - var ignoreInfos = (configuredIgnoreInfos ?? false) || + var ignoreInfos = + (configuredIgnoreInfos ?? false) || (flagValue(argResults, 'ignore-infos') ?? false); return [ 'run', @@ -136,14 +140,19 @@ TuneupExecution buildExecution( final argResults = context.argResults; if (argResults != null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName); + argResults, + context.usageException, + commandName: context.commandName, + ); } if (!packageIsImmediateDependency('tuneup', path: path)) { - _log.severe(red.wrap('Cannot run "tuneup check".\n')! + - yellow.wrap( - 'You must have a dependency on "tuneup" in pubspec.yaml.\n')!); + _log.severe( + red.wrap('Cannot run "tuneup check".\n')! + + yellow.wrap( + 'You must have a dependency on "tuneup" in pubspec.yaml.\n', + )!, + ); return TuneupExecution.exitEarly(ExitCode.config.code); } @@ -154,5 +163,6 @@ TuneupExecution buildExecution( ).toList(); logSubprocessHeader(_log, 'dart ${args.join(' ')}'); return TuneupExecution.process( - ProcessDeclaration(exe.dart, args, mode: ProcessStartMode.inheritStdio)); + ProcessDeclaration(exe.dart, args, mode: ProcessStartMode.inheritStdio), + ); } diff --git a/lib/src/tools/webdev_serve_tool.dart b/lib/src/tools/webdev_serve_tool.dart index cc3179bc..d8a2326c 100644 --- a/lib/src/tools/webdev_serve_tool.dart +++ b/lib/src/tools/webdev_serve_tool.dart @@ -64,27 +64,40 @@ class WebdevServeTool extends DevTool { @override final ArgParser argParser = ArgParser() - ..addFlag('release', - abbr: 'r', help: 'Build with release mode defaults for builders.') + ..addFlag( + 'release', + abbr: 'r', + help: 'Build with release mode defaults for builders.', + ) ..addSeparator('======== Other Options') - ..addOption('webdev-args', - help: 'Args to pass to the webdev serve process.\n' - 'Run "dart pub global run webdev serve -h -v" to see all available ' - 'options.') - ..addOption('build-args', - help: 'Args to pass to the build runner process.\n' - 'Run "dart run build_runner build -h -v" to see all available ' - 'options.'); + ..addOption( + 'webdev-args', + help: + 'Args to pass to the webdev serve process.\n' + 'Run "dart pub global run webdev serve -h -v" to see all available ' + 'options.', + ) + ..addOption( + 'build-args', + help: + 'Args to pass to the build runner process.\n' + 'Run "dart run build_runner build -h -v" to see all available ' + 'options.', + ); @override - String? description = 'Run a local web development server and a file system ' + String? description = + 'Run a local web development server and a file system ' 'watcher that rebuilds on changes.'; @override FutureOr run([DevToolExecutionContext? context]) async { context ??= DevToolExecutionContext(); - final execution = buildExecution(context, - configuredBuildArgs: buildArgs, configuredWebdevArgs: webdevArgs); + final execution = buildExecution( + context, + configuredBuildArgs: buildArgs, + configuredWebdevArgs: webdevArgs, + ); return execution.exitCode ?? await runProcessAndEnsureExit(execution.process!, log: _log); } @@ -133,11 +146,12 @@ class WebdevServeExecution { /// /// If [verbose] is true, both the webdev args and the build args portions of /// the returned list will include the `-v` verbose flag. -List buildArgs( - {ArgResults? argResults, - List? configuredBuildArgs, - List? configuredWebdevArgs, - bool verbose = false}) { +List buildArgs({ + ArgResults? argResults, + List? configuredBuildArgs, + List? configuredWebdevArgs, + bool verbose = false, +}) { final webdevArgs = [ // Combine all args that should be passed through to the webdev serve // process in this order: @@ -207,32 +221,44 @@ WebdevServeExecution buildExecution( final argResults = context.argResults; if (argResults != null) { assertNoPositionalArgsNorArgsAfterSeparator( - argResults, context.usageException, - commandName: context.commandName, - usageFooter: 'Arguments can be passed to the webdev process via the ' - '--webdev-args option.\n' - 'Arguments can be passed to the build process via the --build-args ' - 'option.'); + argResults, + context.usageException, + commandName: context.commandName, + usageFooter: + 'Arguments can be passed to the webdev process via the ' + '--webdev-args option.\n' + 'Arguments can be passed to the build process via the --build-args ' + 'option.', + ); } final webdevVersion = dartSemverVersion.major == 2 ? '^2.0.0' : '^3.0.0'; if (!globalPackageIsActiveAndCompatible( - 'webdev', VersionConstraint.parse(webdevVersion), - environment: environment)) { - _log.severe(red.wrap( - '${styleBold.wrap('webdev serve')} could not run for this project.\n')! + - yellow.wrap('You must have `webdev` globally activated:\n' - ' dart pub global activate webdev ${webdevVersion}')!); + 'webdev', + VersionConstraint.parse(webdevVersion), + environment: environment, + )) { + _log.severe( + red.wrap( + '${styleBold.wrap('webdev serve')} could not run for this project.\n', + )! + + yellow.wrap( + 'You must have `webdev` globally activated:\n' + ' dart pub global activate webdev ${webdevVersion}', + )!, + ); return WebdevServeExecution.exitEarly(ExitCode.config.code); } final args = buildArgs( - argResults: argResults, - configuredBuildArgs: configuredBuildArgs, - configuredWebdevArgs: configuredWebdevArgs, - verbose: context.verbose); + argResults: argResults, + configuredBuildArgs: configuredBuildArgs, + configuredWebdevArgs: configuredWebdevArgs, + verbose: context.verbose, + ); logSubprocessHeader(_log, 'dart ${args.join(' ')}'.trim()); return WebdevServeExecution.process( - ProcessDeclaration(exe.dart, args, mode: ProcessStartMode.inheritStdio)); + ProcessDeclaration(exe.dart, args, mode: ProcessStartMode.inheritStdio), + ); } diff --git a/lib/src/utils/assert_no_args_after_separator.dart b/lib/src/utils/assert_no_args_after_separator.dart index d11f87ec..bccc1d8b 100644 --- a/lib/src/utils/assert_no_args_after_separator.dart +++ b/lib/src/utils/assert_no_args_after_separator.dart @@ -3,11 +3,16 @@ import 'package:args/args.dart'; import 'has_args_after_separator.dart'; void assertNoArgsAfterSeparator( - ArgResults argResults, void Function(String msg) usageException, - {String? commandName, String? usageFooter}) { + ArgResults argResults, + void Function(String msg) usageException, { + String? commandName, + String? usageFooter, +}) { if (hasArgsAfterSeparator(argResults)) { - usageException('${commandName != null ? 'The "$commandName"' : 'This'} ' - 'command does not support args after a separator.' - '${usageFooter != null ? '\n$usageFooter' : ''}'); + usageException( + '${commandName != null ? 'The "$commandName"' : 'This'} ' + 'command does not support args after a separator.' + '${usageFooter != null ? '\n$usageFooter' : ''}', + ); } } diff --git a/lib/src/utils/assert_no_positional_args_before_separator.dart b/lib/src/utils/assert_no_positional_args_before_separator.dart index 55deb2af..460ca446 100644 --- a/lib/src/utils/assert_no_positional_args_before_separator.dart +++ b/lib/src/utils/assert_no_positional_args_before_separator.dart @@ -9,7 +9,9 @@ void assertNoPositionalArgs( bool beforeSeparator = false, }) { if (hasAnyPositionalArgsBeforeSeparator(argResults)) { - usageException('The "$name" command does not support positional args' - '${beforeSeparator ? ' before the `--` separator' : ''}.\n'); + usageException( + 'The "$name" command does not support positional args' + '${beforeSeparator ? ' before the `--` separator' : ''}.\n', + ); } } diff --git a/lib/src/utils/assert_no_positional_args_nor_args_after_separator.dart b/lib/src/utils/assert_no_positional_args_nor_args_after_separator.dart index aab207ff..4bcc1c81 100644 --- a/lib/src/utils/assert_no_positional_args_nor_args_after_separator.dart +++ b/lib/src/utils/assert_no_positional_args_nor_args_after_separator.dart @@ -3,12 +3,18 @@ import 'package:args/args.dart'; import 'has_args_after_separator.dart'; void assertNoPositionalArgsNorArgsAfterSeparator( - ArgResults argResults, void Function(String msg) usageException, - {String? commandName, String? usageFooter, bool allowRest = false}) { + ArgResults argResults, + void Function(String msg) usageException, { + String? commandName, + String? usageFooter, + bool allowRest = false, +}) { if ((argResults.rest.isNotEmpty && !allowRest) || hasArgsAfterSeparator(argResults)) { - usageException('${commandName != null ? 'The "$commandName"' : 'This'} ' - 'command does not support positional args nor args after a separator.' - '${usageFooter != null ? '\n$usageFooter' : ''}'); + usageException( + '${commandName != null ? 'The "$commandName"' : 'This'} ' + 'command does not support positional args nor args after a separator.' + '${usageFooter != null ? '\n$usageFooter' : ''}', + ); } } diff --git a/lib/src/utils/cached_pubspec.dart b/lib/src/utils/cached_pubspec.dart index a68e3b52..e45765e0 100644 --- a/lib/src/utils/cached_pubspec.dart +++ b/lib/src/utils/cached_pubspec.dart @@ -6,9 +6,12 @@ import 'package:pubspec_parse/pubspec_parse.dart'; Pubspec cachedPubspec({String? path}) { final sourceUrl = p.join(path ?? p.current, 'pubspec.yaml'); return _cachedPubspecs.putIfAbsent( - sourceUrl, - () => Pubspec.parse(File(sourceUrl).readAsStringSync(), - sourceUrl: Uri.parse(sourceUrl))); + sourceUrl, + () => Pubspec.parse( + File(sourceUrl).readAsStringSync(), + sourceUrl: Uri.parse(sourceUrl), + ), + ); } final _cachedPubspecs = {}; diff --git a/lib/src/utils/dart_dev_paths.dart b/lib/src/utils/dart_dev_paths.dart index 6547cdd3..f405d615 100644 --- a/lib/src/utils/dart_dev_paths.dart +++ b/lib/src/utils/dart_dev_paths.dart @@ -8,7 +8,8 @@ class DartDevPaths { DartDevPaths({p.Context? context}) : _context = context ?? p.context; String cache([String? subPath]) => _context.normalize( - _context.joinAll([..._cacheParts, if (subPath != null) subPath])); + _context.joinAll([..._cacheParts, if (subPath != null) subPath]), + ); String get _cacheForDart => p.url.joinAll(_cacheParts); @@ -21,9 +22,9 @@ class DartDevPaths { final List _configParts = ['tool', 'dart_dev', 'config.dart']; String get configFromRunScriptForDart => p.url.relative( - p.url.absolute(configForDart), - from: p.url.absolute(_cacheForDart), - ); + p.url.absolute(configForDart), + from: p.url.absolute(_cacheForDart), + ); String get packageConfig => _context.join('.dart_tool', 'package_config.json'); diff --git a/lib/src/utils/ensure_process_exit.dart b/lib/src/utils/ensure_process_exit.dart index 844e8231..887fd930 100644 --- a/lib/src/utils/ensure_process_exit.dart +++ b/lib/src/utils/ensure_process_exit.dart @@ -15,8 +15,11 @@ import 'exit_process_signals.dart'; /// process will be forwarded via [process.kill]. This is only needed if the /// given [process] was started in either the [ProcessStartMode.detached] or /// [ProcessStartMode.detachedWithStdio] modes. -void ensureProcessExit(Process process, - {bool forwardExitSignals = false, Logger? log}) { +void ensureProcessExit( + Process process, { + bool forwardExitSignals = false, + Logger? log, +}) { final signalsSub = exitProcessSignals.listen((signal) async { log?.info('Waiting for subprocess to exit...'); if (forwardExitSignals) { diff --git a/lib/src/utils/exit_process_signals.dart b/lib/src/utils/exit_process_signals.dart index 9d1ee034..34c29bb4 100644 --- a/lib/src/utils/exit_process_signals.dart +++ b/lib/src/utils/exit_process_signals.dart @@ -5,5 +5,7 @@ import 'package:async/async.dart'; Stream get exitProcessSignals => Platform.isWindows ? ProcessSignal.sigint.watch() - : StreamGroup.merge( - [ProcessSignal.sigterm.watch(), ProcessSignal.sigint.watch()]); + : StreamGroup.merge([ + ProcessSignal.sigterm.watch(), + ProcessSignal.sigint.watch(), + ]); diff --git a/lib/src/utils/format_tool_builder.dart b/lib/src/utils/format_tool_builder.dart index f703adac..c52cffdf 100644 --- a/lib/src/utils/format_tool_builder.dart +++ b/lib/src/utils/format_tool_builder.dart @@ -48,9 +48,9 @@ class FormatToolBuilder extends GeneralizingAstVisitor { return formatterInvocation.cascadeSections .whereType() .firstWhereOrNull((assignment) { - final lhs = assignment.leftHandSide; - return lhs is PropertyAccess && lhs.propertyName.name == property; - }); + final lhs = assignment.leftHandSide; + return lhs is PropertyAccess && lhs.propertyName.name == property; + }); } final typedFormatDevTool = formatDevTool; @@ -59,8 +59,9 @@ class FormatToolBuilder extends GeneralizingAstVisitor { if (formatter != null) { final formatterType = formatter.rightHandSide; if (formatterType is PrefixedIdentifier) { - final detectedFormatter = - detectFormatterForFormatTool(formatterType.identifier); + final detectedFormatter = detectFormatterForFormatTool( + formatterType.identifier, + ); if (detectedFormatter != null) { typedFormatDevTool.formatter = detectedFormatter; } @@ -82,7 +83,8 @@ class FormatToolBuilder extends GeneralizingAstVisitor { if (stringArgs.length < argList.elements.length) { logWarningMessageFor( - KnownErrorOutcome.failedToReconstructFormatterArgs); + KnownErrorOutcome.failedToReconstructFormatterArgs, + ); } } else { logWarningMessageFor(KnownErrorOutcome.failedToParseFormatterArgs); @@ -96,7 +98,8 @@ class FormatToolBuilder extends GeneralizingAstVisitor { typedFormatDevTool.organizeDirectives = valueExpression.value; } else { logWarningMessageFor( - KnownErrorOutcome.failedToParseOrganizeDirective); + KnownErrorOutcome.failedToParseOrganizeDirective, + ); } } @@ -108,7 +111,8 @@ class FormatToolBuilder extends GeneralizingAstVisitor { typedFormatDevTool.languageVersion = valueExpression.stringValue; } else { logWarningMessageFor( - KnownErrorOutcome.failedToParseLanguageVersion); + KnownErrorOutcome.failedToParseLanguageVersion, + ); } } } else if (typedFormatDevTool is OverReactFormatTool) { @@ -122,15 +126,17 @@ class FormatToolBuilder extends GeneralizingAstVisitor { } } - final organizeDirectivesAssignment = - getCascadeByProperty('organizeDirectives'); + final organizeDirectivesAssignment = getCascadeByProperty( + 'organizeDirectives', + ); if (organizeDirectivesAssignment != null) { final valueExpression = organizeDirectivesAssignment.rightHandSide; if (valueExpression is BooleanLiteral) { typedFormatDevTool.organizeDirectives = valueExpression.value; } else { logWarningMessageFor( - KnownErrorOutcome.failedToParseOrganizeDirective); + KnownErrorOutcome.failedToParseOrganizeDirective, + ); } } } @@ -220,8 +226,10 @@ DevTool? detectFormatter(AstNode formatterNode) { if (formatterNode is MethodInvocation) { detectedFormatterName = formatterNode.methodName.name; } else if (formatterNode is CascadeExpression) { - detectedFormatterName = - formatterNode.target.toSource().replaceAll(RegExp('[()]'), ''); + detectedFormatterName = formatterNode.target.toSource().replaceAll( + RegExp('[()]'), + '', + ); } if (detectedFormatterName == 'FormatTool') { diff --git a/lib/src/utils/global_package_is_active_and_compatible.dart b/lib/src/utils/global_package_is_active_and_compatible.dart index a03d5d88..e7d6e79f 100644 --- a/lib/src/utils/global_package_is_active_and_compatible.dart +++ b/lib/src/utils/global_package_is_active_and_compatible.dart @@ -16,17 +16,25 @@ import 'executables.dart' as exe; /// an [environment] map with a `'PUB_CACHE': ''` entry, which will be /// passed to the [Process] that is run by this function. bool globalPackageIsActiveAndCompatible( - String packageName, VersionConstraint constraint, - {Map? environment}) { + String packageName, + VersionConstraint constraint, { + Map? environment, +}) { final args = ['pub', 'global', 'list']; - final result = Process.runSync(exe.dart, args, - environment: environment, stderrEncoding: utf8, stdoutEncoding: utf8); + final result = Process.runSync( + exe.dart, + args, + environment: environment, + stderrEncoding: utf8, + stdoutEncoding: utf8, + ); if (result.exitCode != 0) { throw ProcessException( - exe.dart, - args, - 'Could not list global pub packages:\n${result.stderr}', - result.exitCode); + exe.dart, + args, + 'Could not list global pub packages:\n${result.stderr}', + result.exitCode, + ); } for (final line in result.stdout.split('\n')) { diff --git a/lib/src/utils/logging.dart b/lib/src/utils/logging.dart index 24991643..fd56deb7 100644 --- a/lib/src/utils/logging.dart +++ b/lib/src/utils/logging.dart @@ -48,7 +48,7 @@ StringBuffer colorLog(LogRecord record, {bool verbose = false}) { final level = color.wrap('[${record.level}]'); final eraseLine = ansiOutputEnabled && !verbose ? '\x1b[2K\r' : ''; final lines = [ - '$eraseLine$level ${_loggerName(record, verbose)}${record.message}' + '$eraseLine$level ${_loggerName(record, verbose)}${record.message}', ]; if (record.error != null) { @@ -100,11 +100,16 @@ String humanReadable(Duration duration) { return '${hours}h ${remaining.inMinutes}m'; } -void logSubprocessHeader(Logger logger, String command, - {Level level = Level.INFO}) { +void logSubprocessHeader( + Logger logger, + String command, { + Level level = Level.INFO, +}) { final numColumns = io.stdout.hasTerminal ? io.stdout.terminalColumns : 79; - logger.log(level, - 'Running subprocess:\n${magenta.wrap(command)}\n${'-' * numColumns}\n'); + logger.log( + level, + 'Running subprocess:\n${magenta.wrap(command)}\n${'-' * numColumns}\n', + ); } /// Logs an asynchronous [action] with [description] before and after. @@ -144,9 +149,11 @@ T logTimedSync( } void Function(LogRecord) stdIOLogListener({bool verbose = false}) => - (record) => io.stdout.write(record.message.trim().isEmpty - ? '\n' * (record.message.split('\n').length - 1) - : colorLog(record, verbose: verbose)); + (record) => io.stdout.write( + record.message.trim().isEmpty + ? '\n' * (record.message.split('\n').length - 1) + : colorLog(record, verbose: verbose), + ); String _loggerName(LogRecord record, bool verbose) { final maybeSplit = record.level >= Level.WARNING ? '\n' : ' '; diff --git a/lib/src/utils/organize_directives/organize_directives.dart b/lib/src/utils/organize_directives/organize_directives.dart index b2b1804c..ec3407d5 100644 --- a/lib/src/utils/organize_directives/organize_directives.dart +++ b/lib/src/utils/organize_directives/organize_directives.dart @@ -10,9 +10,9 @@ import 'namespace_collector.dart'; /// /// Throws an ArgumentError if [sourceFileContents] cannot be parsed. String organizeDirectives(String sourceFileContents) { - final directives = parseString(content: sourceFileContents) - .unit - .accept(NamespaceCollector())!; + final directives = parseString( + content: sourceFileContents, + ).unit.accept(NamespaceCollector())!; if (directives.isEmpty) { return sourceFileContents; @@ -59,7 +59,7 @@ String _organizeDirectives( return [ if (sortedImports.isNotEmpty) sortedImports, - if (sortedExports.isNotEmpty) sortedExports + if (sortedExports.isNotEmpty) sortedExports, ].join('\n'); } @@ -68,8 +68,9 @@ String _organizeDirectivesOfType( String sourceFileContents, List namespaces, ) { - final directives = - namespaces.where((element) => element.directive is T).toList(); + final directives = namespaces + .where((element) => element.directive is T) + .toList(); directives.sort(_namespaceComparator); @@ -130,9 +131,11 @@ void _assignCommentsBeforeTokenToNamespace( // `precedingComments` returns the first comment before token. // Calling `comment.next` returns the next comment. // Returns null when there are no more comments left. - for (Token? comment = token.precedingComments; - comment != null; - comment = comment.next) { + for ( + Token? comment = token.precedingComments; + comment != null; + comment = comment.next + ) { // the LanguageVersionToken (`// @dart=2.11`) must stay where it is at // the top of the file. Do not assign this to any namespace if (comment is LanguageVersionToken) continue; @@ -152,7 +155,10 @@ void _assignCommentsBeforeTokenToNamespace( /// Checks if a given comment is on the same line as a directive. /// It's expected that directive end is before comment start. bool _commentIsOnSameLineAsNamespace( - Token comment, Namespace? namespace, String sourceFileContents) { + Token comment, + Namespace? namespace, + String sourceFileContents, +) { return namespace != null && !sourceFileContents .substring(namespace.directive.endToken.end, comment.charOffset) @@ -165,10 +171,12 @@ String _getSortedNamespaceString( List namespaces, ) { final sortedReplacement = StringBuffer(); - final firstRelativeNamespaceIdx = - namespaces.indexWhere((namespace) => namespace.isRelative); - final firstPkgDirectiveIdx = - namespaces.indexWhere((namespace) => namespace.isExternalPkg); + final firstRelativeNamespaceIdx = namespaces.indexWhere( + (namespace) => namespace.isRelative, + ); + final firstPkgDirectiveIdx = namespaces.indexWhere( + (namespace) => namespace.isExternalPkg, + ); for (var nsIndex = 0; nsIndex < namespaces.length; nsIndex++) { final namespace = namespaces[nsIndex]; if (nsIndex != 0 && diff --git a/lib/src/utils/organize_directives/organize_directives_in_paths.dart b/lib/src/utils/organize_directives/organize_directives_in_paths.dart index 0ff5dba2..0966c996 100644 --- a/lib/src/utils/organize_directives/organize_directives_in_paths.dart +++ b/lib/src/utils/organize_directives/organize_directives_in_paths.dart @@ -52,8 +52,11 @@ int _organizeDirectivesInFiles( }) { var exitCode = 0; for (final path in paths) { - final codeForFile = - _organizeDirectivesInFile(path, verbose: verbose, check: check); + final codeForFile = _organizeDirectivesInFile( + path, + verbose: verbose, + check: check, + ); if (codeForFile != 0) { exitCode = codeForFile; } diff --git a/lib/src/utils/parse_flag_from_args.dart b/lib/src/utils/parse_flag_from_args.dart index 933c1404..2b9b8ff5 100644 --- a/lib/src/utils/parse_flag_from_args.dart +++ b/lib/src/utils/parse_flag_from_args.dart @@ -1,5 +1,10 @@ -bool parseFlagFromArgs(List args, String name, - {String? abbr, bool defaultsTo = false, bool negatable = false}) { +bool parseFlagFromArgs( + List args, + String name, { + String? abbr, + bool defaultsTo = false, + bool negatable = false, +}) { // Ignore all args after a separator. final argsBeforeSep = args.takeWhile((arg) => arg != '--').toList(); diff --git a/lib/src/utils/parse_imports.dart b/lib/src/utils/parse_imports.dart index e6618e1f..b3f84aa6 100644 --- a/lib/src/utils/parse_imports.dart +++ b/lib/src/utils/parse_imports.dart @@ -6,8 +6,10 @@ import 'package:collection/collection.dart'; Iterable parseImports(String fileContents) => _importRegex.allMatches(fileContents).map((m) => m.group(1)).whereNotNull(); -final _importRegex = - RegExp(r'''^import ['"]([^'"]+)['"];?$''', multiLine: true); +final _importRegex = RegExp( + r'''^import ['"]([^'"]+)['"];?$''', + multiLine: true, +); /// Return a set of package names given a list of imports. Set computePackageNamesFromImports(Iterable imports) => imports diff --git a/lib/src/utils/process_declaration.dart b/lib/src/utils/process_declaration.dart index 93662842..5cd9a9d8 100644 --- a/lib/src/utils/process_declaration.dart +++ b/lib/src/utils/process_declaration.dart @@ -6,6 +6,10 @@ class ProcessDeclaration { final ProcessStartMode? mode; final String? workingDirectory; - ProcessDeclaration(this.executable, this.args, - {this.mode, this.workingDirectory}); + ProcessDeclaration( + this.executable, + this.args, { + this.mode, + this.workingDirectory, + }); } diff --git a/lib/src/utils/pubspec_lock.dart b/lib/src/utils/pubspec_lock.dart index 07e35e33..6a7efcda 100644 --- a/lib/src/utils/pubspec_lock.dart +++ b/lib/src/utils/pubspec_lock.dart @@ -5,7 +5,9 @@ import 'package:yaml/yaml.dart'; /// Index into the pubspecLock to locate the 'source' field for the given /// package. String? _getPubSpecLockPackageSource( - YamlDocument pubSpecLock, String packageName) { + YamlDocument pubSpecLock, + String packageName, +) { final contents = pubSpecLock.contents; if (contents is YamlMap) { final packages = contents['packages']; @@ -38,7 +40,9 @@ String? getDependencyVersion(YamlDocument pubSpecLock, String packageName) { /// lock document. If a package cannot be located in the pubspec lock document, /// it will map to null. HashMap getDependencySources( - YamlDocument pubspecLockDocument, Iterable packageNames) => - HashMap.fromIterable(packageNames, - value: (name) => - _getPubSpecLockPackageSource(pubspecLockDocument, name)); + YamlDocument pubspecLockDocument, + Iterable packageNames, +) => HashMap.fromIterable( + packageNames, + value: (name) => _getPubSpecLockPackageSource(pubspecLockDocument, name), +); diff --git a/lib/src/utils/run_process_and_ensure_exit.dart b/lib/src/utils/run_process_and_ensure_exit.dart index ce6a7c29..11689e25 100644 --- a/lib/src/utils/run_process_and_ensure_exit.dart +++ b/lib/src/utils/run_process_and_ensure_exit.dart @@ -5,12 +5,16 @@ import 'package:logging/logging.dart'; import 'ensure_process_exit.dart'; import 'process_declaration.dart'; -Future runProcessAndEnsureExit(ProcessDeclaration processDeclaration, - {Logger? log}) async { +Future runProcessAndEnsureExit( + ProcessDeclaration processDeclaration, { + Logger? log, +}) async { final process = await Process.start( - processDeclaration.executable, processDeclaration.args, - mode: processDeclaration.mode ?? ProcessStartMode.normal, - workingDirectory: processDeclaration.workingDirectory); + processDeclaration.executable, + processDeclaration.args, + mode: processDeclaration.mode ?? ProcessStartMode.normal, + workingDirectory: processDeclaration.workingDirectory, + ); ensureProcessExit(process, log: log); return process.exitCode; } diff --git a/lib/src/utils/start_process_and_ensure_exit.dart b/lib/src/utils/start_process_and_ensure_exit.dart index 9fe6137f..335cf034 100644 --- a/lib/src/utils/start_process_and_ensure_exit.dart +++ b/lib/src/utils/start_process_and_ensure_exit.dart @@ -5,12 +5,16 @@ import 'package:logging/logging.dart'; import 'ensure_process_exit.dart'; import 'process_declaration.dart'; -Future startProcessAndEnsureExit(ProcessDeclaration processDeclaration, - {Logger? log}) async { +Future startProcessAndEnsureExit( + ProcessDeclaration processDeclaration, { + Logger? log, +}) async { final process = await Process.start( - processDeclaration.executable, processDeclaration.args.toList(), - mode: processDeclaration.mode ?? ProcessStartMode.normal, - workingDirectory: processDeclaration.workingDirectory); + processDeclaration.executable, + processDeclaration.args.toList(), + mode: processDeclaration.mode ?? ProcessStartMode.normal, + workingDirectory: processDeclaration.workingDirectory, + ); ensureProcessExit(process, log: log); return process; } diff --git a/test/functional.dart b/test/functional.dart index 8a4e80c8..2f6e7dd0 100644 --- a/test/functional.dart +++ b/test/functional.dart @@ -7,14 +7,18 @@ import 'package:test_descriptor/test_descriptor.dart' as d; import 'package:test_process/test_process.dart'; Future runDevToolFunctionalTest( - String command, String projectTemplatePath, - {List? args, bool? verbose}) async { + String command, + String projectTemplatePath, { + List? args, + bool? verbose, +}) async { // Setup a temporary directory on which this tool will be run, using the given // project template as a starting point. final templateDir = Directory(projectTemplatePath); if (!templateDir.existsSync()) { throw ArgumentError( - 'projectTemplatePath does not exist: $projectTemplatePath'); + 'projectTemplatePath does not exist: $projectTemplatePath', + ); } final templateFiles = templateDir @@ -22,8 +26,10 @@ Future runDevToolFunctionalTest( .whereType() .map((f) => f.absolute); for (final file in templateFiles) { - final target = - p.join(d.sandbox, p.relative(file.path, from: templateDir.path)); + final target = p.join( + d.sandbox, + p.relative(file.path, from: templateDir.path), + ); Directory(p.dirname(target)).createSync(recursive: true); file.copySync(target); } @@ -36,29 +42,40 @@ Future runDevToolFunctionalTest( final pathDepPattern = RegExp(r'path: (.*)'); for (final pubspec in pubspecs) { - final updated = - pubspec.readAsStringSync().replaceAllMapped(pathDepPattern, (match) { - final relDepPath = match.group(1); - final relPubspecPath = p.relative(pubspec.path, from: d.sandbox); - var absPath = p.absolute(p.normalize( - p.join(templateDir.path, relPubspecPath, relDepPath, '..'))); - // Since pubspec paths should always be posix style or dart analyze - // complains, switch to forward slashes on windows - if (Platform.isWindows) { - absPath = absPath.replaceAll('\\', '/'); - } - return 'path: $absPath'; - }); + final updated = pubspec.readAsStringSync().replaceAllMapped( + pathDepPattern, + (match) { + final relDepPath = match.group(1); + final relPubspecPath = p.relative(pubspec.path, from: d.sandbox); + var absPath = p.absolute( + p.normalize( + p.join(templateDir.path, relPubspecPath, relDepPath, '..'), + ), + ); + // Since pubspec paths should always be posix style or dart analyze + // complains, switch to forward slashes on windows + if (Platform.isWindows) { + absPath = absPath.replaceAll('\\', '/'); + } + return 'path: $absPath'; + }, + ); pubspec.writeAsStringSync(updated); - final result = Process.runSync(exe.dart, ['pub', 'get'], - workingDirectory: pubspec.parent.path); + final result = Process.runSync(exe.dart, [ + 'pub', + 'get', + ], workingDirectory: pubspec.parent.path); if (result.exitCode != 0) { - final origPath = p.join(p.relative(templateDir.absolute.path), - p.relative(pubspec.absolute.path, from: d.sandbox)); - throw StateError('dart pub get failed on: $origPath\n' - 'STDOUT:\n${result.stdout}\n' - 'STDERR:\n${result.stderr}\n'); + final origPath = p.join( + p.relative(templateDir.absolute.path), + p.relative(pubspec.absolute.path, from: d.sandbox), + ); + throw StateError( + 'dart pub get failed on: $origPath\n' + 'STDOUT:\n${result.stdout}\n' + 'STDERR:\n${result.stderr}\n', + ); } } diff --git a/test/functional/analyze_tool_functional_test.dart b/test/functional/analyze_tool_functional_test.dart index 5e908e03..b4ea9d66 100644 --- a/test/functional/analyze_tool_functional_test.dart +++ b/test/functional/analyze_tool_functional_test.dart @@ -7,13 +7,17 @@ import '../functional.dart'; void main() { test('success', () async { final process = await runDevToolFunctionalTest( - 'analyze', 'test/functional/fixtures/analyze/success'); + 'analyze', + 'test/functional/fixtures/analyze/success', + ); await process.shouldExit(0); }); test('failure', () async { final process = await runDevToolFunctionalTest( - 'analyze', 'test/functional/fixtures/analyze/failure'); + 'analyze', + 'test/functional/fixtures/analyze/failure', + ); await process.shouldExit(greaterThan(0)); }); } diff --git a/test/functional/documentation_test.dart b/test/functional/documentation_test.dart index 709788e4..5aae33e5 100644 --- a/test/functional/documentation_test.dart +++ b/test/functional/documentation_test.dart @@ -29,14 +29,17 @@ void main() { d.file('pubspec.yaml', pubspecSource), ]).create(); - final pubGet = await TestProcess.start(exe.dart, ['pub', 'get'], - workingDirectory: '${d.sandbox}/project'); + final pubGet = await TestProcess.start(exe.dart, [ + 'pub', + 'get', + ], workingDirectory: '${d.sandbox}/project'); printOnFailure('PUBSPEC:\n$pubspecSource\n'); await pubGet.shouldExit(0); - final analysis = await TestProcess.start( - exe.dart, ['analyze', '--fatal-infos'], - workingDirectory: '${d.sandbox}/project'); + final analysis = await TestProcess.start(exe.dart, [ + 'analyze', + '--fatal-infos', + ], workingDirectory: '${d.sandbox}/project'); printOnFailure('SOURCE:\n${dartBlock.source}\n'); await analysis.shouldExit(0); }); @@ -44,8 +47,10 @@ void main() { } Iterable getDartBlocks() sync* { - final dartBlockPattern = - RegExp(r'^```dart *([^\r\n]*)([^`]*)^```', multiLine: true); + final dartBlockPattern = RegExp( + r'^```dart *([^\r\n]*)([^`]*)^```', + multiLine: true, + ); for (final file in Glob('**.md').listSync().whereType()) { final source = file.readAsStringSync(); var i = 1; @@ -64,8 +69,9 @@ String pubspecWithPackages(Set packages) { ..writeln(' sdk: ">=2.12.0 <3.0.0"') ..writeln('dependencies:'); for (final package in packages) { - var constraint = - package == 'dart_dev' ? '\n path: ${p.current}' : ' any'; + var constraint = package == 'dart_dev' + ? '\n path: ${p.current}' + : ' any'; buffer.writeln(' $package:$constraint'); } return buffer.toString(); @@ -78,13 +84,13 @@ class DartBlock { final String sourceUrl; DartBlock.fromSource(this.source, this.sourceUrl, this.index) - : packages = parsePackagesFromSource(source); + : packages = parsePackagesFromSource(source); static Set parsePackagesFromSource(String source) { final packagePattern = RegExp(r'''['"]package:(\w+)\/.*['"]'''); return { for (final match in packagePattern.allMatches(source)) - if (match.group(1) != null) match.group(1)! + if (match.group(1) != null) match.group(1)!, }; } } diff --git a/test/functional/format_tool_functional_test.dart b/test/functional/format_tool_functional_test.dart index 36352186..e497fbf9 100644 --- a/test/functional/format_tool_functional_test.dart +++ b/test/functional/format_tool_functional_test.dart @@ -25,10 +25,7 @@ void main() { const projectPath = 'test/functional/fixtures/format/unsorted_imports/organize_directives_off/'; final sourceFile = await format(projectPath); - expect( - sourceFile.contentsBefore, - equals(sourceFile.contentsAfter), - ); + expect(sourceFile.contentsBefore, equals(sourceFile.contentsAfter)); }); test('organize directives on', () async { @@ -41,25 +38,27 @@ void main() { ); }); - test('passes configured languageVersion to dart format when supported', - () async { - const projectPath = - 'test/functional/fixtures/format/language_version/dart_format_configured/'; + test( + 'passes configured languageVersion to dart format when supported', + () async { + const projectPath = + 'test/functional/fixtures/format/language_version/dart_format_configured/'; - final process = await runDevToolFunctionalTest('format', projectPath); - final stdoutFuture = process.stdoutStream().toList(); + final process = await runDevToolFunctionalTest('format', projectPath); + final stdoutFuture = process.stdoutStream().toList(); - await process.shouldExit(0); + await process.shouldExit(0); - final stdout = (await stdoutFuture).join('\n'); - final expectedCommand = [ - 'dart format', - if (dartSemverVersion.major >= 3) '--language-version=3.0', - 'lib/main.dart', - ].join(' '); + final stdout = (await stdoutFuture).join('\n'); + final expectedCommand = [ + 'dart format', + if (dartSemverVersion.major >= 3) '--language-version=3.0', + 'lib/main.dart', + ].join(' '); - expect(stdout, contains(expectedCommand)); - }); + expect(stdout, contains(expectedCommand)); + }, + ); }); } diff --git a/test/functional/null_safety_functional_test.dart b/test/functional/null_safety_functional_test.dart index 5605b189..497ff444 100644 --- a/test/functional/null_safety_functional_test.dart +++ b/test/functional/null_safety_functional_test.dart @@ -8,19 +8,25 @@ void main() { group('runs properly in a project that has opted into null safety', () { test('without any custom config', () async { final process = await runDevToolFunctionalTest( - 'analyze', 'test/functional/fixtures/null_safety/opted_in_no_config'); + 'analyze', + 'test/functional/fixtures/null_safety/opted_in_no_config', + ); await process.shouldExit(0); }); test('with a custom config', () async { - final process = await runDevToolFunctionalTest('analyze', - 'test/functional/fixtures/null_safety/opted_in_custom_config'); + final process = await runDevToolFunctionalTest( + 'analyze', + 'test/functional/fixtures/null_safety/opted_in_custom_config', + ); await process.shouldExit(0); }); test('with a custom config that has a language version comment', () async { - final process = await runDevToolFunctionalTest('analyze', - 'test/functional/fixtures/null_safety/opted_in_custom_config_version_comment'); + final process = await runDevToolFunctionalTest( + 'analyze', + 'test/functional/fixtures/null_safety/opted_in_custom_config_version_comment', + ); await process.shouldExit(0); }, tags: 'dart2'); }); diff --git a/test/log_matchers.dart b/test/log_matchers.dart index 15ba2f40..3348e090 100644 --- a/test/log_matchers.dart +++ b/test/log_matchers.dart @@ -35,8 +35,10 @@ class _LogRecordMatcher extends Matcher { final Matcher _message; factory _LogRecordMatcher(dynamic levelOr, dynamic messageOr) => - _LogRecordMatcher._(levelOr is Matcher ? levelOr : equals(levelOr), - messageOr is Matcher ? messageOr : equals(messageOr)); + _LogRecordMatcher._( + levelOr is Matcher ? levelOr : equals(levelOr), + messageOr is Matcher ? messageOr : equals(messageOr), + ); _LogRecordMatcher._(this._level, this._message); @@ -50,8 +52,12 @@ class _LogRecordMatcher extends Matcher { } @override - Description describeMismatch(covariant LogRecord item, - Description description, Map _, bool __) { + Description describeMismatch( + covariant LogRecord item, + Description description, + Map _, + bool __, + ) { if (!_level.matches(item.level, {})) { _level.describeMismatch(item.level, description, {}, false); } diff --git a/test/tools/analyze_tool_test.dart b/test/tools/analyze_tool_test.dart index 2850cf67..1c7adbd6 100644 --- a/test/tools/analyze_tool_test.dart +++ b/test/tools/analyze_tool_test.dart @@ -33,42 +33,52 @@ void main() { final argParser = AnalyzeTool().toCommand('t').argParser; final argResults = argParser.parse(['--analyzer-args', 'c d']); expect( - buildArgs(argResults: argResults, configuredAnalyzerArgs: ['a', 'b']), - orderedEquals(['a', 'b', 'c', 'd'])); + buildArgs(argResults: argResults, configuredAnalyzerArgs: ['a', 'b']), + orderedEquals(['a', 'b', 'c', 'd']), + ); }); test( - 'combines configured args and cli args (in that order) with useDartAnalyze', - () { - final argParser = AnalyzeTool().toCommand('t').argParser; - final argResults = argParser.parse(['--analyzer-args', 'c d']); - expect( + 'combines configured args and cli args (in that order) with useDartAnalyze', + () { + final argParser = AnalyzeTool().toCommand('t').argParser; + final argResults = argParser.parse(['--analyzer-args', 'c d']); + expect( buildArgs( - argResults: argResults, - configuredAnalyzerArgs: ['a', 'b'], - useDartAnalyze: true), - orderedEquals(['analyze', 'a', 'b', 'c', 'd'])); - }); + argResults: argResults, + configuredAnalyzerArgs: ['a', 'b'], + useDartAnalyze: true, + ), + orderedEquals(['analyze', 'a', 'b', 'c', 'd']), + ); + }, + ); test('inserts a verbose flag if not already present', () { final argParser = AnalyzeTool().toCommand('t').argParser; final argResults = argParser.parse(['--analyzer-args', 'c d']); expect( - buildArgs( - argResults: argResults, - configuredAnalyzerArgs: ['a', 'b'], - verbose: true), - orderedEquals(['a', 'b', 'c', 'd', '-v'])); + buildArgs( + argResults: argResults, + configuredAnalyzerArgs: ['a', 'b'], + verbose: true, + ), + orderedEquals(['a', 'b', 'c', 'd', '-v']), + ); }); test('does not insert a duplicate verbose flag (-v)', () { - expect(buildArgs(configuredAnalyzerArgs: ['-v'], verbose: true), - orderedEquals(['-v'])); + expect( + buildArgs(configuredAnalyzerArgs: ['-v'], verbose: true), + orderedEquals(['-v']), + ); }); test('does not insert a duplicate verbose flag (--verbose)', () { - expect(buildArgs(configuredAnalyzerArgs: ['--verbose'], verbose: true), - orderedEquals(['--verbose'])); + expect( + buildArgs(configuredAnalyzerArgs: ['--verbose'], verbose: true), + orderedEquals(['--verbose']), + ); }); }); @@ -79,15 +89,19 @@ void main() { }); test('from one glob', () { - expect(buildEntrypoints(include: [Glob('*.dart')], root: globRoot), - ['${globRoot}file.dart']); + expect(buildEntrypoints(include: [Glob('*.dart')], root: globRoot), [ + '${globRoot}file.dart', + ]); }); test('from multiple globs', () { expect( - buildEntrypoints( - include: [Glob('*.dart'), Glob('*.txt')], root: globRoot), - unorderedEquals(['${globRoot}file.dart', '${globRoot}file.txt'])); + buildEntrypoints( + include: [Glob('*.dart'), Glob('*.txt')], + root: globRoot, + ), + unorderedEquals(['${globRoot}file.dart', '${globRoot}file.txt']), + ); }); }); @@ -95,27 +109,49 @@ void main() { test('throws UsageException if positional args are given', () { final argResults = ArgParser().parse(['a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_analyze'); + argResults: argResults, + commandName: 'test_analyze', + ); expect( - () => buildProcess(context), - throwsA(isA() + () => buildProcess(context), + throwsA( + isA() + .having( + (e) => e.message, + 'command name', + contains('test_analyze'), + ) .having( - (e) => e.message, 'command name', contains('test_analyze')) - .having((e) => e.message, 'usage footer', - contains('--analyzer-args')))); + (e) => e.message, + 'usage footer', + contains('--analyzer-args'), + ), + ), + ); }); test('throws UsageException if args are given after a separator', () { final argResults = ArgParser().parse(['--', 'a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_analyze'); + argResults: argResults, + commandName: 'test_analyze', + ); expect( - () => buildProcess(context), - throwsA(isA() + () => buildProcess(context), + throwsA( + isA() .having( - (e) => e.message, 'command name', contains('test_analyze')) - .having((e) => e.message, 'usage footer', - contains('--analyzer-args')))); + (e) => e.message, + 'command name', + contains('test_analyze'), + ) + .having( + (e) => e.message, + 'usage footer', + contains('--analyzer-args'), + ), + ), + ); }); test('returns a ProcessDeclaration (default)', () { @@ -134,96 +170,121 @@ void main() { test('returns a ProcessDeclaration (with args)', () { final argParser = AnalyzeTool().toCommand('t').argParser; - final argResults = - argParser.parse(['--analyzer-args', '--dart-sdk /sdk']); + final argResults = argParser.parse([ + '--analyzer-args', + '--dart-sdk /sdk', + ]); final context = DevToolExecutionContext(argResults: argResults); - final process = buildProcess(context, - configuredAnalyzerArgs: ['--fatal-infos', '--fatal-warnings'], - include: [Glob('*.dart'), Glob('*.txt')], - path: globRoot); + final process = buildProcess( + context, + configuredAnalyzerArgs: ['--fatal-infos', '--fatal-warnings'], + include: [Glob('*.dart'), Glob('*.txt')], + path: globRoot, + ); expect(process.executable, exe.dartanalyzer); expect( - process.args, - orderedEquals([ - '--fatal-infos', - '--fatal-warnings', - '--dart-sdk', - '/sdk', - '${globRoot}file.dart', - '${globRoot}file.txt', - ])); + process.args, + orderedEquals([ + '--fatal-infos', + '--fatal-warnings', + '--dart-sdk', + '/sdk', + '${globRoot}file.dart', + '${globRoot}file.txt', + ]), + ); }); test('returns a ProcessDeclaration with useDartAnalyzer (with args)', () { final argParser = AnalyzeTool().toCommand('t').argParser; - final argResults = - argParser.parse(['--analyzer-args', '--dart-sdk /sdk']); + final argResults = argParser.parse([ + '--analyzer-args', + '--dart-sdk /sdk', + ]); final context = DevToolExecutionContext(argResults: argResults); - final process = buildProcess(context, - configuredAnalyzerArgs: ['--fatal-infos', '--fatal-warnings'], - include: [Glob('*.dart')], - path: globRoot, - useDartAnalyze: true); + final process = buildProcess( + context, + configuredAnalyzerArgs: ['--fatal-infos', '--fatal-warnings'], + include: [Glob('*.dart')], + path: globRoot, + useDartAnalyze: true, + ); expect(process.executable, exe.dart); expect( - process.args, - orderedEquals([ - 'analyze', - '--fatal-infos', - '--fatal-warnings', - '--dart-sdk', - '/sdk', - '${globRoot}file.dart', - ])); + process.args, + orderedEquals([ + 'analyze', + '--fatal-infos', + '--fatal-warnings', + '--dart-sdk', + '/sdk', + '${globRoot}file.dart', + ]), + ); }); test('returns a ProcessDeclaration (verbose)', () { final argParser = AnalyzeTool().toCommand('t').argParser; - final argResults = - argParser.parse(['--analyzer-args', '--dart-sdk /sdk']); - final context = - DevToolExecutionContext(argResults: argResults, verbose: true); - final process = buildProcess(context, - configuredAnalyzerArgs: ['--fatal-infos', '--fatal-warnings'], - include: [Glob('*.dart'), Glob('*.txt')], - path: globRoot); + final argResults = argParser.parse([ + '--analyzer-args', + '--dart-sdk /sdk', + ]); + final context = DevToolExecutionContext( + argResults: argResults, + verbose: true, + ); + final process = buildProcess( + context, + configuredAnalyzerArgs: ['--fatal-infos', '--fatal-warnings'], + include: [Glob('*.dart'), Glob('*.txt')], + path: globRoot, + ); expect(process.executable, exe.dartanalyzer); expect( - process.args, - orderedEquals([ - '--fatal-infos', - '--fatal-warnings', - '--dart-sdk', - '/sdk', - '-v', - '${globRoot}file.dart', - '${globRoot}file.txt', - ])); + process.args, + orderedEquals([ + '--fatal-infos', + '--fatal-warnings', + '--dart-sdk', + '/sdk', + '-v', + '${globRoot}file.dart', + '${globRoot}file.txt', + ]), + ); }); }); group('logCommand', () { test('with <=5 entrypoints', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dartanalyzer -t a b c d e')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dartanalyzer -t a b c d e'))), + ); logCommand(['-t'], ['a', 'b', 'c', 'd', 'e'], useDartAnalyzer: false); }); test('with >5 entrypoints', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dartanalyzer -t <6 paths>')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dartanalyzer -t <6 paths>'))), + ); logCommand(['-t'], ['a', 'b', 'c', 'd', 'e', 'f']); }); test('with >5 entrypoints in verbose mode', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dartanalyzer -t a b c d e f')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dartanalyzer -t a b c d e f'))), + ); logCommand(['-t'], ['a', 'b', 'c', 'd', 'e', 'f'], verbose: true); }); test('in useDartAnalyze mode', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dart analyze -t a')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dart analyze -t a'))), + ); logCommand(['analyze', '-t'], ['a'], useDartAnalyzer: true); }); }); diff --git a/test/tools/compound_tool_test.dart b/test/tools/compound_tool_test.dart index ae74de7a..8bc29753 100644 --- a/test/tools/compound_tool_test.dart +++ b/test/tools/compound_tool_test.dart @@ -78,8 +78,11 @@ void main() { final ct = CompoundTool() ..addTool(tool1) ..addTool(tool2); - await ct.run(DevToolExecutionContext( - argResults: ct.argParser.parse(['--foo', '--bar', 'baz']))); + await ct.run( + DevToolExecutionContext( + argResults: ct.argParser.parse(['--foo', '--bar', 'baz']), + ), + ); }); test('runs tools with a custom ArgMapper, if provided', () async { @@ -90,8 +93,11 @@ void main() { }, argParser: ArgParser()..addFlag('foo')); final ct = CompoundTool()..addTool(tool, argMapper: takeAllArgs); - await ct.run(DevToolExecutionContext( - argResults: ct.argParser.parse(['--foo', 'bar', 'baz']))); + await ct.run( + DevToolExecutionContext( + argResults: ct.argParser.parse(['--foo', 'bar', 'baz']), + ), + ); }); }); @@ -151,7 +157,9 @@ void main() { ..addParser(parser1) ..addParser(parser2); expect( - cap.usage, allOf(contains(parser1.usage), contains(parser2.usage))); + cap.usage, + allOf(contains(parser1.usage), contains(parser2.usage)), + ); }); }); @@ -191,7 +199,8 @@ void main() { ..addTool(fooTool) ..addTool(barTool); final baseContext = DevToolExecutionContext( - argResults: compoundTool.argParser.parse(['--foo', '--bar'])); + argResults: compoundTool.argParser.parse(['--foo', '--bar']), + ); final spec = DevToolSpec(RunWhen.passing, fooTool); final result = contextForTool(baseContext, spec); @@ -219,13 +228,9 @@ void main() { ]); final args = optionArgsOnly(originalResults); expect( - args, - unorderedEquals([ - '--flag', - '--opt=opt', - '--multi=one', - '--multi=two', - ])); + args, + unorderedEquals(['--flag', '--opt=opt', '--multi=one', '--multi=two']), + ); }); test('filters by allowedOptions if given', () { @@ -252,16 +257,14 @@ void main() { 'foo', 'bar', ]); - final args = optionArgsOnly(originalResults, - allowedOptions: ['flag', 'opt', 'multi']); + final args = optionArgsOnly( + originalResults, + allowedOptions: ['flag', 'opt', 'multi'], + ); expect( - args, - unorderedEquals([ - '--flag', - '--opt=opt', - '--multi=one', - '--multi=two', - ])); + args, + unorderedEquals(['--flag', '--opt=opt', '--multi=one', '--multi=two']), + ); }); }); diff --git a/test/tools/format_tool_test.dart b/test/tools/format_tool_test.dart index a90237db..97b73f67 100644 --- a/test/tools/format_tool_test.dart +++ b/test/tools/format_tool_test.dart @@ -22,8 +22,10 @@ void main() { test('toCommand overrides the argParser', () { final argParser = FormatTool().argParser; - expect(argParser.options.keys, - containsAll(['overwrite', 'dry-run', 'check', 'formatter-args'])); + expect( + argParser.options.keys, + containsAll(['overwrite', 'dry-run', 'check', 'formatter-args']), + ); expect(argParser.options['overwrite']!.type, OptionType.flag); expect(argParser.options['overwrite']!.abbr, 'w'); @@ -49,52 +51,62 @@ void main() { }); test('custom excludes', () { - FormatterInputs formatterInputs = - FormatTool.getInputs(exclude: [Glob('*_exclude.dart')], root: root); + FormatterInputs formatterInputs = FormatTool.getInputs( + exclude: [Glob('*_exclude.dart')], + root: root, + ); expect( - formatterInputs.includedFiles, - unorderedEquals({ - 'file.dart', - p.join('links', 'not_link.dart'), - p.join('lib', 'sub', 'file.dart'), - 'linked.dart', - p.join('other', 'file.dart'), - })); + formatterInputs.includedFiles, + unorderedEquals({ + 'file.dart', + p.join('links', 'not_link.dart'), + p.join('lib', 'sub', 'file.dart'), + 'linked.dart', + p.join('other', 'file.dart'), + }), + ); }); test('empty inputs due to excludes config', () async { expect( - FormatTool.getInputs(exclude: [Glob('**')], root: root) - .includedFiles, - isEmpty); + FormatTool.getInputs(exclude: [Glob('**')], root: root).includedFiles, + isEmpty, + ); }); test('expandCwd forces . to be expanded to all files', () async { - final formatterInputs = - FormatTool.getInputs(expandCwd: true, root: root); + final formatterInputs = FormatTool.getInputs( + expandCwd: true, + root: root, + ); expect( - formatterInputs.includedFiles, - unorderedEquals({ - 'file.dart', - p.join('links', 'not_link.dart'), - p.join('lib', 'sub', 'file.dart'), - 'linked.dart', - p.join('other', 'file.dart'), - 'should_exclude.dart', - })); + formatterInputs.includedFiles, + unorderedEquals({ + 'file.dart', + p.join('links', 'not_link.dart'), + p.join('lib', 'sub', 'file.dart'), + 'linked.dart', + p.join('other', 'file.dart'), + 'should_exclude.dart', + }), + ); }); test('followLinks follows linked files and directories', () async { final formatterInputs = FormatTool.getInputs( - expandCwd: true, followLinks: true, root: p.join(root, 'links')); + expandCwd: true, + followLinks: true, + root: p.join(root, 'links'), + ); expect( - formatterInputs.includedFiles, - unorderedEquals({ - p.join('lib-link', 'sub', 'file.dart'), - 'not_link.dart', - 'link.dart', - })); + formatterInputs.includedFiles, + unorderedEquals({ + p.join('lib-link', 'sub', 'file.dart'), + 'not_link.dart', + 'link.dart', + }), + ); }); }); }); @@ -105,107 +117,140 @@ void main() { }); test('mode=overwrite', () { - expect(buildArgs(['a', 'b'], FormatMode.overwrite), - orderedEquals(['a', 'b', '-w'])); + expect( + buildArgs(['a', 'b'], FormatMode.overwrite), + orderedEquals(['a', 'b', '-w']), + ); }); test('mode=overwrite without write arg', () { expect( - buildArgs(['a', 'b'], FormatMode.overwrite, - passWriteArgForOverwrite: false), - orderedEquals(['a', 'b'])); + buildArgs( + ['a', 'b'], + FormatMode.overwrite, + passWriteArgForOverwrite: false, + ), + orderedEquals(['a', 'b']), + ); }); test('adds latest language version flag when configured', () { expect( - buildArgs(['a', 'b'], FormatMode.overwrite, + buildArgs( + ['a', 'b'], + FormatMode.overwrite, passWriteArgForOverwrite: false, - languageVersion: 'latest'), - orderedEquals(['a', 'b', '--language-version=latest'])); + languageVersion: 'latest', + ), + orderedEquals(['a', 'b', '--language-version=latest']), + ); }); test('adds configured language version flag', () { expect( - buildArgs(['a', 'b'], FormatMode.overwrite, + buildArgs( + ['a', 'b'], + FormatMode.overwrite, passWriteArgForOverwrite: false, - languageVersion: '3.0'), - orderedEquals(['a', 'b', '--language-version=3.0'])); + languageVersion: '3.0', + ), + orderedEquals(['a', 'b', '--language-version=3.0']), + ); }); test('mode=dry-run', () { - expect(buildArgs(['a', 'b'], FormatMode.dryRun), - orderedEquals(['a', 'b', '-n'])); + expect( + buildArgs(['a', 'b'], FormatMode.dryRun), + orderedEquals(['a', 'b', '-n']), + ); }); test('mode=check', () { - expect(buildArgs(['a', 'b'], FormatMode.check), - orderedEquals(['a', 'b', '-n', '--set-exit-if-changed'])); + expect( + buildArgs(['a', 'b'], FormatMode.check), + orderedEquals(['a', 'b', '-n', '--set-exit-if-changed']), + ); }); test('combines configured args with cli args (in that order)', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); expect( - buildArgs(['a', 'b'], FormatMode.overwrite, - argResults: argResults, - configuredFormatterArgs: ['--fix', '--follow-links']), - orderedEquals([ - 'a', - 'b', - '-w', - '--fix', - '--follow-links', - '--indent', - '2', - ])); + buildArgs( + ['a', 'b'], + FormatMode.overwrite, + argResults: argResults, + configuredFormatterArgs: ['--fix', '--follow-links'], + ), + orderedEquals([ + 'a', + 'b', + '-w', + '--fix', + '--follow-links', + '--indent', + '2', + ]), + ); }); }); group('buildArgsForDartFormat', () { test('no mode', () { expect( - buildArgsForDartFormat(['a', 'b'], null), orderedEquals(['a', 'b'])); + buildArgsForDartFormat(['a', 'b'], null), + orderedEquals(['a', 'b']), + ); }); test('mode=dry-run', () { - expect(buildArgsForDartFormat(['a', 'b'], FormatMode.dryRun), - orderedEquals(['a', 'b', '-o', 'none'])); + expect( + buildArgsForDartFormat(['a', 'b'], FormatMode.dryRun), + orderedEquals(['a', 'b', '-o', 'none']), + ); }); test('mode=check', () { - expect(buildArgsForDartFormat(['a', 'b'], FormatMode.check), - orderedEquals(['a', 'b', '-o', 'none', '--set-exit-if-changed'])); + expect( + buildArgsForDartFormat(['a', 'b'], FormatMode.check), + orderedEquals(['a', 'b', '-o', 'none', '--set-exit-if-changed']), + ); }); test('adds latest language version flag when configured', () { expect( - buildArgsForDartFormat(['a', 'b'], FormatMode.overwrite, - languageVersion: 'latest'), - orderedEquals(['a', 'b', '--language-version=latest'])); + buildArgsForDartFormat( + ['a', 'b'], + FormatMode.overwrite, + languageVersion: 'latest', + ), + orderedEquals(['a', 'b', '--language-version=latest']), + ); }); test('adds configured language version flag', () { expect( - buildArgsForDartFormat(['a', 'b'], FormatMode.overwrite, - languageVersion: '3.0'), - orderedEquals(['a', 'b', '--language-version=3.0'])); + buildArgsForDartFormat( + ['a', 'b'], + FormatMode.overwrite, + languageVersion: '3.0', + ), + orderedEquals(['a', 'b', '--language-version=3.0']), + ); }); test('combines configured args with cli args (in that order)', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); expect( - buildArgsForDartFormat(['a', 'b'], FormatMode.overwrite, - argResults: argResults, - configuredFormatterArgs: ['--fix', '--follow-links']), - orderedEquals([ - 'a', - 'b', - '--fix', - '--follow-links', - '--indent', - '2', - ])); + buildArgsForDartFormat( + ['a', 'b'], + FormatMode.overwrite, + argResults: argResults, + configuredFormatterArgs: ['--fix', '--follow-links'], + ), + orderedEquals(['a', 'b', '--fix', '--follow-links', '--indent', '2']), + ); }); }); @@ -213,20 +258,26 @@ void main() { test('throws UsageException if positional args are given', () { final argResults = ArgParser().parse(['a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_format'); + argResults: argResults, + commandName: 'test_format', + ); expect( - () => buildExecution(context), - throwsA(isA() + () => buildExecution(context), + throwsA( + isA() .having((e) => e.message, 'command name', contains('test_format')) - .having( - (e) => e.message, 'usage', contains('--formatter-args')))); + .having((e) => e.message, 'usage', contains('--formatter-args')), + ), + ); }); test('allows positional arguments when the command is hackFastFormat', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['a/random/path']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'hackFastFormat'); + argResults: argResults, + commandName: 'hackFastFormat', + ); final execution = buildExecution(context); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dartfmt); @@ -235,60 +286,93 @@ void main() { expect(execution.directiveOrganization, isNull); }); - test('requires positional arguments when the command is hackFastFormat', - () { - final argParser = FormatTool().toCommand('t').argParser; - final argResults = argParser.parse([]); - final context = DevToolExecutionContext( - argResults: argResults, commandName: 'hackFastFormat'); - expect( + test( + 'requires positional arguments when the command is hackFastFormat', + () { + final argParser = FormatTool().toCommand('t').argParser; + final argResults = argParser.parse([]); + final context = DevToolExecutionContext( + argResults: argResults, + commandName: 'hackFastFormat', + ); + expect( () => buildExecution(context), - throwsA(isA() - .having( - (e) => e.message, 'command name', contains('hackFastFormat')) - .having((e) => e.message, 'usage', - contains('must specify targets')))); - }); + throwsA( + isA() + .having( + (e) => e.message, + 'command name', + contains('hackFastFormat'), + ) + .having( + (e) => e.message, + 'usage', + contains('must specify targets'), + ), + ), + ); + }, + ); test('throws UsageException if args are given after a separator', () { final argResults = ArgParser().parse(['--', 'a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_format'); + argResults: argResults, + commandName: 'test_format', + ); expect( - () => buildExecution(context), - throwsA(isA() + () => buildExecution(context), + throwsA( + isA() .having((e) => e.message, 'command name', contains('test_format')) - .having( - (e) => e.message, 'usage', contains('--formatter-args')))); + .having((e) => e.message, 'usage', contains('--formatter-args')), + ), + ); }); - test( - 'returns config exit code and logs if configured formatter is ' + test('returns config exit code and logs if configured formatter is ' 'dart_style but the package is not a direct dependency', () { expect( - Logger.root.onRecord, - emitsThrough(severeLogOf(allOf( + Logger.root.onRecord, + emitsThrough( + severeLogOf( + allOf( contains('Cannot run "dart_style:format"'), contains('add "dart_style" to your pubspec.yaml'), - contains('use "dartfmt" instead'))))); + contains('use "dartfmt" instead'), + ), + ), + ), + ); final context = DevToolExecutionContext(); - final execution = buildExecution(context, - formatter: Formatter.dartStyle, - path: 'test/tools/fixtures/format/missing_dart_style'); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + path: 'test/tools/fixtures/format/missing_dart_style', + ); expect(execution.exitCode, ExitCode.config.code); }); test('returns a config exit code if inputs list is empty', () { expect( - Logger.root.onRecord, - emitsThrough(severeLogOf(allOf( + Logger.root.onRecord, + emitsThrough( + severeLogOf( + allOf( contains('formatter cannot run because no inputs could be found'), - contains('tool/dart_dev/config.dart'))))); + contains('tool/dart_dev/config.dart'), + ), + ), + ), + ); final context = DevToolExecutionContext(); - final execution = buildExecution(context, - exclude: [Glob('**')], path: 'test/tools/fixtures/format/globs'); + final execution = buildExecution( + context, + exclude: [Glob('**')], + path: 'test/tools/fixtures/format/globs', + ); expect(execution.exitCode, ExitCode.config.code); }); @@ -305,8 +389,10 @@ void main() { test('that uses defaultMode if no mode flag is given', () { final context = DevToolExecutionContext(); - final execution = - buildExecution(context, defaultMode: FormatMode.dryRun); + final execution = buildExecution( + context, + defaultMode: FormatMode.dryRun, + ); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dartfmt); expect(execution.formatProcess!.args, orderedEquals(['-n', '.'])); @@ -326,121 +412,164 @@ void main() { test('with dartFormat', () { final context = DevToolExecutionContext(); - final execution = - buildExecution(context, formatter: Formatter.dartFormat); + final execution = buildExecution( + context, + formatter: Formatter.dartFormat, + ); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dart); expect( - execution.formatProcess!.args, - orderedEquals([ - 'format', - if (dartSemverVersion.major >= 3) '--language-version=latest', - '.', - ])); + execution.formatProcess!.args, + orderedEquals([ + 'format', + if (dartSemverVersion.major >= 3) '--language-version=latest', + '.', + ]), + ); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); test('with dart_style:format', () { final context = DevToolExecutionContext(); - final execution = buildExecution(context, - formatter: Formatter.dartStyle, - path: 'test/tools/fixtures/format/has_dart_style'); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + path: 'test/tools/fixtures/format/has_dart_style', + ); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dart); - expect(execution.formatProcess!.args, - orderedEquals(['run', 'dart_style:format', '.'])); + expect( + execution.formatProcess!.args, + orderedEquals(['run', 'dart_style:format', '.']), + ); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); expect(execution.directiveOrganization, isNull); }); test('dartfmt with args', () { final argParser = FormatTool().toCommand('t').argParser; - final argResults = - argParser.parse(['-w', '--formatter-args', '--indent 2']); + final argResults = argParser.parse([ + '-w', + '--formatter-args', + '--indent 2', + ]); final context = DevToolExecutionContext(argResults: argResults); - final execution = buildExecution(context, - configuredFormatterArgs: ['--fix', '--follow-links'], - formatter: Formatter.dartfmt); + final execution = buildExecution( + context, + configuredFormatterArgs: ['--fix', '--follow-links'], + formatter: Formatter.dartfmt, + ); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dartfmt); expect( - execution.formatProcess!.args, - orderedEquals( - ['-w', '--fix', '--follow-links', '--indent', '2', '.'])); + execution.formatProcess!.args, + orderedEquals([ + '-w', + '--fix', + '--follow-links', + '--indent', + '2', + '.', + ]), + ); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); expect(execution.directiveOrganization, isNull); }); - test('dart_style:format in overwrite mode passes -w for dart_style <3.0.0', - () { - final context = DevToolExecutionContext(); - final execution = buildExecution( - context, - formatter: Formatter.dartStyle, - defaultMode: FormatMode.overwrite, - path: 'test/tools/fixtures/format/has_dart_style_v2', - ); - expect(execution.exitCode, isNull); - expect(execution.formatProcess!.executable, exe.dart); - expect(execution.formatProcess!.args, - orderedEquals(['run', 'dart_style:format', '-w', '.'])); - expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); - }); + test( + 'dart_style:format in overwrite mode passes -w for dart_style <3.0.0', + () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + defaultMode: FormatMode.overwrite, + path: 'test/tools/fixtures/format/has_dart_style_v2', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect( + execution.formatProcess!.args, + orderedEquals(['run', 'dart_style:format', '-w', '.']), + ); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }, + ); test( - 'dart_style:format in overwrite mode omits -w for dart_style >=3.0.0', - () { - final context = DevToolExecutionContext(); - final execution = buildExecution( - context, - formatter: Formatter.dartStyle, - defaultMode: FormatMode.overwrite, - path: 'test/tools/fixtures/format/has_dart_style_v3', - ); - expect(execution.exitCode, isNull); - expect(execution.formatProcess!.executable, exe.dart); - expect(execution.formatProcess!.args, - orderedEquals(['run', 'dart_style:format', '--language-version=latest', '.'])); - expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); - }); + 'dart_style:format in overwrite mode omits -w for dart_style >=3.0.0', + () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + defaultMode: FormatMode.overwrite, + path: 'test/tools/fixtures/format/has_dart_style_v3', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect( + execution.formatProcess!.args, + orderedEquals([ + 'run', + 'dart_style:format', + '--language-version=latest', + '.', + ]), + ); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }, + ); - test('dart_style:format uses configured language version for dart_style >=3.0.0', - () { - final context = DevToolExecutionContext(); - final execution = buildExecution( - context, - formatter: Formatter.dartStyle, - languageVersion: '3.0', - defaultMode: FormatMode.overwrite, - path: 'test/tools/fixtures/format/has_dart_style_v3', - ); - expect(execution.exitCode, isNull); - expect(execution.formatProcess!.executable, exe.dart); - expect(execution.formatProcess!.args, - orderedEquals(['run', 'dart_style:format', '--language-version=3.0', '.'])); - expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); - }); + test( + 'dart_style:format uses configured language version for dart_style >=3.0.0', + () { + final context = DevToolExecutionContext(); + final execution = buildExecution( + context, + formatter: Formatter.dartStyle, + languageVersion: '3.0', + defaultMode: FormatMode.overwrite, + path: 'test/tools/fixtures/format/has_dart_style_v3', + ); + expect(execution.exitCode, isNull); + expect(execution.formatProcess!.executable, exe.dart); + expect( + execution.formatProcess!.args, + orderedEquals([ + 'run', + 'dart_style:format', + '--language-version=3.0', + '.', + ]), + ); + expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); + }, + ); test('dartFormat with args', () { final argParser = FormatTool().toCommand('t').argParser; final argResults = argParser.parse(['--formatter-args', '--indent 2']); final context = DevToolExecutionContext(argResults: argResults); - final execution = buildExecution(context, - configuredFormatterArgs: ['--fix', '--follow-links'], - formatter: Formatter.dartFormat); + final execution = buildExecution( + context, + configuredFormatterArgs: ['--fix', '--follow-links'], + formatter: Formatter.dartFormat, + ); expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dart); expect( - execution.formatProcess!.args, - orderedEquals([ - 'format', - if (dartSemverVersion.major >= 3) '--language-version=latest', - '--fix', - '--follow-links', - '--indent', - '2', - '.', - ])); + execution.formatProcess!.args, + orderedEquals([ + 'format', + if (dartSemverVersion.major >= 3) '--language-version=latest', + '--fix', + '--follow-links', + '--indent', + '2', + '.', + ]), + ); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); @@ -454,33 +583,46 @@ void main() { expect(execution.exitCode, isNull); expect(execution.formatProcess!.executable, exe.dart); expect( - execution.formatProcess!.args, - orderedEquals([ - 'format', - if (dartSemverVersion.major >= 3) '--language-version=3.0', - '.', - ])); + execution.formatProcess!.args, + orderedEquals([ + 'format', + if (dartSemverVersion.major >= 3) '--language-version=3.0', + '.', + ]), + ); expect(execution.formatProcess!.mode, ProcessStartMode.inheritStdio); }); test('and logs the test subprocess by default', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('${exe.dartfmt} .')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('${exe.dartfmt} .'))), + ); buildExecution(DevToolExecutionContext()); }); test('and logs the test subprocess for dart format', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains([ - exe.dart, - 'format', - if (dartSemverVersion.major >= 3) '--language-version=latest', - '.', - ].join(' '))))); - - buildExecution(DevToolExecutionContext(), - formatter: Formatter.dartFormat); + expect( + Logger.root.onRecord, + emitsThrough( + infoLogOf( + contains( + [ + exe.dart, + 'format', + if (dartSemverVersion.major >= 3) '--language-version=latest', + '.', + ].join(' '), + ), + ), + ), + ); + + buildExecution( + DevToolExecutionContext(), + formatter: Formatter.dartFormat, + ); }); test('sorts imports when organizeImports is true', () { @@ -537,22 +679,32 @@ void main() { group('logFormatCommand', () { test('<=5 inputs and verbose=false', () async { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dartfmt -x -y a b')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dartfmt -x -y a b'))), + ); logCommand('dartfmt', ['a', 'b'], ['-x', '-y']); }); test('>5 inputs and verbose=true', () async { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dartfmt -x -y <6 paths>')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dartfmt -x -y <6 paths>'))), + ); logCommand('dartfmt', ['a', 'b', 'c', 'd', 'e', 'f'], ['-x', '-y']); }); test('>5 inputs and verbose=false', () async { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dartfmt -x -y a b c d e f')))); - logCommand('dartfmt', ['a', 'b', 'c', 'd', 'e', 'f'], ['-x', '-y'], - verbose: true); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dartfmt -x -y a b c d e f'))), + ); + logCommand( + 'dartfmt', + ['a', 'b', 'c', 'd', 'e', 'f'], + ['-x', '-y'], + verbose: true, + ); }); }); @@ -562,59 +714,93 @@ void main() { setUp(() { argParser = FormatTool().toCommand('test_format').argParser; - usageException = - DevToolExecutionContext(commandName: 'test_format').usageException; + usageException = DevToolExecutionContext( + commandName: 'test_format', + ).usageException; }); test('--check and --dry-run and --overwrite throws UsageException', () { - final argResults = - argParser.parse(['--check', '--dry-run', '--overwrite']); + final argResults = argParser.parse([ + '--check', + '--dry-run', + '--overwrite', + ]); expect( - () => validateAndParseMode(argResults, usageException), - throwsA(isA().having((e) => e.message, 'usage footer', - contains('--check and --dry-run and --overwrite')))); + () => validateAndParseMode(argResults, usageException), + throwsA( + isA().having( + (e) => e.message, + 'usage footer', + contains('--check and --dry-run and --overwrite'), + ), + ), + ); }); test('--check and --dry-run throws UsageException', () { final argResults = argParser.parse(['--check', '--dry-run']); expect( - () => validateAndParseMode(argResults, usageException), - throwsA(isA().having((e) => e.message, 'usage footer', - contains('--check and --dry-run')))); + () => validateAndParseMode(argResults, usageException), + throwsA( + isA().having( + (e) => e.message, + 'usage footer', + contains('--check and --dry-run'), + ), + ), + ); }); test('--check and --overwrite throws UsageException', () { final argResults = argParser.parse(['--check', '--overwrite']); expect( - () => validateAndParseMode(argResults, usageException), - throwsA(isA().having((e) => e.message, 'usage footer', - contains('--check and --overwrite')))); + () => validateAndParseMode(argResults, usageException), + throwsA( + isA().having( + (e) => e.message, + 'usage footer', + contains('--check and --overwrite'), + ), + ), + ); }); test('--dry-run and --overwrite throws UsageException', () { final argResults = argParser.parse(['--dry-run', '--overwrite']); expect( - () => validateAndParseMode(argResults, usageException), - throwsA(isA().having((e) => e.message, 'usage footer', - contains('--dry-run and --overwrite')))); + () => validateAndParseMode(argResults, usageException), + throwsA( + isA().having( + (e) => e.message, + 'usage footer', + contains('--dry-run and --overwrite'), + ), + ), + ); }); test('--check', () { final argResults = argParser.parse(['--check']); expect( - validateAndParseMode(argResults, usageException), FormatMode.check); + validateAndParseMode(argResults, usageException), + FormatMode.check, + ); }); test('--dry-run', () { final argResults = argParser.parse(['--dry-run']); expect( - validateAndParseMode(argResults, usageException), FormatMode.dryRun); + validateAndParseMode(argResults, usageException), + FormatMode.dryRun, + ); }); test('--overwrite', () { final argResults = argParser.parse(['--overwrite']); - expect(validateAndParseMode(argResults, usageException), - FormatMode.overwrite); + expect( + validateAndParseMode(argResults, usageException), + FormatMode.overwrite, + ); }); test('no mode flag', () { diff --git a/test/tools/function_tool_test.dart b/test/tools/function_tool_test.dart index c6c7dbe3..8eef6640 100644 --- a/test/tools/function_tool_test.dart +++ b/test/tools/function_tool_test.dart @@ -17,14 +17,18 @@ void main() { expect(await tool.run(), 1); }); - test('throws UsageException when no ArgParser given but args are present', - () { - final tool = DevTool.fromFunction((_) => 0); - expect( + test( + 'throws UsageException when no ArgParser given but args are present', + () { + final tool = DevTool.fromFunction((_) => 0); + expect( () => tool.run( - DevToolExecutionContext(argResults: ArgParser().parse(['foo']))), - throwsA(isA())); - }); + DevToolExecutionContext(argResults: ArgParser().parse(['foo'])), + ), + throwsA(isA()), + ); + }, + ); test('accepts a custom ArgParser', () async { final parser = ArgParser()..addFlag('flag'); @@ -32,19 +36,23 @@ void main() { expect(context.argResults!['flag'], isTrue); return 0; }, argParser: parser); - await tool - .run(DevToolExecutionContext(argResults: parser.parse(['--flag']))); + await tool.run( + DevToolExecutionContext(argResults: parser.parse(['--flag'])), + ); }); test('allows a custom ArgParser and args after a separator', () async { final tool = DevTool.fromFunction((_) => 0, argParser: ArgParser()); - await tool.run(DevToolExecutionContext( - argResults: ArgParser().parse(['--', 'foo']))); + await tool.run( + DevToolExecutionContext(argResults: ArgParser().parse(['--', 'foo'])), + ); }); test('logs a warning if no exit code is returned', () { - expect(Logger.root.onRecord, - emitsThrough(warningLogOf(contains('did not return an exit code')))); + expect( + Logger.root.onRecord, + emitsThrough(warningLogOf(contains('did not return an exit code'))), + ); DevTool.fromFunction((_) => null).run(); }); }); diff --git a/test/tools/process_tool_test.dart b/test/tools/process_tool_test.dart index f20849d1..7a01dde9 100644 --- a/test/tools/process_tool_test.dart +++ b/test/tools/process_tool_test.dart @@ -21,8 +21,9 @@ void main() { }); test('can run from a custom working directory', () async { - final tool = DevTool.fromProcess('pwd', [], workingDirectory: 'lib') - as ProcessTool; + final tool = + DevTool.fromProcess('pwd', [], workingDirectory: 'lib') + as ProcessTool; expect(await tool.run(), isZero); final stdout = (await tool.process!.stdout.transform(utf8.decoder).join('')).trim(); @@ -32,14 +33,18 @@ void main() { test('throws UsageException when args are present', () { final tool = DevTool.fromProcess('true', []); expect( - () => tool.run( - DevToolExecutionContext(argResults: ArgParser().parse(['foo']))), - throwsA(isA())); + () => tool.run( + DevToolExecutionContext(argResults: ArgParser().parse(['foo'])), + ), + throwsA(isA()), + ); }); test('logs the subprocess', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('true foo bar')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('true foo bar'))), + ); DevTool.fromProcess('true', ['foo', 'bar']).run(); }); }); @@ -48,16 +53,18 @@ void main() { sharedDevToolTests(() => BackgroundProcessTool('true', []).starter); sharedDevToolTests(() => BackgroundProcessTool('true', []).stopper); - test('starter runs the process without waiting for it to complete', - () async { - var processHasExited = false; - final tool = BackgroundProcessTool('sleep', ['5']); - expect(await tool.starter.run(), isZero); - unawaited(tool.process!.exitCode.then((_) => processHasExited = true)); - await Future.delayed(Duration.zero); - expect(processHasExited, isFalse); - await tool.stopper.run(); - }); + test( + 'starter runs the process without waiting for it to complete', + () async { + var processHasExited = false; + final tool = BackgroundProcessTool('sleep', ['5']); + expect(await tool.starter.run(), isZero); + unawaited(tool.process!.exitCode.then((_) => processHasExited = true)); + await Future.delayed(Duration.zero); + expect(processHasExited, isFalse); + await tool.stopper.run(); + }, + ); test('stopper stops the process immediately', () async { var processHasExited = false; @@ -73,8 +80,11 @@ void main() { }); test('starter forwards the returned exit code', () async { - final tool = BackgroundProcessTool('false', [], - delayAfterStart: Duration(milliseconds: 500)); + final tool = BackgroundProcessTool( + 'false', + [], + delayAfterStart: Duration(milliseconds: 500), + ); expect(await tool.starter.run(), isNonZero); }); @@ -86,8 +96,12 @@ void main() { }); test('can run from a custom working directory', () async { - final tool = BackgroundProcessTool('pwd', [], - workingDirectory: 'lib', delayAfterStart: Duration(seconds: 1)); + final tool = BackgroundProcessTool( + 'pwd', + [], + workingDirectory: 'lib', + delayAfterStart: Duration(seconds: 1), + ); expect(await tool.starter.run(), isZero); final stdout = (await tool.process!.stdout.transform(utf8.decoder).join('')).trim(); @@ -97,14 +111,18 @@ void main() { test('throws UsageException when args are present', () { final tool = BackgroundProcessTool('true', []); expect( - () => tool.starter.run( - DevToolExecutionContext(argResults: ArgParser().parse(['foo']))), - throwsA(isA())); + () => tool.starter.run( + DevToolExecutionContext(argResults: ArgParser().parse(['foo'])), + ), + throwsA(isA()), + ); }); test('logs the subprocess', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('true foo bar')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('true foo bar'))), + ); BackgroundProcessTool('true', ['foo', 'bar']).starter.run(); }); }); diff --git a/test/tools/shared_tool_tests.dart b/test/tools/shared_tool_tests.dart index b1900f80..52ec9083 100644 --- a/test/tools/shared_tool_tests.dart +++ b/test/tools/shared_tool_tests.dart @@ -8,8 +8,10 @@ void sharedDevToolTests(DevTool Function() factory) { }); test('should return a command with a customizable description', () { - expect((factory()..description = 'desc').toCommand('test').description, - 'desc'); + expect( + (factory()..description = 'desc').toCommand('test').description, + 'desc', + ); }); test('should return a command with a customizable hidden value', () { diff --git a/test/tools/test_tool_test.dart b/test/tools/test_tool_test.dart index 7c870771..65862360 100644 --- a/test/tools/test_tool_test.dart +++ b/test/tools/test_tool_test.dart @@ -20,15 +20,16 @@ void main() { test('toCommand overrides the argParser', () { final argParser = TestTool().toCommand('t').argParser; expect( - argParser.options.keys, - containsAll([ - 'name', - 'plain-name', - 'preset', - 'release', - 'test-args', - 'build-args', - ])); + argParser.options.keys, + containsAll([ + 'name', + 'plain-name', + 'preset', + 'release', + 'test-args', + 'build-args', + ]), + ); expect(argParser.options['name']!.type, OptionType.multiple); expect(argParser.options['name']!.abbr, 'n'); @@ -58,29 +59,37 @@ void main() { test('forwards the -n|--name options', () { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['-n', 'foo', '-n', 'bar']); - expect(buildArgs(argResults: argResults), - orderedEquals(['test', '--name=foo', '--name=bar'])); + expect( + buildArgs(argResults: argResults), + orderedEquals(['test', '--name=foo', '--name=bar']), + ); }); test('forwards the -N|--plain-name options', () { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['-N', 'foo', '-N', 'bar']); - expect(buildArgs(argResults: argResults), - orderedEquals(['test', '--plain-name=foo', '--plain-name=bar'])); + expect( + buildArgs(argResults: argResults), + orderedEquals(['test', '--plain-name=foo', '--plain-name=bar']), + ); }); test('forwards the -P|--preset options', () { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['-P', 'foo', '-P', 'bar']); - expect(buildArgs(argResults: argResults), - orderedEquals(['test', '--preset=foo', '--preset=bar'])); + expect( + buildArgs(argResults: argResults), + orderedEquals(['test', '--preset=foo', '--preset=bar']), + ); }); test('forwards the --reporter option', () { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--reporter', 'expanded']); - expect(buildArgs(argResults: argResults), - orderedEquals(['test', '--reporter=expanded'])); + expect( + buildArgs(argResults: argResults), + orderedEquals(['test', '--reporter=expanded']), + ); }); group('with useBuildTest=false', () { @@ -88,20 +97,24 @@ void main() { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--test-args', '-N foo']); expect( - buildArgs( - argResults: argResults, configuredTestArgs: ['-P', 'unit']), - orderedEquals(['test', '-P', 'unit', '-N', 'foo'])); + buildArgs(argResults: argResults, configuredTestArgs: ['-P', 'unit']), + orderedEquals(['test', '-P', 'unit', '-N', 'foo']), + ); }); test('ignores build args if given', () { final argParser = TestTool().toCommand('t').argParser; - final argResults = - argParser.parse(['--build-args', '--delete-conflicting-outputs']); + final argResults = argParser.parse([ + '--build-args', + '--delete-conflicting-outputs', + ]); expect( - buildArgs( - argResults: argResults, - configuredBuildArgs: ['-o', 'test:build']), - orderedEquals(['test'])); + buildArgs( + argResults: argResults, + configuredBuildArgs: ['-o', 'test:build'], + ), + orderedEquals(['test']), + ); }); }); @@ -109,48 +122,27 @@ void main() { test('forwards the --release flag', () { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--release']); - expect(buildArgs(argResults: argResults, useBuildRunner: true), - orderedEquals(['run', 'build_runner', 'test', '--release'])); + expect( + buildArgs(argResults: argResults, useBuildRunner: true), + orderedEquals(['run', 'build_runner', 'test', '--release']), + ); }); test('combines configured args with cli args (in that order)', () { final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser - .parse(['--build-args', '--config bar', '--test-args', '-N foo']); + final argResults = argParser.parse([ + '--build-args', + '--config bar', + '--test-args', + '-N foo', + ]); expect( - buildArgs( - argResults: argResults, - configuredBuildArgs: ['-o', 'test:build'], - configuredTestArgs: ['-P', 'unit'], - useBuildRunner: true), - orderedEquals([ - 'run', - 'build_runner', - 'test', - '-o', - 'test:build', - '--config', - 'bar', - '--', - '-P', - 'unit', - '-N', - 'foo' - ])); - }); - }); - - test('inserts a verbose flag if not already present', () { - final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser - .parse(['--build-args', '--config bar', '--test-args', '-N foo']); - expect( buildArgs( - argResults: argResults, - configuredBuildArgs: ['-o', 'test:build'], - configuredTestArgs: ['-P', 'unit'], - useBuildRunner: true, - verbose: true), + argResults: argResults, + configuredBuildArgs: ['-o', 'test:build'], + configuredTestArgs: ['-P', 'unit'], + useBuildRunner: true, + ), orderedEquals([ 'run', 'build_runner', @@ -159,29 +151,70 @@ void main() { 'test:build', '--config', 'bar', - '-v', '--', '-P', 'unit', '-N', 'foo', - ])); + ]), + ); + }); + }); + + test('inserts a verbose flag if not already present', () { + final argParser = TestTool().toCommand('t').argParser; + final argResults = argParser.parse([ + '--build-args', + '--config bar', + '--test-args', + '-N foo', + ]); + expect( + buildArgs( + argResults: argResults, + configuredBuildArgs: ['-o', 'test:build'], + configuredTestArgs: ['-P', 'unit'], + useBuildRunner: true, + verbose: true, + ), + orderedEquals([ + 'run', + 'build_runner', + 'test', + '-o', + 'test:build', + '--config', + 'bar', + '-v', + '--', + '-P', + 'unit', + '-N', + 'foo', + ]), + ); }); test('does not insert a duplicate verbose flag (-v)', () { expect( - buildArgs( - configuredBuildArgs: ['-v'], useBuildRunner: true, verbose: true), - orderedEquals(['run', 'build_runner', 'test', '-v'])); + buildArgs( + configuredBuildArgs: ['-v'], + useBuildRunner: true, + verbose: true, + ), + orderedEquals(['run', 'build_runner', 'test', '-v']), + ); }); test('does not insert a duplicate verbose flag (--verbose)', () { expect( - buildArgs( - configuredBuildArgs: ['--verbose'], - useBuildRunner: true, - verbose: true), - orderedEquals(['run', 'build_runner', 'test', '--verbose'])); + buildArgs( + configuredBuildArgs: ['--verbose'], + useBuildRunner: true, + verbose: true, + ), + orderedEquals(['run', 'build_runner', 'test', '--verbose']), + ); }); group('supports test args after a separator', () { @@ -189,45 +222,53 @@ void main() { final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--', '-r', 'json', '-j1']); expect( - buildArgs(argResults: argResults, useBuildRunner: true), - orderedEquals([ - 'run', - 'build_runner', - 'test', - '--', - '-r', - 'json', - '-j1', - ])); + buildArgs(argResults: argResults, useBuildRunner: true), + orderedEquals([ + 'run', + 'build_runner', + 'test', + '--', + '-r', + 'json', + '-j1', + ]), + ); }); test('with a test file', () { final argParser = TestTool().toCommand('t').argParser; - final argResults = - argParser.parse(['--', '-r', 'json', '-j1', 'test/foo_test.dart']); + final argResults = argParser.parse([ + '--', + '-r', + 'json', + '-j1', + 'test/foo_test.dart', + ]); expect( - buildArgs(argResults: argResults, useBuildRunner: true), - orderedEquals([ - 'run', - 'build_runner', - 'test', - '--build-filter=test/foo_test.dart.*_test.dart.js*', - '--build-filter=test/foo_test.html', - '--', - '-r', - 'json', - '-j1', - 'test/foo_test.dart', - ])); + buildArgs(argResults: argResults, useBuildRunner: true), + orderedEquals([ + 'run', + 'build_runner', + 'test', + '--build-filter=test/foo_test.dart.*_test.dart.js*', + '--build-filter=test/foo_test.html', + '--', + '-r', + 'json', + '-j1', + 'test/foo_test.dart', + ]), + ); }); }); }); group('buildExecution', () { test( - 'throws UsageException if --build-args is used but build_runner is not ' - 'a direct dependency', () async { - await d.file('pubspec.yaml', ''' + 'throws UsageException if --build-args is used but build_runner is not ' + 'a direct dependency', + () async { + await d.file('pubspec.yaml', ''' name: _test publish_to: none environment: @@ -236,18 +277,21 @@ dev_dependencies: build_test: any test: any ''').create(); - final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser.parse(['--build-args', 'foo']); - final context = DevToolExecutionContext(argResults: argResults); - expect( + final argParser = TestTool().toCommand('t').argParser; + final argResults = argParser.parse(['--build-args', 'foo']); + final context = DevToolExecutionContext(argResults: argResults); + expect( () => buildExecution(context, path: d.sandbox), - throwsA(isA() - .having((e) => e.message, 'help', contains('--build-args')) - .having((e) => e.message, 'help', contains('build_runner')))); - }); - - test( - 'throws UsageException if --build-args is used but build_test is not ' + throwsA( + isA() + .having((e) => e.message, 'help', contains('--build-args')) + .having((e) => e.message, 'help', contains('build_runner')), + ), + ); + }, + ); + + test('throws UsageException if --build-args is used but build_test is not ' 'a direct dependency', () async { await d.file('pubspec.yaml', ''' name: _test @@ -262,39 +306,58 @@ dev_dependencies: final argResults = argParser.parse(['--build-args', 'foo']); final context = DevToolExecutionContext(argResults: argResults); expect( - () => buildExecution(context, path: d.sandbox), - throwsA(isA() + () => buildExecution(context, path: d.sandbox), + throwsA( + isA() .having((e) => e.message, 'help', contains('--build-args')) - .having((e) => e.message, 'help', contains('build_test')))); + .having((e) => e.message, 'help', contains('build_test')), + ), + ); }); - test('returns config exit code and logs if test is not a direct dependency', - () async { - expect( + test( + 'returns config exit code and logs if test is not a direct dependency', + () async { + expect( Logger.root.onRecord, - emitsThrough(severeLogOf(allOf(contains('Cannot run tests'), - contains('"test" in pubspec.yaml'))))); - await d.file('pubspec.yaml', ''' + emitsThrough( + severeLogOf( + allOf( + contains('Cannot run tests'), + contains('"test" in pubspec.yaml'), + ), + ), + ), + ); + await d.file('pubspec.yaml', ''' name: _test publish_to: none environment: sdk: '>=2.12.0 <3.0.0' ''').create(); - final context = DevToolExecutionContext(); - expect(buildExecution(context, path: d.sandbox).exitCode, - ExitCode.config.code); - }); + final context = DevToolExecutionContext(); + expect( + buildExecution(context, path: d.sandbox).exitCode, + ExitCode.config.code, + ); + }, + ); - test( - 'returns config exit code and logs if configured to run tests with ' + test('returns config exit code and logs if configured to run tests with ' 'build args but build_runner is not a direct dependency', () async { expect( - Logger.root.onRecord, - emitsThrough(severeLogOf(allOf( + Logger.root.onRecord, + emitsThrough( + severeLogOf( + allOf( contains('missing a direct dependency on'), contains('build_runner'), contains('tool/dart_dev/config.dart'), - contains('pubspec.yaml'))))); + contains('pubspec.yaml'), + ), + ), + ), + ); await d.file('pubspec.yaml', ''' name: _test publish_to: none @@ -306,22 +369,30 @@ dev_dependencies: ''').create(); final context = DevToolExecutionContext(); expect( - buildExecution(context, - configuredBuildArgs: ['-o', 'test:build'], path: d.sandbox) - .exitCode, - ExitCode.config.code); + buildExecution( + context, + configuredBuildArgs: ['-o', 'test:build'], + path: d.sandbox, + ).exitCode, + ExitCode.config.code, + ); }); - test( - 'returns config exit code and logs if configured to run tests with ' + test('returns config exit code and logs if configured to run tests with ' 'build args but build_test is not a direct dependency', () async { expect( - Logger.root.onRecord, - emitsThrough(severeLogOf(allOf( + Logger.root.onRecord, + emitsThrough( + severeLogOf( + allOf( contains('missing a direct dependency on'), contains('build_test'), contains('tool/dart_dev/config.dart'), - contains('pubspec.yaml'))))); + contains('pubspec.yaml'), + ), + ), + ), + ); await d.file('pubspec.yaml', ''' name: _test publish_to: none @@ -333,10 +404,13 @@ dev_dependencies: ''').create(); final context = DevToolExecutionContext(); expect( - buildExecution(context, - configuredBuildArgs: ['-o', 'test:build'], path: d.sandbox) - .exitCode, - ExitCode.config.code); + buildExecution( + context, + configuredBuildArgs: ['-o', 'test:build'], + path: d.sandbox, + ).exitCode, + ExitCode.config.code, + ); }); group('returns a TestExecution', () { @@ -365,12 +439,17 @@ dev_dependencies: final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--test-args', '-n foo']); final context = DevToolExecutionContext(argResults: argResults); - final execution = buildExecution(context, - configuredTestArgs: ['-P', 'unit'], path: d.sandbox); + final execution = buildExecution( + context, + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); - expect(execution.process!.args, - orderedEquals(['test', '-P', 'unit', '-n', 'foo'])); + expect( + execution.process!.args, + orderedEquals(['test', '-P', 'unit', '-n', 'foo']), + ); }); test('with args after a separator', () { @@ -384,29 +463,36 @@ dev_dependencies: }); test( - 'and logs a warning if --release is used in a non-build project', - () => overrideAnsiOutput(false, () { - expect( - Logger.root.onRecord, - emitsThrough(warningLogOf( - contains('The --release flag is only applicable')))); - - final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser.parse(['--release']); - final context = - DevToolExecutionContext(argResults: argResults); - buildExecution(context, path: d.sandbox); - })); + 'and logs a warning if --release is used in a non-build project', + () => overrideAnsiOutput(false, () { + expect( + Logger.root.onRecord, + emitsThrough( + warningLogOf(contains('The --release flag is only applicable')), + ), + ); + + final argParser = TestTool().toCommand('t').argParser; + final argResults = argParser.parse(['--release']); + final context = DevToolExecutionContext(argResults: argResults); + buildExecution(context, path: d.sandbox); + }), + ); test('and logs the test subprocess', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dart test -P unit -n foo')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dart test -P unit -n foo'))), + ); final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--test-args', '-n foo']); final context = DevToolExecutionContext(argResults: argResults); - buildExecution(context, - configuredTestArgs: ['-P', 'unit'], path: d.sandbox); + buildExecution( + context, + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); }); }); @@ -435,12 +521,17 @@ dev_dependencies: final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--test-args', '-n foo']); final context = DevToolExecutionContext(argResults: argResults); - final execution = buildExecution(context, - configuredTestArgs: ['-P', 'unit'], path: d.sandbox); + final execution = buildExecution( + context, + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); - expect(execution.process!.args, - orderedEquals(['test', '-P', 'unit', '-n', 'foo'])); + expect( + execution.process!.args, + orderedEquals(['test', '-P', 'unit', '-n', 'foo']), + ); }); test('with args after a separator', () { @@ -454,29 +545,36 @@ dev_dependencies: }); test( - 'and logs a warning if --release is used in a non-build project', - () => overrideAnsiOutput(false, () { - expect( - Logger.root.onRecord, - emitsThrough(warningLogOf( - contains('The --release flag is only applicable')))); - - final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser.parse(['--release']); - final context = - DevToolExecutionContext(argResults: argResults); - buildExecution(context, path: d.sandbox); - })); + 'and logs a warning if --release is used in a non-build project', + () => overrideAnsiOutput(false, () { + expect( + Logger.root.onRecord, + emitsThrough( + warningLogOf(contains('The --release flag is only applicable')), + ), + ); + + final argParser = TestTool().toCommand('t').argParser; + final argResults = argParser.parse(['--release']); + final context = DevToolExecutionContext(argResults: argResults); + buildExecution(context, path: d.sandbox); + }), + ); test('and logs the test subprocess', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(contains('dart test -P unit -n foo')))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(contains('dart test -P unit -n foo'))), + ); final argParser = TestTool().toCommand('t').argParser; final argResults = argParser.parse(['--test-args', '-n foo']); final context = DevToolExecutionContext(argResults: argResults); - buildExecution(context, - configuredTestArgs: ['-P', 'unit'], path: d.sandbox); + buildExecution( + context, + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); }); }); @@ -499,36 +597,45 @@ dev_dependencies: final execution = buildExecution(context, path: d.sandbox); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); - expect(execution.process!.args, - orderedEquals(['run', 'build_runner', 'test'])); + expect( + execution.process!.args, + orderedEquals(['run', 'build_runner', 'test']), + ); }); test('with args', () { final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--build-args', '-o test:build', '--test-args', '-n foo']); + final argResults = argParser.parse([ + '--build-args', + '-o test:build', + '--test-args', + '-n foo', + ]); final context = DevToolExecutionContext(argResults: argResults); - final execution = buildExecution(context, - configuredBuildArgs: ['foo'], - configuredTestArgs: ['-P', 'unit'], - path: d.sandbox); + final execution = buildExecution( + context, + configuredBuildArgs: ['foo'], + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, - orderedEquals([ - 'run', - 'build_runner', - 'test', - 'foo', - '-o', - 'test:build', - '--', - '-P', - 'unit', - '-n', - 'foo' - ])); + execution.process!.args, + orderedEquals([ + 'run', + 'build_runner', + 'test', + 'foo', + '-o', + 'test:build', + '--', + '-P', + 'unit', + '-n', + 'foo', + ]), + ); }); test('with args after a separator', () { @@ -539,61 +646,77 @@ dev_dependencies: expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, - orderedEquals([ - 'run', - 'build_runner', - 'test', - '--', - '-j1', - ])); + execution.process!.args, + orderedEquals(['run', 'build_runner', 'test', '--', '-j1']), + ); }); test('with verbose=true', () { final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--build-args', '-o test:build', '--test-args', '-n foo']); - final context = - DevToolExecutionContext(argResults: argResults, verbose: true); - final execution = buildExecution(context, - configuredBuildArgs: ['foo'], - configuredTestArgs: ['-P', 'unit'], - path: d.sandbox); + final argResults = argParser.parse([ + '--build-args', + '-o test:build', + '--test-args', + '-n foo', + ]); + final context = DevToolExecutionContext( + argResults: argResults, + verbose: true, + ); + final execution = buildExecution( + context, + configuredBuildArgs: ['foo'], + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, - orderedEquals([ - 'run', - 'build_runner', - 'test', - 'foo', - '-o', - 'test:build', - '-v', - '--', - '-P', - 'unit', - '-n', - 'foo', - ])); + execution.process!.args, + orderedEquals([ + 'run', + 'build_runner', + 'test', + 'foo', + '-o', + 'test:build', + '-v', + '--', + '-P', + 'unit', + '-n', + 'foo', + ]), + ); }); test('and logs the test subprocess', () { expect( - Logger.root.onRecord, - emitsThrough(infoLogOf(contains( + Logger.root.onRecord, + emitsThrough( + infoLogOf( + contains( 'dart run build_runner test foo -o test:build -- -P unit ' - '-n foo')))); + '-n foo', + ), + ), + ), + ); final argParser = TestTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--build-args', '-o test:build', '--test-args', '-n foo']); + final argResults = argParser.parse([ + '--build-args', + '-o test:build', + '--test-args', + '-n foo', + ]); final context = DevToolExecutionContext(argResults: argResults); - buildExecution(context, - configuredBuildArgs: ['foo'], - configuredTestArgs: ['-P', 'unit'], - path: d.sandbox); + buildExecution( + context, + configuredBuildArgs: ['foo'], + configuredTestArgs: ['-P', 'unit'], + path: d.sandbox, + ); }); }); }); diff --git a/test/tools/tuneup_check_tool_test.dart b/test/tools/tuneup_check_tool_test.dart index 1e825d2c..8ec17a31 100644 --- a/test/tools/tuneup_check_tool_test.dart +++ b/test/tools/tuneup_check_tool_test.dart @@ -30,19 +30,25 @@ void main() { }); test('configured ignoreInfos', () { - expect(buildArgs(configuredIgnoreInfos: true), - orderedEquals(['run', 'tuneup', 'check', '--ignore-infos'])); + expect( + buildArgs(configuredIgnoreInfos: true), + orderedEquals(['run', 'tuneup', 'check', '--ignore-infos']), + ); }); test('--ignore-infos', () { final argResults = TuneupCheckTool().argParser.parse(['--ignore-infos']); - expect(buildArgs(argResults: argResults), - orderedEquals(['run', 'tuneup', 'check', '--ignore-infos'])); + expect( + buildArgs(argResults: argResults), + orderedEquals(['run', 'tuneup', 'check', '--ignore-infos']), + ); }); test('verbose', () { - expect(buildArgs(verbose: true), - orderedEquals(['run', 'tuneup', 'check', '--verbose'])); + expect( + buildArgs(verbose: true), + orderedEquals(['run', 'tuneup', 'check', '--verbose']), + ); }); }); @@ -50,22 +56,39 @@ void main() { test('throws UsageException if positional args are given', () { final argResults = ArgParser().parse(['a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_tuneup'); + argResults: argResults, + commandName: 'test_tuneup', + ); expect( - () => buildExecution(context), - throwsA(isA().having( - (e) => e.message, 'command name', contains('test_tuneup')))); + () => buildExecution(context), + throwsA( + isA().having( + (e) => e.message, + 'command name', + contains('test_tuneup'), + ), + ), + ); }); test('exits early and logs if tuneup is not an immediate dependency', () { expect( - Logger.root.onRecord, - emitsThrough(severeLogOf(allOf(contains('Cannot run "tuneup check"'), - contains('"tuneup" in pubspec.yaml'))))); + Logger.root.onRecord, + emitsThrough( + severeLogOf( + allOf( + contains('Cannot run "tuneup check"'), + contains('"tuneup" in pubspec.yaml'), + ), + ), + ), + ); final context = DevToolExecutionContext(); - final execution = buildExecution(context, - path: 'test/tools/fixtures/tuneup_check/missing_tuneup'); + final execution = buildExecution( + context, + path: 'test/tools/fixtures/tuneup_check/missing_tuneup', + ); expect(execution.exitCode, ExitCode.config.code); }); @@ -76,28 +99,41 @@ void main() { expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, orderedEquals(['run', 'tuneup', 'check'])); + execution.process!.args, + orderedEquals(['run', 'tuneup', 'check']), + ); expect(execution.process!.mode, ProcessStartMode.inheritStdio); }); test('with args', () { - final argResults = - TuneupCheckTool().argParser.parse(['--ignore-infos']); - final context = - DevToolExecutionContext(argResults: argResults, verbose: true); + final argResults = TuneupCheckTool().argParser.parse([ + '--ignore-infos', + ]); + final context = DevToolExecutionContext( + argResults: argResults, + verbose: true, + ); final execution = buildExecution(context, path: path); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, - orderedEquals( - ['run', 'tuneup', 'check', '--ignore-infos', '--verbose'])); + execution.process!.args, + orderedEquals([ + 'run', + 'tuneup', + 'check', + '--ignore-infos', + '--verbose', + ]), + ); expect(execution.process!.mode, ProcessStartMode.inheritStdio); }); test('and logs the subprocess header', () { - expect(Logger.root.onRecord, - emitsThrough(infoLogOf(allOf(contains('dart run tuneup check'))))); + expect( + Logger.root.onRecord, + emitsThrough(infoLogOf(allOf(contains('dart run tuneup check')))), + ); buildExecution(DevToolExecutionContext(), path: path); }); diff --git a/test/tools/webdev_serve_tool_test.dart b/test/tools/webdev_serve_tool_test.dart index 5699e126..1f8c00d1 100644 --- a/test/tools/webdev_serve_tool_test.dart +++ b/test/tools/webdev_serve_tool_test.dart @@ -20,8 +20,10 @@ void main() { test('toCommand overrides the argParser', () { final argParser = WebdevServeTool().toCommand('t').argParser; - expect(argParser.options.keys, - containsAll(['release', 'webdev-args', 'build-args'])); + expect( + argParser.options.keys, + containsAll(['release', 'webdev-args', 'build-args']), + ); expect(argParser.options['release']!.type, OptionType.flag); expect(argParser.options['release']!.abbr, 'r'); @@ -34,102 +36,128 @@ void main() { group('buildArgs', () { test('(default)', () { - expect(buildArgs(), - orderedEquals(['pub', 'global', 'run', 'webdev', 'serve'])); + expect( + buildArgs(), + orderedEquals(['pub', 'global', 'run', 'webdev', 'serve']), + ); }); test('forwards the -r|--release flag', () { final argParser = WebdevServeTool().toCommand('t').argParser; final argResults = argParser.parse(['-r']); expect( - buildArgs(argResults: argResults), - orderedEquals( - ['pub', 'global', 'run', 'webdev', 'serve', '--release'])); + buildArgs(argResults: argResults), + orderedEquals(['pub', 'global', 'run', 'webdev', 'serve', '--release']), + ); }); test('combines configured args with cli args (in that order)', () { final argParser = WebdevServeTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--webdev-args', '-r --debug', '--build-args', '--config foo']); + final argResults = argParser.parse([ + '--webdev-args', + '-r --debug', + '--build-args', + '--config foo', + ]); expect( - buildArgs( - argResults: argResults, - configuredBuildArgs: ['-o', 'web:build'], - configuredWebdevArgs: ['web:9000', 'example:9001']), - orderedEquals([ - 'pub', - 'global', - 'run', - 'webdev', - 'serve', - 'web:9000', - 'example:9001', - '-r', - '--debug', - '--', - '-o', - 'web:build', - '--config', - 'foo' - ])); + buildArgs( + argResults: argResults, + configuredBuildArgs: ['-o', 'web:build'], + configuredWebdevArgs: ['web:9000', 'example:9001'], + ), + orderedEquals([ + 'pub', + 'global', + 'run', + 'webdev', + 'serve', + 'web:9000', + 'example:9001', + '-r', + '--debug', + '--', + '-o', + 'web:build', + '--config', + 'foo', + ]), + ); }); test('inserts a verbose flag if not already present', () { final argParser = WebdevServeTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--webdev-args', '-r --debug', '--build-args', '--config foo']); + final argResults = argParser.parse([ + '--webdev-args', + '-r --debug', + '--build-args', + '--config foo', + ]); expect( - buildArgs( - argResults: argResults, - configuredBuildArgs: ['-o', 'web:build'], - configuredWebdevArgs: ['web:9000', 'example:9001'], - verbose: true), - orderedEquals([ - 'pub', - 'global', - 'run', - 'webdev', - 'serve', - 'web:9000', - 'example:9001', - '-r', - '--debug', - '-v', - '--', - '-o', - 'web:build', - '--config', - 'foo', - '-v' - ])); + buildArgs( + argResults: argResults, + configuredBuildArgs: ['-o', 'web:build'], + configuredWebdevArgs: ['web:9000', 'example:9001'], + verbose: true, + ), + orderedEquals([ + 'pub', + 'global', + 'run', + 'webdev', + 'serve', + 'web:9000', + 'example:9001', + '-r', + '--debug', + '-v', + '--', + '-o', + 'web:build', + '--config', + 'foo', + '-v', + ]), + ); }); test('does not insert a duplicate verbose flag (-v)', () { expect( - buildArgs( - configuredBuildArgs: ['-v'], - configuredWebdevArgs: ['-v'], - verbose: true), - orderedEquals( - ['pub', 'global', 'run', 'webdev', 'serve', '-v', '--', '-v'])); + buildArgs( + configuredBuildArgs: ['-v'], + configuredWebdevArgs: ['-v'], + verbose: true, + ), + orderedEquals([ + 'pub', + 'global', + 'run', + 'webdev', + 'serve', + '-v', + '--', + '-v', + ]), + ); }); test('does not insert a duplicate verbose flag (--verbose)', () { expect( - buildArgs( - configuredBuildArgs: ['--verbose'], - configuredWebdevArgs: ['--verbose'], - verbose: true), - orderedEquals([ - 'pub', - 'global', - 'run', - 'webdev', - 'serve', - '--verbose', - '--', - '--verbose' - ])); + buildArgs( + configuredBuildArgs: ['--verbose'], + configuredWebdevArgs: ['--verbose'], + verbose: true, + ), + orderedEquals([ + 'pub', + 'global', + 'run', + 'webdev', + 'serve', + '--verbose', + '--', + '--verbose', + ]), + ); }); }); @@ -139,8 +167,11 @@ void main() { setUpAll(() { pubCacheWithWebdev = TempPubCache(); - globalActivate('webdev', '^${dartSemverVersion.major}.0.0', - environment: pubCacheWithWebdev.envOverride); + globalActivate( + 'webdev', + '^${dartSemverVersion.major}.0.0', + environment: pubCacheWithWebdev.envOverride, + ); pubCacheWithoutWebdev = TempPubCache(); }); @@ -153,140 +184,189 @@ void main() { test('throws UsageException if positional args are given', () { final argResults = ArgParser().parse(['a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_serve'); + argResults: argResults, + commandName: 'test_serve', + ); expect( - () => buildExecution(context), - throwsA(isA() + () => buildExecution(context), + throwsA( + isA() .having((e) => e.message, 'command name', contains('test_serve')) .having((e) => e.message, 'usage', contains('--webdev-args')) - .having((e) => e.message, 'usage', contains('--build-args')))); + .having((e) => e.message, 'usage', contains('--build-args')), + ), + ); }); test('throws UsageException if args are given after a separator', () { final argResults = ArgParser().parse(['--', 'a']); final context = DevToolExecutionContext( - argResults: argResults, commandName: 'test_serve'); + argResults: argResults, + commandName: 'test_serve', + ); expect( - () => buildExecution(context), - throwsA(isA() + () => buildExecution(context), + throwsA( + isA() .having((e) => e.message, 'command name', contains('test_serve')) .having((e) => e.message, 'usage', contains('--webdev-args')) - .having((e) => e.message, 'usage', contains('--build-args')))); + .having((e) => e.message, 'usage', contains('--build-args')), + ), + ); }); - test('returns config exit code and logs if webdev is not globally activate', - () { - overrideAnsiOutput(false, () { - expect( + test( + 'returns config exit code and logs if webdev is not globally activate', + () { + overrideAnsiOutput(false, () { + expect( Logger.root.onRecord, - emitsThrough(severeLogOf(allOf( - contains('webdev serve could not run'), - contains( - 'dart pub global activate webdev ^${dartSemverVersion.major}.0.0'))))); + emitsThrough( + severeLogOf( + allOf( + contains('webdev serve could not run'), + contains( + 'dart pub global activate webdev ^${dartSemverVersion.major}.0.0', + ), + ), + ), + ), + ); - expect( - buildExecution(DevToolExecutionContext(), - environment: pubCacheWithoutWebdev.envOverride) - .exitCode, - ExitCode.config.code); - }); - }); + expect( + buildExecution( + DevToolExecutionContext(), + environment: pubCacheWithoutWebdev.envOverride, + ).exitCode, + ExitCode.config.code, + ); + }); + }, + ); group('returns a WebdevServeExecution', () { test('(default)', () { - final execution = buildExecution(DevToolExecutionContext(), - environment: pubCacheWithWebdev.envOverride); + final execution = buildExecution( + DevToolExecutionContext(), + environment: pubCacheWithWebdev.envOverride, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); - expect(execution.process!.args, - orderedEquals(['pub', 'global', 'run', 'webdev', 'serve'])); + expect( + execution.process!.args, + orderedEquals(['pub', 'global', 'run', 'webdev', 'serve']), + ); }); test('with args', () { final argParser = WebdevServeTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--webdev-args', '-r --debug', '--build-args', '--config foo']); + final argResults = argParser.parse([ + '--webdev-args', + '-r --debug', + '--build-args', + '--config foo', + ]); final context = DevToolExecutionContext(argResults: argResults); - final execution = buildExecution(context, - configuredBuildArgs: ['-o', 'web:build'], - configuredWebdevArgs: ['web:9000', 'example:9001'], - environment: pubCacheWithWebdev.envOverride); + final execution = buildExecution( + context, + configuredBuildArgs: ['-o', 'web:build'], + configuredWebdevArgs: ['web:9000', 'example:9001'], + environment: pubCacheWithWebdev.envOverride, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, - orderedEquals([ - 'pub', - 'global', - 'run', - 'webdev', - 'serve', - 'web:9000', - 'example:9001', - '-r', - '--debug', - '--', - '-o', - 'web:build', - '--config', - 'foo', - ])); + execution.process!.args, + orderedEquals([ + 'pub', + 'global', + 'run', + 'webdev', + 'serve', + 'web:9000', + 'example:9001', + '-r', + '--debug', + '--', + '-o', + 'web:build', + '--config', + 'foo', + ]), + ); }); test('with verbose=true', () { final argParser = WebdevServeTool().toCommand('t').argParser; - final argResults = argParser.parse( - ['--webdev-args', '-r --debug', '--build-args', '--config foo']); - final context = - DevToolExecutionContext(argResults: argResults, verbose: true); - final execution = buildExecution(context, - configuredBuildArgs: ['-o', 'web:build'], - configuredWebdevArgs: ['web:9000', 'example:9001'], - environment: pubCacheWithWebdev.envOverride); + final argResults = argParser.parse([ + '--webdev-args', + '-r --debug', + '--build-args', + '--config foo', + ]); + final context = DevToolExecutionContext( + argResults: argResults, + verbose: true, + ); + final execution = buildExecution( + context, + configuredBuildArgs: ['-o', 'web:build'], + configuredWebdevArgs: ['web:9000', 'example:9001'], + environment: pubCacheWithWebdev.envOverride, + ); expect(execution.exitCode, isNull); expect(execution.process!.executable, exe.dart); expect( - execution.process!.args, - orderedEquals([ - 'pub', - 'global', - 'run', - 'webdev', - 'serve', - 'web:9000', - 'example:9001', - '-r', - '--debug', - '-v', - '--', - '-o', - 'web:build', - '--config', - 'foo', - '-v', - ])); + execution.process!.args, + orderedEquals([ + 'pub', + 'global', + 'run', + 'webdev', + 'serve', + 'web:9000', + 'example:9001', + '-r', + '--debug', + '-v', + '--', + '-o', + 'web:build', + '--config', + 'foo', + '-v', + ]), + ); }); test('and logs the test subprocess', () { overrideAnsiOutput(false, () { expect( - Logger.root.onRecord, - emitsThrough(infoLogOf(contains( + Logger.root.onRecord, + emitsThrough( + infoLogOf( + contains( 'dart pub global run webdev serve web --auto restart -- ' - '--delete-conflicting-outputs -o test:build')))); + '--delete-conflicting-outputs -o test:build', + ), + ), + ), + ); final argParser = WebdevServeTool().toCommand('t').argParser; final argResults = argParser.parse([ '--webdev-args', '--auto restart', '--build-args', - '-o test:build' + '-o test:build', ]); final context = DevToolExecutionContext(argResults: argResults); - buildExecution(context, - configuredBuildArgs: ['--delete-conflicting-outputs'], - configuredWebdevArgs: ['web'], - environment: pubCacheWithWebdev.envOverride); + buildExecution( + context, + configuredBuildArgs: ['--delete-conflicting-outputs'], + configuredWebdevArgs: ['web'], + environment: pubCacheWithWebdev.envOverride, + ); }); }); }); diff --git a/test/utils.dart b/test/utils.dart index 0aeac19e..b2d58179 100644 --- a/test/utils.dart +++ b/test/utils.dart @@ -17,8 +17,11 @@ class TempPubCache { /// If non-null, [environment] will be passed to the [Process]. This provides a /// way to override certain things like the `PUB_CACHE` var that points pub to /// the global pub-cache directory. -void globalActivate(String packageName, String constraint, - {Map? environment}) { +void globalActivate( + String packageName, + String constraint, { + Map? environment, +}) { final result = Process.runSync( exe.dart, ['pub', 'global', 'activate', packageName, constraint], @@ -27,18 +30,23 @@ void globalActivate(String packageName, String constraint, stdoutEncoding: utf8, ); if (result.exitCode != 0) { - fail('Failed to global activate $packageName.\n' - 'Process stdout:\n' - '---------------\n' - '${result.stdout}\n' - 'Process stderr:\n' - '---------------\n' - '${result.stderr}\n'); + fail( + 'Failed to global activate $packageName.\n' + 'Process stdout:\n' + '---------------\n' + '${result.stdout}\n' + 'Process stderr:\n' + '---------------\n' + '${result.stderr}\n', + ); } expect( - globalPackageIsActiveAndCompatible( - packageName, VersionConstraint.parse(constraint), - environment: environment), - isTrue, - reason: "$packageName should be globally activated, but isn't."); + globalPackageIsActiveAndCompatible( + packageName, + VersionConstraint.parse(constraint), + environment: environment, + ), + isTrue, + reason: "$packageName should be globally activated, but isn't.", + ); } diff --git a/test/utils/arg_results_utils_test.dart b/test/utils/arg_results_utils_test.dart index 25fcb5c0..7114b799 100644 --- a/test/utils/arg_results_utils_test.dart +++ b/test/utils/arg_results_utils_test.dart @@ -87,7 +87,9 @@ void main() { test('throws ArgumentError on non-single-option value', () { final argResults = (ArgParser()..addFlag(opt)).parse(['--$opt']); expect( - () => splitSingleOptionValue(argResults, opt), throwsArgumentError); + () => splitSingleOptionValue(argResults, opt), + throwsArgumentError, + ); }); test('returns value as Iterable', () { diff --git a/test/utils/assert_no_positional_args_before_separator_test.dart b/test/utils/assert_no_positional_args_before_separator_test.dart index 04b651b4..7325334f 100644 --- a/test/utils/assert_no_positional_args_before_separator_test.dart +++ b/test/utils/assert_no_positional_args_before_separator_test.dart @@ -29,14 +29,19 @@ void main() { }); test( - 'calls usageException callback if assertion fails (beforeSeparator=true)', - () { - final argResults = ArgParser().parse(['positional', 'args']); - beforeSeparator = true; - assertNoPositionalArgs(commandName, argResults, usageException, - beforeSeparator: true); - expect(usageExceptionCalled, isTrue); - }); + 'calls usageException callback if assertion fails (beforeSeparator=true)', + () { + final argResults = ArgParser().parse(['positional', 'args']); + beforeSeparator = true; + assertNoPositionalArgs( + commandName, + argResults, + usageException, + beforeSeparator: true, + ); + expect(usageExceptionCalled, isTrue); + }, + ); test('does not call usageException callback if assertion passes', () { final argResults = ArgParser().parse([]); diff --git a/test/utils/dart_dev_paths_test.dart b/test/utils/dart_dev_paths_test.dart index aa09e9e6..90b87434 100644 --- a/test/utils/dart_dev_paths_test.dart +++ b/test/utils/dart_dev_paths_test.dart @@ -24,8 +24,10 @@ void main() { }); test('configFromRunScriptForDart', () { - expect(paths.configFromRunScriptForDart, - '../../tool/dart_dev/config.dart'); + expect( + paths.configFromRunScriptForDart, + '../../tool/dart_dev/config.dart', + ); }); test('legacyConfig', () { @@ -57,8 +59,10 @@ void main() { }); test('configFromRunScriptForDart', () { - expect(paths.configFromRunScriptForDart, - r'../../tool/dart_dev/config.dart'); + expect( + paths.configFromRunScriptForDart, + r'../../tool/dart_dev/config.dart', + ); }); test('legacyConfig', () { diff --git a/test/utils/format_tool_builder_test.dart b/test/utils/format_tool_builder_test.dart index 5a2d1134..598f9c83 100644 --- a/test/utils/format_tool_builder_test.dart +++ b/test/utils/format_tool_builder_test.dart @@ -1,5 +1,4 @@ @TestOn('vm') - import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:dart_dev/dart_dev.dart'; import 'package:dart_dev/src/tools/over_react_format_tool.dart'; @@ -27,7 +26,9 @@ void main() { expect(visitor.formatDevTool, isNotNull); expect(visitor.formatDevTool, isA()); expect( - (visitor.formatDevTool as OverReactFormatTool).lineLength, 120); + (visitor.formatDevTool as OverReactFormatTool).lineLength, + 120, + ); }); }); }); @@ -51,34 +52,40 @@ void main() { expect(visitor.formatDevTool, isNotNull); expect(visitor.formatDevTool, isA()); - expect((visitor.formatDevTool as FormatTool).formatter, - Formatter.dartfmt); + expect( + (visitor.formatDevTool as FormatTool).formatter, + Formatter.dartfmt, + ); }); test('dartFormat', () { final visitor = FormatToolBuilder(); - parseString(content: formatToolCascadeSrc(formatter: 'dartFormat')) - .unit - .accept(visitor); + parseString( + content: formatToolCascadeSrc(formatter: 'dartFormat'), + ).unit.accept(visitor); expect(visitor.formatDevTool, isNotNull); expect(visitor.formatDevTool, isA()); - expect((visitor.formatDevTool as FormatTool).formatter, - Formatter.dartFormat); + expect( + (visitor.formatDevTool as FormatTool).formatter, + Formatter.dartFormat, + ); }); test('dartStyle', () { final visitor = FormatToolBuilder(); - parseString(content: formatToolCascadeSrc(formatter: 'dartStyle')) - .unit - .accept(visitor); + parseString( + content: formatToolCascadeSrc(formatter: 'dartStyle'), + ).unit.accept(visitor); expect(visitor.formatDevTool, isNotNull); expect(visitor.formatDevTool, isA()); - expect((visitor.formatDevTool as FormatTool).formatter, - Formatter.dartStyle); + expect( + (visitor.formatDevTool as FormatTool).formatter, + Formatter.dartStyle, + ); }); }); @@ -89,16 +96,18 @@ void main() { expect(visitor.formatDevTool, isNotNull); expect(visitor.formatDevTool, isA()); - expect((visitor.formatDevTool as FormatTool).formatterArgs, - orderedEquals(['-l', '120'])); + expect( + (visitor.formatDevTool as FormatTool).formatterArgs, + orderedEquals(['-l', '120']), + ); }); test('detects languageVersion', () { final visitor = FormatToolBuilder(); - parseString(content: formatToolCascadeSrc(languageVersion: '3.0')) - .unit - .accept(visitor); + parseString( + content: formatToolCascadeSrc(languageVersion: '3.0'), + ).unit.accept(visitor); expect(visitor.formatDevTool, isNotNull); expect(visitor.formatDevTool, isA()); @@ -108,15 +117,16 @@ void main() { }); test( - 'sets the failedToDetectAKnownFormatter flag when an unknown FormatTool is being used', - () { - final visitor = FormatToolBuilder(); + 'sets the failedToDetectAKnownFormatter flag when an unknown FormatTool is being used', + () { + final visitor = FormatToolBuilder(); - parseString(content: unknownFormatterTool).unit.accept(visitor); + parseString(content: unknownFormatterTool).unit.accept(visitor); - expect(visitor.formatDevTool, isNull); - expect(visitor.failedToDetectAKnownFormatter, isTrue); - }); + expect(visitor.formatDevTool, isNull); + expect(visitor.failedToDetectAKnownFormatter, isTrue); + }, + ); }); } @@ -148,8 +158,10 @@ final config = { }; '''; -String formatToolCascadeSrc( - {String formatter = 'dartfmt', String? languageVersion}) => +String formatToolCascadeSrc({ + String formatter = 'dartfmt', + String? languageVersion, +}) => '''import 'package:dart_dev/dart_dev.dart'; import 'package:glob/glob.dart'; diff --git a/test/utils/get_dart_version_comment_test.dart b/test/utils/get_dart_version_comment_test.dart index 950af30b..b3d8acb5 100644 --- a/test/utils/get_dart_version_comment_test.dart +++ b/test/utils/get_dart_version_comment_test.dart @@ -7,18 +7,17 @@ void main() { group('getDartVersionComment returns the version comment in a Dart file', () { test('', () { expect( - getDartVersionComment([ - '//@dart=2.9', - '', - 'main() {}', - ].join('\n')), - '//@dart=2.9'); + getDartVersionComment(['//@dart=2.9', '', 'main() {}'].join('\n')), + '//@dart=2.9', + ); }); test('allowing for whitespace', () { expect(getDartVersionComment('//@dart=2.9'), '//@dart=2.9'); expect( - getDartVersionComment('// @dart = 2.9 '), '// @dart = 2.9 '); + getDartVersionComment('// @dart = 2.9 '), + '// @dart = 2.9 ', + ); }); test('regardless of which line it appears on', () { @@ -26,15 +25,19 @@ void main() { }); test( - 'ignores version comments that don\'t start at the beginning of the line', - () { - const wellFormedVersionComment = '//@dart=2.9'; - expect(getDartVersionComment(wellFormedVersionComment), isNotNull, - reason: 'test setup check'); + 'ignores version comments that don\'t start at the beginning of the line', + () { + const wellFormedVersionComment = '//@dart=2.9'; + expect( + getDartVersionComment(wellFormedVersionComment), + isNotNull, + reason: 'test setup check', + ); - expect(getDartVersionComment(' $wellFormedVersionComment'), isNull); - expect(getDartVersionComment('"$wellFormedVersionComment"'), isNull); - }); + expect(getDartVersionComment(' $wellFormedVersionComment'), isNull); + expect(getDartVersionComment('"$wellFormedVersionComment"'), isNull); + }, + ); test('ignores incomplete version comments', () { expect(getDartVersionComment('//@dart='), isNull); diff --git a/test/utils/organize_imports/organize_directives_test.dart b/test/utils/organize_imports/organize_directives_test.dart index 943a16b5..ed708336 100644 --- a/test/utils/organize_imports/organize_directives_test.dart +++ b/test/utils/organize_imports/organize_directives_test.dart @@ -5,16 +5,8 @@ import '../../tools/fixtures/organize_directives/directives.dart'; void main() { const testCases = [ - _TestCase( - '1. sorts dart imports alphabetically', - unorganized1, - organized1, - ), - _TestCase( - '2. sorts pkg imports alphabetically', - unorganized2, - organized2, - ), + _TestCase('1. sorts dart imports alphabetically', unorganized1, organized1), + _TestCase('2. sorts pkg imports alphabetically', unorganized2, organized2), _TestCase( '3. sorts relative imports alphabetically', unorganized3, diff --git a/test/utils/parse_imports_test.dart b/test/utils/parse_imports_test.dart index 5717f0f8..ecc16d91 100644 --- a/test/utils/parse_imports_test.dart +++ b/test/utils/parse_imports_test.dart @@ -16,16 +16,23 @@ void main() { 'utils/dart_dev_paths.dart', ]; group( - 'parseImports', - () => test('correctly returns all imports', - () => expect(parseImports(sampleFile), equals(expectedImportList)))); + 'parseImports', + () => test( + 'correctly returns all imports', + () => expect(parseImports(sampleFile), equals(expectedImportList)), + ), + ); group( - 'computePackageNamesFromImports', - () => test( - 'correctly computes package names from imports', - () => expect(computePackageNamesFromImports(expectedImportList), - equals(['analyzer', 'dart_dev', 'test'])))); + 'computePackageNamesFromImports', + () => test( + 'correctly computes package names from imports', + () => expect( + computePackageNamesFromImports(expectedImportList), + equals(['analyzer', 'dart_dev', 'test']), + ), + ), + ); } const sampleFile = ''' diff --git a/test/utils/rest_args_with_separator_test.dart b/test/utils/rest_args_with_separator_test.dart index 53849b35..0ea0eed3 100644 --- a/test/utils/rest_args_with_separator_test.dart +++ b/test/utils/rest_args_with_separator_test.dart @@ -28,18 +28,22 @@ void main() { 'c', '-d', ]); - expect(restArgsWithSeparator(results), [ + expect(restArgsWithSeparator(results), ['a', 'b', '--', 'c', '-d']); + }); + + test('with multiple separators', () { + final results = parser.parse([ 'a', + '-o', + 'out', + '-v', 'b', '--', 'c', '-d', + '--', + 'e', ]); - }); - - test('with multiple separators', () { - final results = parser - .parse(['a', '-o', 'out', '-v', 'b', '--', 'c', '-d', '--', 'e']); expect(restArgsWithSeparator(results), [ 'a', 'b', From 5a254749a147001d098dfb3a7ff9d407bdb4ffd6 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 15 Mar 2026 11:51:24 -0600 Subject: [PATCH 4/6] fix slashes for windows --- test/functional/format_tool_functional_test.dart | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/functional/format_tool_functional_test.dart b/test/functional/format_tool_functional_test.dart index e497fbf9..f6c21826 100644 --- a/test/functional/format_tool_functional_test.dart +++ b/test/functional/format_tool_functional_test.dart @@ -50,13 +50,16 @@ void main() { await process.shouldExit(0); final stdout = (await stdoutFuture).join('\n'); - final expectedCommand = [ - 'dart format', - if (dartSemverVersion.major >= 3) '--language-version=3.0', - 'lib/main.dart', - ].join(' '); + final expectedCommandPattern = RegExp( + [ + RegExp.escape('dart format'), + if (dartSemverVersion.major >= 3) + RegExp.escape('--language-version=3.0'), + r'lib[\\/]main\.dart', + ].join(r'\s+'), + ); - expect(stdout, contains(expectedCommand)); + expect(stdout, contains(expectedCommandPattern)); }, ); }); From cd3533580c37b3ef01997e75e495f898086d7398 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 15 Mar 2026 13:26:48 -0600 Subject: [PATCH 5/6] minimize format changes --- lib/src/core_config.dart | 8 +- lib/src/dart_dev_runner.dart | 5 +- lib/src/dart_dev_tool.dart | 29 +++--- lib/src/executable.dart | 29 +++--- lib/src/tools/analyze_tool.dart | 22 ++--- lib/src/tools/compound_tool.dart | 89 ++++++++++--------- lib/src/tools/format_tool.dart | 29 +++--- lib/src/tools/function_tool.dart | 4 +- lib/src/tools/over_react_format_tool.dart | 11 ++- lib/src/tools/process_tool.dart | 21 +++-- lib/src/tools/test_tool.dart | 15 ++-- lib/src/tools/tuneup_check_tool.dart | 6 +- lib/src/tools/webdev_serve_tool.dart | 12 +-- lib/src/utils/dart_dev_paths.dart | 10 +-- lib/src/utils/format_tool_builder.dart | 12 +-- lib/src/utils/logging.dart | 8 +- .../organize_directives.dart | 13 ++- lib/src/utils/pubspec_lock.dart | 9 +- test/functional.dart | 11 ++- test/functional/documentation_test.dart | 29 +++--- test/tools/format_tool_test.dart | 3 +- test/tools/process_tool_test.dart | 5 +- test/tools/test_tool_test.dart | 9 +- tool/dart_dev/config.dart | 1 + 24 files changed, 198 insertions(+), 192 deletions(-) diff --git a/lib/src/core_config.dart b/lib/src/core_config.dart index ceef7655..0df31897 100644 --- a/lib/src/core_config.dart +++ b/lib/src/core_config.dart @@ -6,7 +6,7 @@ library dart_dev.src.core_config; import 'package:dart_dev/dart_dev.dart'; Map get coreConfig => { - 'analyze': AnalyzeTool(), - 'format': FormatTool(), - 'test': TestTool(), -}; + 'analyze': AnalyzeTool(), + 'format': FormatTool(), + 'test': TestTool(), + }; diff --git a/lib/src/dart_dev_runner.dart b/lib/src/dart_dev_runner.dart index fcee8e6d..1434d8f3 100644 --- a/lib/src/dart_dev_runner.dart +++ b/lib/src/dart_dev_runner.dart @@ -11,7 +11,7 @@ import 'utils/version.dart'; class DartDevRunner extends CommandRunner { DartDevRunner(Map commands) - : super('dart_dev', 'Dart tool runner.') { + : super('dart_dev', 'Dart tool runner.') { // For backwards-compatibility, only add the `clean` command if it doesn't // conflict with any configured command. if (!commands.containsKey('clean')) { @@ -79,7 +79,6 @@ class CommandNameMismatch implements Exception { CommandNameMismatch(this.actual, this.expected); @override - String toString() => - 'CommandNameMismatch: ' + String toString() => 'CommandNameMismatch: ' 'Expected a "$expected" command but got one named "$actual".'; } diff --git a/lib/src/dart_dev_tool.dart b/lib/src/dart_dev_tool.dart index c5658191..04ccf8ef 100644 --- a/lib/src/dart_dev_tool.dart +++ b/lib/src/dart_dev_tool.dart @@ -14,19 +14,21 @@ abstract class DevTool { factory DevTool.fromFunction( FutureOr Function(DevToolExecutionContext context) function, { ArgParser? argParser, - }) => FunctionTool(function, argParser: argParser); + }) => + FunctionTool(function, argParser: argParser); factory DevTool.fromProcess( String executable, List args, { ProcessStartMode? mode, String? workingDirectory, - }) => ProcessTool( - executable, - args, - mode: mode, - workingDirectory: workingDirectory, - ); + }) => + ProcessTool( + executable, + args, + mode: mode, + workingDirectory: workingDirectory, + ); /// The argument parser for this tool, if needed. /// @@ -120,12 +122,13 @@ class DevToolExecutionContext { String? commandName, void Function(String message)? usageException, bool? verbose, - }) => DevToolExecutionContext( - argResults: argResults ?? this.argResults, - commandName: commandName ?? this.commandName, - usageException: usageException ?? this.usageException, - verbose: verbose ?? this.verbose, - ); + }) => + DevToolExecutionContext( + argResults: argResults ?? this.argResults, + commandName: commandName ?? this.commandName, + usageException: usageException ?? this.usageException, + verbose: verbose ?? this.verbose, + ); /// Calling this will throw a [UsageException] with [message] that should be /// caught by [CommandRunner] and used to set the exit code accordingly and diff --git a/lib/src/executable.dart b/lib/src/executable.dart index aee242a7..82b023e3 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart @@ -62,10 +62,13 @@ Future run(List args) async { } final processArgs = generateRunScript(); - final process = await Process.start(processArgs.first, [ - if (processArgs.length > 1) ...processArgs.sublist(1), - ...args, - ], mode: ProcessStartMode.inheritStdio); + final process = await Process.start( + processArgs.first, + [ + if (processArgs.length > 1) ...processArgs.sublist(1), + ...args, + ], + mode: ProcessStartMode.inheritStdio); ensureProcessExit(process); exitCode = await process.exitCode; } @@ -171,14 +174,13 @@ String? _computeRunScriptDigest() { if (packageConfig.existsSync()) ...packageConfig.readAsBytesSync(), if (configFile.existsSync()) ...configFile.readAsBytesSync(), if (configHasRelativeImports) - for (final file - in Glob('tool/**.dart', recursive: true) - .listSync() - .whereType() - .where( - (f) => p.canonicalize(f.path) != p.canonicalize(_paths.config), - ) - .sortedBy((f) => f.path)) + for (final file in Glob('tool/**.dart', recursive: true) + .listSync() + .whereType() + .where( + (f) => p.canonicalize(f.path) != p.canonicalize(_paths.config), + ) + .sortedBy((f) => f.path)) ...file.readAsBytesSync(), ]); return base64.encode(digest.bytes); @@ -326,8 +328,7 @@ Future runWithConfig( DevTool chooseDefaultFormatTool({String? path}) { final pubspec = cachedPubspec(path: path); const orf = 'over_react_format'; - final hasOverReactFormat = - pubspec.dependencies.containsKey(orf) || + final hasOverReactFormat = pubspec.dependencies.containsKey(orf) || pubspec.devDependencies.containsKey(orf) || pubspec.dependencyOverrides.containsKey(orf); diff --git a/lib/src/tools/analyze_tool.dart b/lib/src/tools/analyze_tool.dart index 37987d92..ded660a3 100644 --- a/lib/src/tools/analyze_tool.dart +++ b/lib/src/tools/analyze_tool.dart @@ -68,8 +68,7 @@ class AnalyzeTool extends DevTool { final ArgParser argParser = ArgParser() ..addOption( 'analyzer-args', - help: - 'Args to pass to the "dartanalyzer" or "dart analyze" process.\n' + help: 'Args to pass to the "dartanalyzer" or "dart analyze" process.\n' 'Run "dartanalyzer -h -v" or `dart analyze -h -v" to see all available options.', ); @@ -83,9 +82,8 @@ class AnalyzeTool extends DevTool { context ?? DevToolExecutionContext(), configuredAnalyzerArgs: analyzerArgs, include: include, - useDartAnalyze: !dartVersionHasDartanalyzer - ? true - : useDartAnalyze ?? false, + useDartAnalyze: + !dartVersionHasDartanalyzer ? true : useDartAnalyze ?? false, ), log: _log, ); @@ -181,8 +179,7 @@ ProcessDeclaration buildProcess( argResults, context.usageException, commandName: context.commandName, - usageFooter: - 'Arguments can be passed to the "$analyzerUsed" process via ' + usageFooter: 'Arguments can be passed to the "$analyzerUsed" process via ' 'the --analyzer-args option.', ); } @@ -200,10 +197,13 @@ ProcessDeclaration buildProcess( verbose: context.verbose, useDartAnalyzer: useDartAnalyze, ); - return ProcessDeclaration(executable, [ - ...args, - ...entrypoints, - ], mode: ProcessStartMode.inheritStdio); + return ProcessDeclaration( + executable, + [ + ...args, + ...entrypoints, + ], + mode: ProcessStartMode.inheritStdio); } /// Logs the `dartanalyzer` or `dart analyze` command that will be run by [AnalyzeTool] so that diff --git a/lib/src/tools/compound_tool.dart b/lib/src/tools/compound_tool.dart index fd93cb89..cc925c38 100644 --- a/lib/src/tools/compound_tool.dart +++ b/lib/src/tools/compound_tool.dart @@ -43,9 +43,9 @@ ArgResults takeOptionArgs(ArgParser parser, ArgResults results) => /// ..addTool(TestTool(), argMapper: takeAllArgs) /// }; ArgResults takeAllArgs(ArgParser parser, ArgResults results) => parser.parse([ - ...optionArgsOnly(results, allowedOptions: parser.options.keys), - ...restArgsWithSeparator(results), -]); + ...optionArgsOnly(results, allowedOptions: parser.options.keys), + ...restArgsWithSeparator(results), + ]); class CompoundTool extends DevTool with CompoundToolMixin {} @@ -81,8 +81,8 @@ mixin CompoundToolMixin on DevTool { for (var i = 0; i < _specs.length; i++) { if (!shouldRunTool(_specs[i].when, code)) continue; final newCode = await _specs[i].tool.run( - contextForTool(context, _specs[i]), - ); + contextForTool(context, _specs[i]), + ); _log.fine('Step ${i + 1}/${_specs.length} done (code: $newCode)\n'); if (code == 0) { code = newCode; @@ -282,18 +282,19 @@ class CompoundArgParser implements ArgParser { bool hide = false, bool hideNegatedUsage = false, List aliases = const [], - }) => _compoundParser.addFlag( - name, - abbr: abbr, - help: help, - defaultsTo: defaultsTo, - negatable: negatable, - // TODO once lower bound of args is 2.7.0 (requires Dart SDK 3.3.0), which adds hideNegatedUsage, forward this arg - // hideNegatedUsage: hideNegatedUsage, - callback: callback, - hide: hide, - aliases: aliases, - ); + }) => + _compoundParser.addFlag( + name, + abbr: abbr, + help: help, + defaultsTo: defaultsTo, + negatable: negatable, + // TODO once lower bound of args is 2.7.0 (requires Dart SDK 3.3.0), which adds hideNegatedUsage, forward this arg + // hideNegatedUsage: hideNegatedUsage, + callback: callback, + hide: hide, + aliases: aliases, + ); @override void addMultiOption( @@ -308,19 +309,20 @@ class CompoundArgParser implements ArgParser { bool splitCommas = true, bool hide = false, List aliases = const [], - }) => _compoundParser.addMultiOption( - name, - abbr: abbr, - help: help, - valueHelp: valueHelp, - allowed: allowed, - allowedHelp: allowedHelp, - defaultsTo: defaultsTo, - callback: callback, - splitCommas: splitCommas, - hide: hide, - aliases: aliases, - ); + }) => + _compoundParser.addMultiOption( + name, + abbr: abbr, + help: help, + valueHelp: valueHelp, + allowed: allowed, + allowedHelp: allowedHelp, + defaultsTo: defaultsTo, + callback: callback, + splitCommas: splitCommas, + hide: hide, + aliases: aliases, + ); @override void addOption( @@ -335,17 +337,18 @@ class CompoundArgParser implements ArgParser { bool mandatory = false, bool hide = false, List aliases = const [], - }) => _compoundParser.addOption( - name, - abbr: abbr, - help: help, - valueHelp: valueHelp, - allowed: allowed, - allowedHelp: allowedHelp, - defaultsTo: defaultsTo, - callback: callback, - mandatory: mandatory, - hide: hide, - aliases: aliases, - ); + }) => + _compoundParser.addOption( + name, + abbr: abbr, + help: help, + valueHelp: valueHelp, + allowed: allowed, + allowedHelp: allowedHelp, + defaultsTo: defaultsTo, + callback: callback, + mandatory: mandatory, + hide: hide, + aliases: aliases, + ); } diff --git a/lib/src/tools/format_tool.dart b/lib/src/tools/format_tool.dart index 5202e41b..5d43beae 100644 --- a/lib/src/tools/format_tool.dart +++ b/lib/src/tools/format_tool.dart @@ -108,15 +108,13 @@ class FormatTool extends DevTool { 'check', abbr: 'c', negatable: false, - help: - 'Check if changes need to be made and set the exit code ' + help: 'Check if changes need to be made and set the exit code ' 'accordingly.\nImplies "--dry-run" and "--set-exit-if-changed".', ) ..addSeparator('======== Other Options') ..addOption( 'formatter-args', - help: - 'Args to pass to the "dartfmt" or "dart format" process.\n' + help: 'Args to pass to the "dartfmt" or "dart format" process.\n' 'Run "dartfmt -h -v" or "dart format -h -v" to see all available options.', ); @@ -283,11 +281,11 @@ class FormatterInputs { /// output of step 1 (an instance of this class) with very simple unit tests. class FormatExecution { FormatExecution.exitEarly(this.exitCode) - : formatProcess = null, - directiveOrganization = null; + : formatProcess = null, + directiveOrganization = null; FormatExecution.process(this.formatProcess, [this.directiveOrganization]) - : exitCode = null; + : exitCode = null; /// If non-null, the execution is already complete and the [FormatTool] should /// exit with this code. @@ -457,8 +455,7 @@ FormatExecution buildExecution( }) { FormatMode? mode; - final useRestForInputs = - (context.argResults?.rest.isNotEmpty ?? false) && + final useRestForInputs = (context.argResults?.rest.isNotEmpty ?? false) && context.commandName == 'hackFastFormat'; final argResults = context.argResults; @@ -515,8 +512,7 @@ FormatExecution buildExecution( final dartFormatter = buildFormatProcess(formatter); Iterable args; - final dartStyleSupportsWriteArg = - formatter != Formatter.dartStyle || + final dartStyleSupportsWriteArg = formatter != Formatter.dartStyle || _dartStyleVersionSupportsWriteArg(path: path); final formatterLanguageVersion = _formatterLanguageVersion( formatter, @@ -548,10 +544,13 @@ FormatExecution buildExecution( verbose: context.verbose, ); - final formatProcess = ProcessDeclaration(dartFormatter.executable, [ - ...args, - ...inputs.includedFiles, - ], mode: ProcessStartMode.inheritStdio); + final formatProcess = ProcessDeclaration( + dartFormatter.executable, + [ + ...args, + ...inputs.includedFiles, + ], + mode: ProcessStartMode.inheritStdio); DirectiveOrganization? directiveOrganization; if (organizeDirectives) { directiveOrganization = DirectiveOrganization( diff --git a/lib/src/tools/function_tool.dart b/lib/src/tools/function_tool.dart index a7445fcc..f9a727f3 100644 --- a/lib/src/tools/function_tool.dart +++ b/lib/src/tools/function_tool.dart @@ -15,8 +15,8 @@ class FunctionTool extends DevTool { FunctionTool( FutureOr Function(DevToolExecutionContext context) function, { ArgParser? argParser, - }) : _argParser = argParser, - _function = function; + }) : _argParser = argParser, + _function = function; final FutureOr Function(DevToolExecutionContext context) _function; diff --git a/lib/src/tools/over_react_format_tool.dart b/lib/src/tools/over_react_format_tool.dart index 32b09f45..81ebd1ea 100644 --- a/lib/src/tools/over_react_format_tool.dart +++ b/lib/src/tools/over_react_format_tool.dart @@ -40,10 +40,13 @@ class OverReactFormatTool extends DevTool { if (lineLength != null) '--line-length=$lineLength', if (organizeDirectives == true) '--organize-directives', ]; - final process = ProcessDeclaration(exe.dart, [ - ...args, - ...paths, - ], mode: ProcessStartMode.inheritStdio); + final process = ProcessDeclaration( + exe.dart, + [ + ...args, + ...paths, + ], + mode: ProcessStartMode.inheritStdio); logCommand('dart', paths, args, verbose: context.verbose); return runProcessAndEnsureExit(process); } diff --git a/lib/src/tools/process_tool.dart b/lib/src/tools/process_tool.dart index 90900c0a..f92bcea5 100644 --- a/lib/src/tools/process_tool.dart +++ b/lib/src/tools/process_tool.dart @@ -32,10 +32,10 @@ class ProcessTool extends DevTool { List args, { ProcessStartMode? mode, String? workingDirectory, - }) : _args = args, - _executable = executable, - _mode = mode, - _workingDirectory = workingDirectory; + }) : _args = args, + _executable = executable, + _mode = mode, + _workingDirectory = workingDirectory; final List _args; final String _executable; @@ -83,11 +83,11 @@ class BackgroundProcessTool { ProcessStartMode? mode, Duration? delayAfterStart, String? workingDirectory, - }) : _args = args, - _executable = executable, - _mode = mode, - _delayAfterStart = delayAfterStart, - _workingDirectory = workingDirectory; + }) : _args = args, + _executable = executable, + _mode = mode, + _delayAfterStart = delayAfterStart, + _workingDirectory = workingDirectory; Process? get process => _process; Process? _process; @@ -109,8 +109,7 @@ class BackgroundProcessTool { } logSubprocessHeader(_log, '$_executable ${_args.join(' ')}'); - final mode = - _mode ?? + final mode = _mode ?? (context.verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal); diff --git a/lib/src/tools/test_tool.dart b/lib/src/tools/test_tool.dart index f58d1e5f..aa83eb24 100644 --- a/lib/src/tools/test_tool.dart +++ b/lib/src/tools/test_tool.dart @@ -53,8 +53,7 @@ class TestTool extends DevTool { ..addMultiOption( 'name', abbr: 'n', - help: - 'A substring of the name of the test to run.\n' + help: 'A substring of the name of the test to run.\n' 'Regular expression syntax is supported.\n' 'If passed multiple times, tests must match all substrings.', splitCommas: false, @@ -62,8 +61,7 @@ class TestTool extends DevTool { ..addMultiOption( 'plain-name', abbr: 'N', - help: - 'A plain-text substring of the name of the test to run.\n' + help: 'A plain-text substring of the name of the test to run.\n' 'If passed multiple times, tests must match all substrings.', splitCommas: false, ) @@ -75,8 +73,7 @@ class TestTool extends DevTool { ) ..addFlag( 'release', - help: - 'Build with release mode defaults for builders.\n' + help: 'Build with release mode defaults for builders.\n' 'This only applies in projects that run tests with build_runner.', ) ..addSeparator('======== Output') @@ -97,14 +94,12 @@ class TestTool extends DevTool { ) ..addOption( 'test-args', - help: - 'Args to pass to the test runner process.\n' + help: 'Args to pass to the test runner process.\n' 'Run "dart test -h" to see all available options.', ) ..addOption( 'build-args', - help: - 'Args to pass to the build runner process.\n' + help: 'Args to pass to the build runner process.\n' 'Run "dart run build_runner test -h" to see all available ' 'options.\n' 'Note: these args are only applicable if the current project ' diff --git a/lib/src/tools/tuneup_check_tool.dart b/lib/src/tools/tuneup_check_tool.dart index bc57fced..0841f164 100644 --- a/lib/src/tools/tuneup_check_tool.dart +++ b/lib/src/tools/tuneup_check_tool.dart @@ -54,8 +54,7 @@ class TuneupCheckTool extends DevTool { ..addFlag('ignore-infos', help: 'Ignore any info level issues.'); @override - String? description = - 'Run static analysis on dart files in this package ' + String? description = 'Run static analysis on dart files in this package ' 'using the tuneup tool.'; @override @@ -104,8 +103,7 @@ Iterable buildArgs({ bool? configuredIgnoreInfos, bool verbose = false, }) { - var ignoreInfos = - (configuredIgnoreInfos ?? false) || + var ignoreInfos = (configuredIgnoreInfos ?? false) || (flagValue(argResults, 'ignore-infos') ?? false); return [ 'run', diff --git a/lib/src/tools/webdev_serve_tool.dart b/lib/src/tools/webdev_serve_tool.dart index d8a2326c..6cdaeb72 100644 --- a/lib/src/tools/webdev_serve_tool.dart +++ b/lib/src/tools/webdev_serve_tool.dart @@ -72,22 +72,19 @@ class WebdevServeTool extends DevTool { ..addSeparator('======== Other Options') ..addOption( 'webdev-args', - help: - 'Args to pass to the webdev serve process.\n' + help: 'Args to pass to the webdev serve process.\n' 'Run "dart pub global run webdev serve -h -v" to see all available ' 'options.', ) ..addOption( 'build-args', - help: - 'Args to pass to the build runner process.\n' + help: 'Args to pass to the build runner process.\n' 'Run "dart run build_runner build -h -v" to see all available ' 'options.', ); @override - String? description = - 'Run a local web development server and a file system ' + String? description = 'Run a local web development server and a file system ' 'watcher that rebuilds on changes.'; @override @@ -224,8 +221,7 @@ WebdevServeExecution buildExecution( argResults, context.usageException, commandName: context.commandName, - usageFooter: - 'Arguments can be passed to the webdev process via the ' + usageFooter: 'Arguments can be passed to the webdev process via the ' '--webdev-args option.\n' 'Arguments can be passed to the build process via the --build-args ' 'option.', diff --git a/lib/src/utils/dart_dev_paths.dart b/lib/src/utils/dart_dev_paths.dart index f405d615..bc8ef56c 100644 --- a/lib/src/utils/dart_dev_paths.dart +++ b/lib/src/utils/dart_dev_paths.dart @@ -8,8 +8,8 @@ class DartDevPaths { DartDevPaths({p.Context? context}) : _context = context ?? p.context; String cache([String? subPath]) => _context.normalize( - _context.joinAll([..._cacheParts, if (subPath != null) subPath]), - ); + _context.joinAll([..._cacheParts, if (subPath != null) subPath]), + ); String get _cacheForDart => p.url.joinAll(_cacheParts); @@ -22,9 +22,9 @@ class DartDevPaths { final List _configParts = ['tool', 'dart_dev', 'config.dart']; String get configFromRunScriptForDart => p.url.relative( - p.url.absolute(configForDart), - from: p.url.absolute(_cacheForDart), - ); + p.url.absolute(configForDart), + from: p.url.absolute(_cacheForDart), + ); String get packageConfig => _context.join('.dart_tool', 'package_config.json'); diff --git a/lib/src/utils/format_tool_builder.dart b/lib/src/utils/format_tool_builder.dart index c52cffdf..54e743c5 100644 --- a/lib/src/utils/format_tool_builder.dart +++ b/lib/src/utils/format_tool_builder.dart @@ -48,9 +48,9 @@ class FormatToolBuilder extends GeneralizingAstVisitor { return formatterInvocation.cascadeSections .whereType() .firstWhereOrNull((assignment) { - final lhs = assignment.leftHandSide; - return lhs is PropertyAccess && lhs.propertyName.name == property; - }); + final lhs = assignment.leftHandSide; + return lhs is PropertyAccess && lhs.propertyName.name == property; + }); } final typedFormatDevTool = formatDevTool; @@ -227,9 +227,9 @@ DevTool? detectFormatter(AstNode formatterNode) { detectedFormatterName = formatterNode.methodName.name; } else if (formatterNode is CascadeExpression) { detectedFormatterName = formatterNode.target.toSource().replaceAll( - RegExp('[()]'), - '', - ); + RegExp('[()]'), + '', + ); } if (detectedFormatterName == 'FormatTool') { diff --git a/lib/src/utils/logging.dart b/lib/src/utils/logging.dart index fd56deb7..bbe19896 100644 --- a/lib/src/utils/logging.dart +++ b/lib/src/utils/logging.dart @@ -150,10 +150,10 @@ T logTimedSync( void Function(LogRecord) stdIOLogListener({bool verbose = false}) => (record) => io.stdout.write( - record.message.trim().isEmpty - ? '\n' * (record.message.split('\n').length - 1) - : colorLog(record, verbose: verbose), - ); + record.message.trim().isEmpty + ? '\n' * (record.message.split('\n').length - 1) + : colorLog(record, verbose: verbose), + ); String _loggerName(LogRecord record, bool verbose) { final maybeSplit = record.level >= Level.WARNING ? '\n' : ' '; diff --git a/lib/src/utils/organize_directives/organize_directives.dart b/lib/src/utils/organize_directives/organize_directives.dart index ec3407d5..e72fe470 100644 --- a/lib/src/utils/organize_directives/organize_directives.dart +++ b/lib/src/utils/organize_directives/organize_directives.dart @@ -68,9 +68,8 @@ String _organizeDirectivesOfType( String sourceFileContents, List namespaces, ) { - final directives = namespaces - .where((element) => element.directive is T) - .toList(); + final directives = + namespaces.where((element) => element.directive is T).toList(); directives.sort(_namespaceComparator); @@ -131,11 +130,9 @@ void _assignCommentsBeforeTokenToNamespace( // `precedingComments` returns the first comment before token. // Calling `comment.next` returns the next comment. // Returns null when there are no more comments left. - for ( - Token? comment = token.precedingComments; - comment != null; - comment = comment.next - ) { + for (Token? comment = token.precedingComments; + comment != null; + comment = comment.next) { // the LanguageVersionToken (`// @dart=2.11`) must stay where it is at // the top of the file. Do not assign this to any namespace if (comment is LanguageVersionToken) continue; diff --git a/lib/src/utils/pubspec_lock.dart b/lib/src/utils/pubspec_lock.dart index 6a7efcda..d9c56d24 100644 --- a/lib/src/utils/pubspec_lock.dart +++ b/lib/src/utils/pubspec_lock.dart @@ -42,7 +42,8 @@ String? getDependencyVersion(YamlDocument pubSpecLock, String packageName) { HashMap getDependencySources( YamlDocument pubspecLockDocument, Iterable packageNames, -) => HashMap.fromIterable( - packageNames, - value: (name) => _getPubSpecLockPackageSource(pubspecLockDocument, name), -); +) => + HashMap.fromIterable( + packageNames, + value: (name) => _getPubSpecLockPackageSource(pubspecLockDocument, name), + ); diff --git a/test/functional.dart b/test/functional.dart index 2f6e7dd0..ef3ee48d 100644 --- a/test/functional.dart +++ b/test/functional.dart @@ -62,10 +62,13 @@ Future runDevToolFunctionalTest( ); pubspec.writeAsStringSync(updated); - final result = Process.runSync(exe.dart, [ - 'pub', - 'get', - ], workingDirectory: pubspec.parent.path); + final result = Process.runSync( + exe.dart, + [ + 'pub', + 'get', + ], + workingDirectory: pubspec.parent.path); if (result.exitCode != 0) { final origPath = p.join( p.relative(templateDir.absolute.path), diff --git a/test/functional/documentation_test.dart b/test/functional/documentation_test.dart index 5aae33e5..e84192ee 100644 --- a/test/functional/documentation_test.dart +++ b/test/functional/documentation_test.dart @@ -29,17 +29,23 @@ void main() { d.file('pubspec.yaml', pubspecSource), ]).create(); - final pubGet = await TestProcess.start(exe.dart, [ - 'pub', - 'get', - ], workingDirectory: '${d.sandbox}/project'); + final pubGet = await TestProcess.start( + exe.dart, + [ + 'pub', + 'get', + ], + workingDirectory: '${d.sandbox}/project'); printOnFailure('PUBSPEC:\n$pubspecSource\n'); await pubGet.shouldExit(0); - final analysis = await TestProcess.start(exe.dart, [ - 'analyze', - '--fatal-infos', - ], workingDirectory: '${d.sandbox}/project'); + final analysis = await TestProcess.start( + exe.dart, + [ + 'analyze', + '--fatal-infos', + ], + workingDirectory: '${d.sandbox}/project'); printOnFailure('SOURCE:\n${dartBlock.source}\n'); await analysis.shouldExit(0); }); @@ -69,9 +75,8 @@ String pubspecWithPackages(Set packages) { ..writeln(' sdk: ">=2.12.0 <3.0.0"') ..writeln('dependencies:'); for (final package in packages) { - var constraint = package == 'dart_dev' - ? '\n path: ${p.current}' - : ' any'; + var constraint = + package == 'dart_dev' ? '\n path: ${p.current}' : ' any'; buffer.writeln(' $package:$constraint'); } return buffer.toString(); @@ -84,7 +89,7 @@ class DartBlock { final String sourceUrl; DartBlock.fromSource(this.source, this.sourceUrl, this.index) - : packages = parsePackagesFromSource(source); + : packages = parsePackagesFromSource(source); static Set parsePackagesFromSource(String source) { final packagePattern = RegExp(r'''['"]package:(\w+)\/.*['"]'''); diff --git a/test/tools/format_tool_test.dart b/test/tools/format_tool_test.dart index 97b73f67..6d99fc66 100644 --- a/test/tools/format_tool_test.dart +++ b/test/tools/format_tool_test.dart @@ -330,7 +330,8 @@ void main() { ); }); - test('returns config exit code and logs if configured formatter is ' + test( + 'returns config exit code and logs if configured formatter is ' 'dart_style but the package is not a direct dependency', () { expect( Logger.root.onRecord, diff --git a/test/tools/process_tool_test.dart b/test/tools/process_tool_test.dart index 7a01dde9..83f45344 100644 --- a/test/tools/process_tool_test.dart +++ b/test/tools/process_tool_test.dart @@ -21,9 +21,8 @@ void main() { }); test('can run from a custom working directory', () async { - final tool = - DevTool.fromProcess('pwd', [], workingDirectory: 'lib') - as ProcessTool; + final tool = DevTool.fromProcess('pwd', [], workingDirectory: 'lib') + as ProcessTool; expect(await tool.run(), isZero); final stdout = (await tool.process!.stdout.transform(utf8.decoder).join('')).trim(); diff --git a/test/tools/test_tool_test.dart b/test/tools/test_tool_test.dart index 65862360..a81b68f1 100644 --- a/test/tools/test_tool_test.dart +++ b/test/tools/test_tool_test.dart @@ -291,7 +291,8 @@ dev_dependencies: }, ); - test('throws UsageException if --build-args is used but build_test is not ' + test( + 'throws UsageException if --build-args is used but build_test is not ' 'a direct dependency', () async { await d.file('pubspec.yaml', ''' name: _test @@ -343,7 +344,8 @@ environment: }, ); - test('returns config exit code and logs if configured to run tests with ' + test( + 'returns config exit code and logs if configured to run tests with ' 'build args but build_runner is not a direct dependency', () async { expect( Logger.root.onRecord, @@ -378,7 +380,8 @@ dev_dependencies: ); }); - test('returns config exit code and logs if configured to run tests with ' + test( + 'returns config exit code and logs if configured to run tests with ' 'build args but build_test is not a direct dependency', () async { expect( Logger.root.onRecord, diff --git a/tool/dart_dev/config.dart b/tool/dart_dev/config.dart index f3d0d9c7..c0fd4ab4 100644 --- a/tool/dart_dev/config.dart +++ b/tool/dart_dev/config.dart @@ -5,6 +5,7 @@ final config = { ...coreConfig, 'analyze': AnalyzeTool()..useDartAnalyze = true, 'format': FormatTool() + ..languageVersion = '2.19' ..organizeDirectives = true ..exclude = [Glob('test/**/fixtures/**.dart')] ..formatter = Formatter.dartFormat, From 7ae8a0066cc0d8f781db81921a776418e0721068 Mon Sep 17 00:00:00 2001 From: Rob Becker Date: Sun, 15 Mar 2026 13:30:59 -0600 Subject: [PATCH 6/6] use latest format --- lib/src/core_config.dart | 8 +- lib/src/dart_dev_runner.dart | 5 +- lib/src/dart_dev_tool.dart | 29 +++--- lib/src/executable.dart | 29 +++--- lib/src/tools/analyze_tool.dart | 22 ++--- lib/src/tools/compound_tool.dart | 89 +++++++++---------- lib/src/tools/format_tool.dart | 29 +++--- lib/src/tools/function_tool.dart | 4 +- lib/src/tools/over_react_format_tool.dart | 11 +-- lib/src/tools/process_tool.dart | 21 ++--- lib/src/tools/test_tool.dart | 15 ++-- lib/src/tools/tuneup_check_tool.dart | 6 +- lib/src/tools/webdev_serve_tool.dart | 12 ++- lib/src/utils/dart_dev_paths.dart | 10 +-- lib/src/utils/format_tool_builder.dart | 12 +-- lib/src/utils/logging.dart | 8 +- .../organize_directives.dart | 13 +-- lib/src/utils/pubspec_lock.dart | 9 +- test/functional.dart | 11 +-- test/functional/documentation_test.dart | 29 +++--- test/tools/format_tool_test.dart | 3 +- test/tools/process_tool_test.dart | 5 +- test/tools/test_tool_test.dart | 9 +- tool/dart_dev/config.dart | 2 +- 24 files changed, 193 insertions(+), 198 deletions(-) diff --git a/lib/src/core_config.dart b/lib/src/core_config.dart index 0df31897..ceef7655 100644 --- a/lib/src/core_config.dart +++ b/lib/src/core_config.dart @@ -6,7 +6,7 @@ library dart_dev.src.core_config; import 'package:dart_dev/dart_dev.dart'; Map get coreConfig => { - 'analyze': AnalyzeTool(), - 'format': FormatTool(), - 'test': TestTool(), - }; + 'analyze': AnalyzeTool(), + 'format': FormatTool(), + 'test': TestTool(), +}; diff --git a/lib/src/dart_dev_runner.dart b/lib/src/dart_dev_runner.dart index 1434d8f3..fcee8e6d 100644 --- a/lib/src/dart_dev_runner.dart +++ b/lib/src/dart_dev_runner.dart @@ -11,7 +11,7 @@ import 'utils/version.dart'; class DartDevRunner extends CommandRunner { DartDevRunner(Map commands) - : super('dart_dev', 'Dart tool runner.') { + : super('dart_dev', 'Dart tool runner.') { // For backwards-compatibility, only add the `clean` command if it doesn't // conflict with any configured command. if (!commands.containsKey('clean')) { @@ -79,6 +79,7 @@ class CommandNameMismatch implements Exception { CommandNameMismatch(this.actual, this.expected); @override - String toString() => 'CommandNameMismatch: ' + String toString() => + 'CommandNameMismatch: ' 'Expected a "$expected" command but got one named "$actual".'; } diff --git a/lib/src/dart_dev_tool.dart b/lib/src/dart_dev_tool.dart index 04ccf8ef..c5658191 100644 --- a/lib/src/dart_dev_tool.dart +++ b/lib/src/dart_dev_tool.dart @@ -14,21 +14,19 @@ abstract class DevTool { factory DevTool.fromFunction( FutureOr Function(DevToolExecutionContext context) function, { ArgParser? argParser, - }) => - FunctionTool(function, argParser: argParser); + }) => FunctionTool(function, argParser: argParser); factory DevTool.fromProcess( String executable, List args, { ProcessStartMode? mode, String? workingDirectory, - }) => - ProcessTool( - executable, - args, - mode: mode, - workingDirectory: workingDirectory, - ); + }) => ProcessTool( + executable, + args, + mode: mode, + workingDirectory: workingDirectory, + ); /// The argument parser for this tool, if needed. /// @@ -122,13 +120,12 @@ class DevToolExecutionContext { String? commandName, void Function(String message)? usageException, bool? verbose, - }) => - DevToolExecutionContext( - argResults: argResults ?? this.argResults, - commandName: commandName ?? this.commandName, - usageException: usageException ?? this.usageException, - verbose: verbose ?? this.verbose, - ); + }) => DevToolExecutionContext( + argResults: argResults ?? this.argResults, + commandName: commandName ?? this.commandName, + usageException: usageException ?? this.usageException, + verbose: verbose ?? this.verbose, + ); /// Calling this will throw a [UsageException] with [message] that should be /// caught by [CommandRunner] and used to set the exit code accordingly and diff --git a/lib/src/executable.dart b/lib/src/executable.dart index 82b023e3..aee242a7 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart @@ -62,13 +62,10 @@ Future run(List args) async { } final processArgs = generateRunScript(); - final process = await Process.start( - processArgs.first, - [ - if (processArgs.length > 1) ...processArgs.sublist(1), - ...args, - ], - mode: ProcessStartMode.inheritStdio); + final process = await Process.start(processArgs.first, [ + if (processArgs.length > 1) ...processArgs.sublist(1), + ...args, + ], mode: ProcessStartMode.inheritStdio); ensureProcessExit(process); exitCode = await process.exitCode; } @@ -174,13 +171,14 @@ String? _computeRunScriptDigest() { if (packageConfig.existsSync()) ...packageConfig.readAsBytesSync(), if (configFile.existsSync()) ...configFile.readAsBytesSync(), if (configHasRelativeImports) - for (final file in Glob('tool/**.dart', recursive: true) - .listSync() - .whereType() - .where( - (f) => p.canonicalize(f.path) != p.canonicalize(_paths.config), - ) - .sortedBy((f) => f.path)) + for (final file + in Glob('tool/**.dart', recursive: true) + .listSync() + .whereType() + .where( + (f) => p.canonicalize(f.path) != p.canonicalize(_paths.config), + ) + .sortedBy((f) => f.path)) ...file.readAsBytesSync(), ]); return base64.encode(digest.bytes); @@ -328,7 +326,8 @@ Future runWithConfig( DevTool chooseDefaultFormatTool({String? path}) { final pubspec = cachedPubspec(path: path); const orf = 'over_react_format'; - final hasOverReactFormat = pubspec.dependencies.containsKey(orf) || + final hasOverReactFormat = + pubspec.dependencies.containsKey(orf) || pubspec.devDependencies.containsKey(orf) || pubspec.dependencyOverrides.containsKey(orf); diff --git a/lib/src/tools/analyze_tool.dart b/lib/src/tools/analyze_tool.dart index ded660a3..37987d92 100644 --- a/lib/src/tools/analyze_tool.dart +++ b/lib/src/tools/analyze_tool.dart @@ -68,7 +68,8 @@ class AnalyzeTool extends DevTool { final ArgParser argParser = ArgParser() ..addOption( 'analyzer-args', - help: 'Args to pass to the "dartanalyzer" or "dart analyze" process.\n' + help: + 'Args to pass to the "dartanalyzer" or "dart analyze" process.\n' 'Run "dartanalyzer -h -v" or `dart analyze -h -v" to see all available options.', ); @@ -82,8 +83,9 @@ class AnalyzeTool extends DevTool { context ?? DevToolExecutionContext(), configuredAnalyzerArgs: analyzerArgs, include: include, - useDartAnalyze: - !dartVersionHasDartanalyzer ? true : useDartAnalyze ?? false, + useDartAnalyze: !dartVersionHasDartanalyzer + ? true + : useDartAnalyze ?? false, ), log: _log, ); @@ -179,7 +181,8 @@ ProcessDeclaration buildProcess( argResults, context.usageException, commandName: context.commandName, - usageFooter: 'Arguments can be passed to the "$analyzerUsed" process via ' + usageFooter: + 'Arguments can be passed to the "$analyzerUsed" process via ' 'the --analyzer-args option.', ); } @@ -197,13 +200,10 @@ ProcessDeclaration buildProcess( verbose: context.verbose, useDartAnalyzer: useDartAnalyze, ); - return ProcessDeclaration( - executable, - [ - ...args, - ...entrypoints, - ], - mode: ProcessStartMode.inheritStdio); + return ProcessDeclaration(executable, [ + ...args, + ...entrypoints, + ], mode: ProcessStartMode.inheritStdio); } /// Logs the `dartanalyzer` or `dart analyze` command that will be run by [AnalyzeTool] so that diff --git a/lib/src/tools/compound_tool.dart b/lib/src/tools/compound_tool.dart index cc925c38..fd93cb89 100644 --- a/lib/src/tools/compound_tool.dart +++ b/lib/src/tools/compound_tool.dart @@ -43,9 +43,9 @@ ArgResults takeOptionArgs(ArgParser parser, ArgResults results) => /// ..addTool(TestTool(), argMapper: takeAllArgs) /// }; ArgResults takeAllArgs(ArgParser parser, ArgResults results) => parser.parse([ - ...optionArgsOnly(results, allowedOptions: parser.options.keys), - ...restArgsWithSeparator(results), - ]); + ...optionArgsOnly(results, allowedOptions: parser.options.keys), + ...restArgsWithSeparator(results), +]); class CompoundTool extends DevTool with CompoundToolMixin {} @@ -81,8 +81,8 @@ mixin CompoundToolMixin on DevTool { for (var i = 0; i < _specs.length; i++) { if (!shouldRunTool(_specs[i].when, code)) continue; final newCode = await _specs[i].tool.run( - contextForTool(context, _specs[i]), - ); + contextForTool(context, _specs[i]), + ); _log.fine('Step ${i + 1}/${_specs.length} done (code: $newCode)\n'); if (code == 0) { code = newCode; @@ -282,19 +282,18 @@ class CompoundArgParser implements ArgParser { bool hide = false, bool hideNegatedUsage = false, List aliases = const [], - }) => - _compoundParser.addFlag( - name, - abbr: abbr, - help: help, - defaultsTo: defaultsTo, - negatable: negatable, - // TODO once lower bound of args is 2.7.0 (requires Dart SDK 3.3.0), which adds hideNegatedUsage, forward this arg - // hideNegatedUsage: hideNegatedUsage, - callback: callback, - hide: hide, - aliases: aliases, - ); + }) => _compoundParser.addFlag( + name, + abbr: abbr, + help: help, + defaultsTo: defaultsTo, + negatable: negatable, + // TODO once lower bound of args is 2.7.0 (requires Dart SDK 3.3.0), which adds hideNegatedUsage, forward this arg + // hideNegatedUsage: hideNegatedUsage, + callback: callback, + hide: hide, + aliases: aliases, + ); @override void addMultiOption( @@ -309,20 +308,19 @@ class CompoundArgParser implements ArgParser { bool splitCommas = true, bool hide = false, List aliases = const [], - }) => - _compoundParser.addMultiOption( - name, - abbr: abbr, - help: help, - valueHelp: valueHelp, - allowed: allowed, - allowedHelp: allowedHelp, - defaultsTo: defaultsTo, - callback: callback, - splitCommas: splitCommas, - hide: hide, - aliases: aliases, - ); + }) => _compoundParser.addMultiOption( + name, + abbr: abbr, + help: help, + valueHelp: valueHelp, + allowed: allowed, + allowedHelp: allowedHelp, + defaultsTo: defaultsTo, + callback: callback, + splitCommas: splitCommas, + hide: hide, + aliases: aliases, + ); @override void addOption( @@ -337,18 +335,17 @@ class CompoundArgParser implements ArgParser { bool mandatory = false, bool hide = false, List aliases = const [], - }) => - _compoundParser.addOption( - name, - abbr: abbr, - help: help, - valueHelp: valueHelp, - allowed: allowed, - allowedHelp: allowedHelp, - defaultsTo: defaultsTo, - callback: callback, - mandatory: mandatory, - hide: hide, - aliases: aliases, - ); + }) => _compoundParser.addOption( + name, + abbr: abbr, + help: help, + valueHelp: valueHelp, + allowed: allowed, + allowedHelp: allowedHelp, + defaultsTo: defaultsTo, + callback: callback, + mandatory: mandatory, + hide: hide, + aliases: aliases, + ); } diff --git a/lib/src/tools/format_tool.dart b/lib/src/tools/format_tool.dart index 5d43beae..5202e41b 100644 --- a/lib/src/tools/format_tool.dart +++ b/lib/src/tools/format_tool.dart @@ -108,13 +108,15 @@ class FormatTool extends DevTool { 'check', abbr: 'c', negatable: false, - help: 'Check if changes need to be made and set the exit code ' + help: + 'Check if changes need to be made and set the exit code ' 'accordingly.\nImplies "--dry-run" and "--set-exit-if-changed".', ) ..addSeparator('======== Other Options') ..addOption( 'formatter-args', - help: 'Args to pass to the "dartfmt" or "dart format" process.\n' + help: + 'Args to pass to the "dartfmt" or "dart format" process.\n' 'Run "dartfmt -h -v" or "dart format -h -v" to see all available options.', ); @@ -281,11 +283,11 @@ class FormatterInputs { /// output of step 1 (an instance of this class) with very simple unit tests. class FormatExecution { FormatExecution.exitEarly(this.exitCode) - : formatProcess = null, - directiveOrganization = null; + : formatProcess = null, + directiveOrganization = null; FormatExecution.process(this.formatProcess, [this.directiveOrganization]) - : exitCode = null; + : exitCode = null; /// If non-null, the execution is already complete and the [FormatTool] should /// exit with this code. @@ -455,7 +457,8 @@ FormatExecution buildExecution( }) { FormatMode? mode; - final useRestForInputs = (context.argResults?.rest.isNotEmpty ?? false) && + final useRestForInputs = + (context.argResults?.rest.isNotEmpty ?? false) && context.commandName == 'hackFastFormat'; final argResults = context.argResults; @@ -512,7 +515,8 @@ FormatExecution buildExecution( final dartFormatter = buildFormatProcess(formatter); Iterable args; - final dartStyleSupportsWriteArg = formatter != Formatter.dartStyle || + final dartStyleSupportsWriteArg = + formatter != Formatter.dartStyle || _dartStyleVersionSupportsWriteArg(path: path); final formatterLanguageVersion = _formatterLanguageVersion( formatter, @@ -544,13 +548,10 @@ FormatExecution buildExecution( verbose: context.verbose, ); - final formatProcess = ProcessDeclaration( - dartFormatter.executable, - [ - ...args, - ...inputs.includedFiles, - ], - mode: ProcessStartMode.inheritStdio); + final formatProcess = ProcessDeclaration(dartFormatter.executable, [ + ...args, + ...inputs.includedFiles, + ], mode: ProcessStartMode.inheritStdio); DirectiveOrganization? directiveOrganization; if (organizeDirectives) { directiveOrganization = DirectiveOrganization( diff --git a/lib/src/tools/function_tool.dart b/lib/src/tools/function_tool.dart index f9a727f3..a7445fcc 100644 --- a/lib/src/tools/function_tool.dart +++ b/lib/src/tools/function_tool.dart @@ -15,8 +15,8 @@ class FunctionTool extends DevTool { FunctionTool( FutureOr Function(DevToolExecutionContext context) function, { ArgParser? argParser, - }) : _argParser = argParser, - _function = function; + }) : _argParser = argParser, + _function = function; final FutureOr Function(DevToolExecutionContext context) _function; diff --git a/lib/src/tools/over_react_format_tool.dart b/lib/src/tools/over_react_format_tool.dart index 81ebd1ea..32b09f45 100644 --- a/lib/src/tools/over_react_format_tool.dart +++ b/lib/src/tools/over_react_format_tool.dart @@ -40,13 +40,10 @@ class OverReactFormatTool extends DevTool { if (lineLength != null) '--line-length=$lineLength', if (organizeDirectives == true) '--organize-directives', ]; - final process = ProcessDeclaration( - exe.dart, - [ - ...args, - ...paths, - ], - mode: ProcessStartMode.inheritStdio); + final process = ProcessDeclaration(exe.dart, [ + ...args, + ...paths, + ], mode: ProcessStartMode.inheritStdio); logCommand('dart', paths, args, verbose: context.verbose); return runProcessAndEnsureExit(process); } diff --git a/lib/src/tools/process_tool.dart b/lib/src/tools/process_tool.dart index f92bcea5..90900c0a 100644 --- a/lib/src/tools/process_tool.dart +++ b/lib/src/tools/process_tool.dart @@ -32,10 +32,10 @@ class ProcessTool extends DevTool { List args, { ProcessStartMode? mode, String? workingDirectory, - }) : _args = args, - _executable = executable, - _mode = mode, - _workingDirectory = workingDirectory; + }) : _args = args, + _executable = executable, + _mode = mode, + _workingDirectory = workingDirectory; final List _args; final String _executable; @@ -83,11 +83,11 @@ class BackgroundProcessTool { ProcessStartMode? mode, Duration? delayAfterStart, String? workingDirectory, - }) : _args = args, - _executable = executable, - _mode = mode, - _delayAfterStart = delayAfterStart, - _workingDirectory = workingDirectory; + }) : _args = args, + _executable = executable, + _mode = mode, + _delayAfterStart = delayAfterStart, + _workingDirectory = workingDirectory; Process? get process => _process; Process? _process; @@ -109,7 +109,8 @@ class BackgroundProcessTool { } logSubprocessHeader(_log, '$_executable ${_args.join(' ')}'); - final mode = _mode ?? + final mode = + _mode ?? (context.verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal); diff --git a/lib/src/tools/test_tool.dart b/lib/src/tools/test_tool.dart index aa83eb24..f58d1e5f 100644 --- a/lib/src/tools/test_tool.dart +++ b/lib/src/tools/test_tool.dart @@ -53,7 +53,8 @@ class TestTool extends DevTool { ..addMultiOption( 'name', abbr: 'n', - help: 'A substring of the name of the test to run.\n' + help: + 'A substring of the name of the test to run.\n' 'Regular expression syntax is supported.\n' 'If passed multiple times, tests must match all substrings.', splitCommas: false, @@ -61,7 +62,8 @@ class TestTool extends DevTool { ..addMultiOption( 'plain-name', abbr: 'N', - help: 'A plain-text substring of the name of the test to run.\n' + help: + 'A plain-text substring of the name of the test to run.\n' 'If passed multiple times, tests must match all substrings.', splitCommas: false, ) @@ -73,7 +75,8 @@ class TestTool extends DevTool { ) ..addFlag( 'release', - help: 'Build with release mode defaults for builders.\n' + help: + 'Build with release mode defaults for builders.\n' 'This only applies in projects that run tests with build_runner.', ) ..addSeparator('======== Output') @@ -94,12 +97,14 @@ class TestTool extends DevTool { ) ..addOption( 'test-args', - help: 'Args to pass to the test runner process.\n' + help: + 'Args to pass to the test runner process.\n' 'Run "dart test -h" to see all available options.', ) ..addOption( 'build-args', - help: 'Args to pass to the build runner process.\n' + help: + 'Args to pass to the build runner process.\n' 'Run "dart run build_runner test -h" to see all available ' 'options.\n' 'Note: these args are only applicable if the current project ' diff --git a/lib/src/tools/tuneup_check_tool.dart b/lib/src/tools/tuneup_check_tool.dart index 0841f164..bc57fced 100644 --- a/lib/src/tools/tuneup_check_tool.dart +++ b/lib/src/tools/tuneup_check_tool.dart @@ -54,7 +54,8 @@ class TuneupCheckTool extends DevTool { ..addFlag('ignore-infos', help: 'Ignore any info level issues.'); @override - String? description = 'Run static analysis on dart files in this package ' + String? description = + 'Run static analysis on dart files in this package ' 'using the tuneup tool.'; @override @@ -103,7 +104,8 @@ Iterable buildArgs({ bool? configuredIgnoreInfos, bool verbose = false, }) { - var ignoreInfos = (configuredIgnoreInfos ?? false) || + var ignoreInfos = + (configuredIgnoreInfos ?? false) || (flagValue(argResults, 'ignore-infos') ?? false); return [ 'run', diff --git a/lib/src/tools/webdev_serve_tool.dart b/lib/src/tools/webdev_serve_tool.dart index 6cdaeb72..d8a2326c 100644 --- a/lib/src/tools/webdev_serve_tool.dart +++ b/lib/src/tools/webdev_serve_tool.dart @@ -72,19 +72,22 @@ class WebdevServeTool extends DevTool { ..addSeparator('======== Other Options') ..addOption( 'webdev-args', - help: 'Args to pass to the webdev serve process.\n' + help: + 'Args to pass to the webdev serve process.\n' 'Run "dart pub global run webdev serve -h -v" to see all available ' 'options.', ) ..addOption( 'build-args', - help: 'Args to pass to the build runner process.\n' + help: + 'Args to pass to the build runner process.\n' 'Run "dart run build_runner build -h -v" to see all available ' 'options.', ); @override - String? description = 'Run a local web development server and a file system ' + String? description = + 'Run a local web development server and a file system ' 'watcher that rebuilds on changes.'; @override @@ -221,7 +224,8 @@ WebdevServeExecution buildExecution( argResults, context.usageException, commandName: context.commandName, - usageFooter: 'Arguments can be passed to the webdev process via the ' + usageFooter: + 'Arguments can be passed to the webdev process via the ' '--webdev-args option.\n' 'Arguments can be passed to the build process via the --build-args ' 'option.', diff --git a/lib/src/utils/dart_dev_paths.dart b/lib/src/utils/dart_dev_paths.dart index bc8ef56c..f405d615 100644 --- a/lib/src/utils/dart_dev_paths.dart +++ b/lib/src/utils/dart_dev_paths.dart @@ -8,8 +8,8 @@ class DartDevPaths { DartDevPaths({p.Context? context}) : _context = context ?? p.context; String cache([String? subPath]) => _context.normalize( - _context.joinAll([..._cacheParts, if (subPath != null) subPath]), - ); + _context.joinAll([..._cacheParts, if (subPath != null) subPath]), + ); String get _cacheForDart => p.url.joinAll(_cacheParts); @@ -22,9 +22,9 @@ class DartDevPaths { final List _configParts = ['tool', 'dart_dev', 'config.dart']; String get configFromRunScriptForDart => p.url.relative( - p.url.absolute(configForDart), - from: p.url.absolute(_cacheForDart), - ); + p.url.absolute(configForDart), + from: p.url.absolute(_cacheForDart), + ); String get packageConfig => _context.join('.dart_tool', 'package_config.json'); diff --git a/lib/src/utils/format_tool_builder.dart b/lib/src/utils/format_tool_builder.dart index 54e743c5..c52cffdf 100644 --- a/lib/src/utils/format_tool_builder.dart +++ b/lib/src/utils/format_tool_builder.dart @@ -48,9 +48,9 @@ class FormatToolBuilder extends GeneralizingAstVisitor { return formatterInvocation.cascadeSections .whereType() .firstWhereOrNull((assignment) { - final lhs = assignment.leftHandSide; - return lhs is PropertyAccess && lhs.propertyName.name == property; - }); + final lhs = assignment.leftHandSide; + return lhs is PropertyAccess && lhs.propertyName.name == property; + }); } final typedFormatDevTool = formatDevTool; @@ -227,9 +227,9 @@ DevTool? detectFormatter(AstNode formatterNode) { detectedFormatterName = formatterNode.methodName.name; } else if (formatterNode is CascadeExpression) { detectedFormatterName = formatterNode.target.toSource().replaceAll( - RegExp('[()]'), - '', - ); + RegExp('[()]'), + '', + ); } if (detectedFormatterName == 'FormatTool') { diff --git a/lib/src/utils/logging.dart b/lib/src/utils/logging.dart index bbe19896..fd56deb7 100644 --- a/lib/src/utils/logging.dart +++ b/lib/src/utils/logging.dart @@ -150,10 +150,10 @@ T logTimedSync( void Function(LogRecord) stdIOLogListener({bool verbose = false}) => (record) => io.stdout.write( - record.message.trim().isEmpty - ? '\n' * (record.message.split('\n').length - 1) - : colorLog(record, verbose: verbose), - ); + record.message.trim().isEmpty + ? '\n' * (record.message.split('\n').length - 1) + : colorLog(record, verbose: verbose), + ); String _loggerName(LogRecord record, bool verbose) { final maybeSplit = record.level >= Level.WARNING ? '\n' : ' '; diff --git a/lib/src/utils/organize_directives/organize_directives.dart b/lib/src/utils/organize_directives/organize_directives.dart index e72fe470..ec3407d5 100644 --- a/lib/src/utils/organize_directives/organize_directives.dart +++ b/lib/src/utils/organize_directives/organize_directives.dart @@ -68,8 +68,9 @@ String _organizeDirectivesOfType( String sourceFileContents, List namespaces, ) { - final directives = - namespaces.where((element) => element.directive is T).toList(); + final directives = namespaces + .where((element) => element.directive is T) + .toList(); directives.sort(_namespaceComparator); @@ -130,9 +131,11 @@ void _assignCommentsBeforeTokenToNamespace( // `precedingComments` returns the first comment before token. // Calling `comment.next` returns the next comment. // Returns null when there are no more comments left. - for (Token? comment = token.precedingComments; - comment != null; - comment = comment.next) { + for ( + Token? comment = token.precedingComments; + comment != null; + comment = comment.next + ) { // the LanguageVersionToken (`// @dart=2.11`) must stay where it is at // the top of the file. Do not assign this to any namespace if (comment is LanguageVersionToken) continue; diff --git a/lib/src/utils/pubspec_lock.dart b/lib/src/utils/pubspec_lock.dart index d9c56d24..6a7efcda 100644 --- a/lib/src/utils/pubspec_lock.dart +++ b/lib/src/utils/pubspec_lock.dart @@ -42,8 +42,7 @@ String? getDependencyVersion(YamlDocument pubSpecLock, String packageName) { HashMap getDependencySources( YamlDocument pubspecLockDocument, Iterable packageNames, -) => - HashMap.fromIterable( - packageNames, - value: (name) => _getPubSpecLockPackageSource(pubspecLockDocument, name), - ); +) => HashMap.fromIterable( + packageNames, + value: (name) => _getPubSpecLockPackageSource(pubspecLockDocument, name), +); diff --git a/test/functional.dart b/test/functional.dart index ef3ee48d..2f6e7dd0 100644 --- a/test/functional.dart +++ b/test/functional.dart @@ -62,13 +62,10 @@ Future runDevToolFunctionalTest( ); pubspec.writeAsStringSync(updated); - final result = Process.runSync( - exe.dart, - [ - 'pub', - 'get', - ], - workingDirectory: pubspec.parent.path); + final result = Process.runSync(exe.dart, [ + 'pub', + 'get', + ], workingDirectory: pubspec.parent.path); if (result.exitCode != 0) { final origPath = p.join( p.relative(templateDir.absolute.path), diff --git a/test/functional/documentation_test.dart b/test/functional/documentation_test.dart index e84192ee..5aae33e5 100644 --- a/test/functional/documentation_test.dart +++ b/test/functional/documentation_test.dart @@ -29,23 +29,17 @@ void main() { d.file('pubspec.yaml', pubspecSource), ]).create(); - final pubGet = await TestProcess.start( - exe.dart, - [ - 'pub', - 'get', - ], - workingDirectory: '${d.sandbox}/project'); + final pubGet = await TestProcess.start(exe.dart, [ + 'pub', + 'get', + ], workingDirectory: '${d.sandbox}/project'); printOnFailure('PUBSPEC:\n$pubspecSource\n'); await pubGet.shouldExit(0); - final analysis = await TestProcess.start( - exe.dart, - [ - 'analyze', - '--fatal-infos', - ], - workingDirectory: '${d.sandbox}/project'); + final analysis = await TestProcess.start(exe.dart, [ + 'analyze', + '--fatal-infos', + ], workingDirectory: '${d.sandbox}/project'); printOnFailure('SOURCE:\n${dartBlock.source}\n'); await analysis.shouldExit(0); }); @@ -75,8 +69,9 @@ String pubspecWithPackages(Set packages) { ..writeln(' sdk: ">=2.12.0 <3.0.0"') ..writeln('dependencies:'); for (final package in packages) { - var constraint = - package == 'dart_dev' ? '\n path: ${p.current}' : ' any'; + var constraint = package == 'dart_dev' + ? '\n path: ${p.current}' + : ' any'; buffer.writeln(' $package:$constraint'); } return buffer.toString(); @@ -89,7 +84,7 @@ class DartBlock { final String sourceUrl; DartBlock.fromSource(this.source, this.sourceUrl, this.index) - : packages = parsePackagesFromSource(source); + : packages = parsePackagesFromSource(source); static Set parsePackagesFromSource(String source) { final packagePattern = RegExp(r'''['"]package:(\w+)\/.*['"]'''); diff --git a/test/tools/format_tool_test.dart b/test/tools/format_tool_test.dart index 6d99fc66..97b73f67 100644 --- a/test/tools/format_tool_test.dart +++ b/test/tools/format_tool_test.dart @@ -330,8 +330,7 @@ void main() { ); }); - test( - 'returns config exit code and logs if configured formatter is ' + test('returns config exit code and logs if configured formatter is ' 'dart_style but the package is not a direct dependency', () { expect( Logger.root.onRecord, diff --git a/test/tools/process_tool_test.dart b/test/tools/process_tool_test.dart index 83f45344..7a01dde9 100644 --- a/test/tools/process_tool_test.dart +++ b/test/tools/process_tool_test.dart @@ -21,8 +21,9 @@ void main() { }); test('can run from a custom working directory', () async { - final tool = DevTool.fromProcess('pwd', [], workingDirectory: 'lib') - as ProcessTool; + final tool = + DevTool.fromProcess('pwd', [], workingDirectory: 'lib') + as ProcessTool; expect(await tool.run(), isZero); final stdout = (await tool.process!.stdout.transform(utf8.decoder).join('')).trim(); diff --git a/test/tools/test_tool_test.dart b/test/tools/test_tool_test.dart index a81b68f1..65862360 100644 --- a/test/tools/test_tool_test.dart +++ b/test/tools/test_tool_test.dart @@ -291,8 +291,7 @@ dev_dependencies: }, ); - test( - 'throws UsageException if --build-args is used but build_test is not ' + test('throws UsageException if --build-args is used but build_test is not ' 'a direct dependency', () async { await d.file('pubspec.yaml', ''' name: _test @@ -344,8 +343,7 @@ environment: }, ); - test( - 'returns config exit code and logs if configured to run tests with ' + test('returns config exit code and logs if configured to run tests with ' 'build args but build_runner is not a direct dependency', () async { expect( Logger.root.onRecord, @@ -380,8 +378,7 @@ dev_dependencies: ); }); - test( - 'returns config exit code and logs if configured to run tests with ' + test('returns config exit code and logs if configured to run tests with ' 'build args but build_test is not a direct dependency', () async { expect( Logger.root.onRecord, diff --git a/tool/dart_dev/config.dart b/tool/dart_dev/config.dart index c0fd4ab4..c07b0f30 100644 --- a/tool/dart_dev/config.dart +++ b/tool/dart_dev/config.dart @@ -5,7 +5,7 @@ final config = { ...coreConfig, 'analyze': AnalyzeTool()..useDartAnalyze = true, 'format': FormatTool() - ..languageVersion = '2.19' + ..languageVersion = 'latest' ..organizeDirectives = true ..exclude = [Glob('test/**/fixtures/**.dart')] ..formatter = Formatter.dartFormat,