diff --git a/CHANGELOG.md b/CHANGELOG.md index 766ec056..fcf44b45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,26 @@ config file and infer the language version for the package from that, similar to how other Dart tools behave like `dart analyze` and `dart run`. +* **Remove the old formatter executables and CLI options.** Before the + `dart format` command was added to the core Dart SDK, users accessed the + formatter by running a separate `dartfmt` executable that was included with + the Dart SDK. That executable had a different CLI interface. For example, you + had to pass `-w` to get it to overwrite files and if you passed no arguments + at all, it silently sat there waiting for input on stdin. When we added + `dart format`, we took that opportunity to revamp the CLI options. + + However, the dart_style package still exposed an executable with the old CLI. + If you ran `dart pub global activate dart_style`, this would give you a + `dartfmt` (and `dartformat`) executable with the old CLI options. Now that + almost everyone is using `dart format`, we have removed the old CLI and the + old package executables. + + You can still run the formatter on the CLI through the package (for example, + if you want to use a particular version of dart_style instead of the one + bundled with your Dart SDK). But it now uses the exact same CLI options and + arguments as the `dart format` command. You can invoke it with + `dart run dart_style:format `. + ## 2.3.7 * Allow passing a language version to `DartFomatter()`. Formatted code will be diff --git a/bin/format.dart b/bin/format.dart index 6b6c9faa..25e78b5d 100644 --- a/bin/format.dart +++ b/bin/format.dart @@ -3,155 +3,21 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:io'; -import 'package:args/args.dart'; -import 'package:dart_style/src/cli/formatter_options.dart'; -import 'package:dart_style/src/cli/options.dart'; -import 'package:dart_style/src/cli/output.dart'; -import 'package:dart_style/src/cli/show.dart'; -import 'package:dart_style/src/cli/summary.dart'; -import 'package:dart_style/src/io.dart'; +import 'package:args/command_runner.dart'; +import 'package:dart_style/src/cli/format_command.dart'; -void main(List args) async { - var parser = ArgParser(allowTrailingOptions: true); +void main(List arguments) async { + var runner = + CommandRunner('format', 'Idiomatically format Dart source code.'); + runner.argParser.addFlag('verbose', + abbr: 'v', negatable: false, help: 'Show verbose help.'); + runner.addCommand(FormatCommand( + verbose: arguments.contains('-v') || arguments.contains('--verbose'))); - defineOptions(parser, - oldCli: true, verbose: args.contains('--verbose') || args.contains('-v')); - - ArgResults argResults; - try { - argResults = parser.parse(args); - } on FormatException catch (err) { - usageError(parser, err.message); - } - - if (argResults['help'] as bool) { - printUsage(parser); - return; - } - - if (argResults['version'] as bool) { - print(dartStyleVersion); - return; - } - - if (argResults['verbose'] as bool && !(argResults['help'] as bool)) { - usageError(parser, 'Can only use --verbose with --help.'); - } - - List? selection; try { - selection = parseSelection(argResults, 'preserve'); - } on FormatException catch (exception) { - usageError(parser, exception.message); - } - - if (argResults['dry-run'] as bool && argResults['overwrite'] as bool) { - usageError( - parser, 'Cannot use --dry-run and --overwrite at the same time.'); + await runner.runCommand(runner.parse(['format', ...arguments])); + } on UsageException catch (exception) { + stderr.writeln(exception); + exit(64); } - - void checkForReporterCollision(String chosen, String other) { - if (!(argResults[other] as bool)) return; - - usageError(parser, 'Cannot use --$chosen and --$other at the same time.'); - } - - var show = Show.legacy; - var summary = Summary.none; - var output = Output.show; - var setExitIfChanged = false; - if (argResults['dry-run'] as bool) { - checkForReporterCollision('dry-run', 'overwrite'); - checkForReporterCollision('dry-run', 'machine'); - - show = Show.dryRun; - output = Output.none; - } else if (argResults['overwrite'] as bool) { - checkForReporterCollision('overwrite', 'machine'); - - if (argResults.rest.isEmpty) { - usageError(parser, - 'Cannot use --overwrite without providing any paths to format.'); - } - - show = Show.overwrite; - output = Output.write; - } else if (argResults['machine'] as bool) { - output = Output.json; - } - - if (argResults['profile'] as bool) summary = Summary.profile(); - - setExitIfChanged = argResults['set-exit-if-changed'] as bool; - - int pageWidth; - try { - pageWidth = int.parse(argResults['line-length'] as String); - } on FormatException catch (_) { - usageError( - parser, - '--line-length must be an integer, was ' - '"${argResults['line-length']}".'); - } - - int indent; - try { - indent = int.parse(argResults['indent'] as String); - if (indent < 0 || indent.toInt() != indent) throw const FormatException(); - } on FormatException catch (_) { - usageError( - parser, - '--indent must be a non-negative integer, was ' - '"${argResults['indent']}".'); - } - - var followLinks = argResults['follow-links'] as bool; - - if (argResults.wasParsed('stdin-name') && argResults.rest.isNotEmpty) { - usageError(parser, 'Cannot pass --stdin-name when not reading from stdin.'); - } - - var options = FormatterOptions( - indent: indent, - pageWidth: pageWidth, - followLinks: followLinks, - show: show, - output: output, - summary: summary, - setExitIfChanged: setExitIfChanged, - experimentFlags: argResults['enable-experiment'] as List); - - if (argResults.rest.isEmpty) { - await formatStdin(options, selection, argResults['stdin-name'] as String); - } else { - await formatPaths(options, argResults.rest); - } - - options.summary.show(); -} - -/// Prints [error] and usage help then exits with exit code 64. -Never usageError(ArgParser parser, String error) { - printUsage(parser, error); - exit(64); -} - -void printUsage(ArgParser parser, [String? error]) { - var output = stdout; - - var message = 'Idiomatically format Dart source code.'; - if (error != null) { - message = error; - output = stdout; - } - - output.write('''$message - -Usage: dartfmt [options...] [files or directories...] - -Example: dartfmt -w . - Reformats every Dart file in the current directory tree. - -${parser.usage} -'''); } diff --git a/lib/src/cli/format_command.dart b/lib/src/cli/format_command.dart index 4f4bb6cc..cba4d16c 100644 --- a/lib/src/cli/format_command.dart +++ b/lib/src/cli/format_command.dart @@ -3,13 +3,13 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:io'; +import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:pub_semver/pub_semver.dart'; import '../dart_formatter.dart'; import '../io.dart'; import 'formatter_options.dart'; -import 'options.dart'; import 'output.dart'; import 'show.dart'; import 'summary.dart'; @@ -26,7 +26,90 @@ class FormatCommand extends Command { '${runner!.executableName} $name [options...] '; FormatCommand({bool verbose = false}) { - defineOptions(argParser, oldCli: false, verbose: verbose); + argParser.addFlag('verbose', + abbr: 'v', + negatable: false, + help: 'Show all options and flags with --help.'); + + if (verbose) argParser.addSeparator('Output options:'); + + argParser.addOption('output', + abbr: 'o', + help: 'Set where to write formatted output.', + allowed: ['write', 'show', 'json', 'none'], + allowedHelp: { + 'write': 'Overwrite formatted files on disk.', + 'show': 'Print code to terminal.', + 'json': 'Print code and selection as JSON.', + 'none': 'Discard output.' + }, + defaultsTo: 'write'); + argParser.addOption('show', + help: 'Set which filenames to print.', + allowed: ['all', 'changed', 'none'], + allowedHelp: { + 'all': 'All visited files and directories.', + 'changed': 'Only the names of files whose formatting is changed.', + 'none': 'No file names or directories.', + }, + defaultsTo: 'changed', + hide: !verbose); + argParser.addOption('summary', + help: 'Show the specified summary after formatting.', + allowed: ['line', 'profile', 'none'], + allowedHelp: { + 'line': 'Single-line summary.', + 'profile': 'How long it took for format each file.', + 'none': 'No summary.' + }, + defaultsTo: 'line', + hide: !verbose); + + argParser.addOption('language-version', + help: 'Language version of formatted code.\n' + 'Use "latest" to parse as the latest supported version.\n' + 'Omit to look for a surrounding package config.', + // TODO(rnystrom): Show this when the tall-style experiment ships. + hide: true); + + argParser.addFlag('set-exit-if-changed', + negatable: false, + help: 'Return exit code 1 if there are any formatting changes.'); + + if (verbose) argParser.addSeparator('Other options:'); + + argParser.addOption('line-length', + abbr: 'l', + help: 'Wrap lines longer than this.', + defaultsTo: '80', + hide: true); + argParser.addOption('indent', + abbr: 'i', + help: 'Add this many spaces of leading indentation.', + defaultsTo: '0', + hide: !verbose); + + argParser.addFlag('follow-links', + negatable: false, + help: 'Follow links to files and directories.\n' + 'If unset, links will be ignored.', + hide: !verbose); + argParser.addFlag('version', + negatable: false, help: 'Show dart_style version.', hide: !verbose); + argParser.addMultiOption('enable-experiment', + help: 'Enable one or more experimental features.\n' + 'See dart.dev/go/experiments.', + hide: !verbose); + + if (verbose) argParser.addSeparator('Options when formatting from stdin:'); + + argParser.addOption('selection', + help: 'Track selection (given as "start:length") through formatting.', + hide: !verbose); + argParser.addOption('stdin-name', + help: 'Use this path in error messages when input is read from stdin.', + defaultsTo: 'stdin', + hide: !verbose); } @override @@ -117,7 +200,7 @@ class FormatCommand extends Command { List? selection; try { - selection = parseSelection(argResults, 'selection'); + selection = _parseSelection(argResults, 'selection'); } on FormatException catch (exception) { usageException(exception.message); } @@ -164,4 +247,30 @@ class FormatCommand extends Command { // and set their own exitCode. return exitCode; } + + List? _parseSelection(ArgResults argResults, String optionName) { + var option = argResults[optionName] as String?; + if (option == null) return null; + + // Can only preserve a selection when parsing from stdin. + if (argResults.rest.isNotEmpty) { + throw FormatException( + 'Can only use --$optionName when reading from stdin.'); + } + + try { + var coordinates = option.split(':'); + if (coordinates.length != 2) { + throw const FormatException( + 'Selection should be a colon-separated pair of integers, ' + '"123:45".'); + } + + return coordinates.map((coord) => int.parse(coord.trim())).toList(); + } on FormatException catch (_) { + throw FormatException( + '--$optionName must be a colon-separated pair of integers, was ' + '"${argResults[optionName]}".'); + } + } } diff --git a/lib/src/cli/formatter_options.dart b/lib/src/cli/formatter_options.dart index bbfaa14d..d20e4238 100644 --- a/lib/src/cli/formatter_options.dart +++ b/lib/src/cli/formatter_options.dart @@ -89,21 +89,4 @@ class FormatterOptions { // Set the exit code. if (setExitIfChanged && changed) exitCode = 1; } - - /// Describes the directory whose contents are about to be processed. - void showDirectory(String path) { - if (output != Output.json) { - show.directory(path); - } - } - - /// Describes the symlink at [path] that wasn't followed. - void showSkippedLink(String path) { - show.skippedLink(path); - } - - /// Describes the hidden [path] that wasn't processed. - void showHiddenPath(String path) { - show.hiddenPath(path); - } } diff --git a/lib/src/cli/options.dart b/lib/src/cli/options.dart deleted file mode 100644 index 546623b2..00000000 --- a/lib/src/cli/options.dart +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -import 'package:args/args.dart'; - -void defineOptions(ArgParser parser, - {bool oldCli = false, bool verbose = false}) { - if (oldCli) { - // The Command class implicitly adds "--help", so we only need to manually - // add it for the old CLI. - parser.addFlag('help', - abbr: 'h', - negatable: false, - help: 'Show this usage information.\n' - '(pass "--verbose" or "-v" to see all options)'); - // Always make verbose hidden since the help text for --help explains it. - parser.addFlag('verbose', abbr: 'v', negatable: false, hide: true); - } else { - parser.addFlag('verbose', - abbr: 'v', - negatable: false, - help: 'Show all options and flags with --help.'); - } - - if (verbose) parser.addSeparator('Output options:'); - - if (oldCli) { - parser.addFlag('overwrite', - abbr: 'w', - negatable: false, - help: 'Overwrite input files with formatted output.'); - parser.addFlag('dry-run', - abbr: 'n', - negatable: false, - help: 'Show which files would be modified but make no changes.'); - } else { - parser.addOption('output', - abbr: 'o', - help: 'Set where to write formatted output.', - allowed: ['write', 'show', 'json', 'none'], - allowedHelp: { - 'write': 'Overwrite formatted files on disk.', - 'show': 'Print code to terminal.', - 'json': 'Print code and selection as JSON.', - 'none': 'Discard output.' - }, - defaultsTo: 'write'); - parser.addOption('show', - help: 'Set which filenames to print.', - allowed: ['all', 'changed', 'none'], - allowedHelp: { - 'all': 'All visited files and directories.', - 'changed': 'Only the names of files whose formatting is changed.', - 'none': 'No file names or directories.', - }, - defaultsTo: 'changed', - hide: !verbose); - parser.addOption('summary', - help: 'Show the specified summary after formatting.', - allowed: ['line', 'profile', 'none'], - allowedHelp: { - 'line': 'Single-line summary.', - 'profile': 'How long it took for format each file.', - 'none': 'No summary.' - }, - defaultsTo: 'line', - hide: !verbose); - - parser.addOption('language-version', - help: 'Language version of formatted code.\n' - 'Use "latest" to parse as the latest supported version.\n' - 'Omit to look for a surrounding package config.'); - } - - parser.addFlag('set-exit-if-changed', - negatable: false, - help: 'Return exit code 1 if there are any formatting changes.'); - - if (verbose) parser.addSeparator('Other options:'); - - parser.addOption('line-length', - abbr: 'l', - help: 'Wrap lines longer than this.', - defaultsTo: '80', - hide: true); - parser.addOption('indent', - abbr: 'i', - help: 'Add this many spaces of leading indentation.', - defaultsTo: '0', - hide: !verbose); - if (oldCli) { - parser.addFlag('machine', - abbr: 'm', - negatable: false, - help: 'Produce machine-readable JSON output.', - hide: !verbose); - } - - parser.addFlag('follow-links', - negatable: false, - help: 'Follow links to files and directories.\n' - 'If unset, links will be ignored.', - hide: !verbose); - parser.addFlag('version', - negatable: false, help: 'Show dart_style version.', hide: !verbose); - parser.addMultiOption('enable-experiment', - help: 'Enable one or more experimental features.\n' - 'See dart.dev/go/experiments.', - hide: !verbose); - - if (verbose) parser.addSeparator('Options when formatting from stdin:'); - - parser.addOption(oldCli ? 'preserve' : 'selection', - help: 'Track selection (given as "start:length") through formatting.', - hide: !verbose); - parser.addOption('stdin-name', - help: 'Use this path in error messages when input is read from stdin.', - defaultsTo: 'stdin', - hide: !verbose); - - if (oldCli) { - parser.addFlag('profile', negatable: false, hide: true); - - // Ancient no longer used flag. - parser.addFlag('transform', abbr: 't', negatable: false, hide: true); - } -} - -List? parseSelection(ArgResults argResults, String optionName) { - var option = argResults[optionName] as String?; - if (option == null) return null; - - // Can only preserve a selection when parsing from stdin. - if (argResults.rest.isNotEmpty) { - throw FormatException( - 'Can only use --$optionName when reading from stdin.'); - } - - try { - var coordinates = option.split(':'); - if (coordinates.length != 2) { - throw const FormatException( - 'Selection should be a colon-separated pair of integers, "123:45".'); - } - - return coordinates.map((coord) => int.parse(coord.trim())).toList(); - } on FormatException catch (_) { - throw FormatException( - '--$optionName must be a colon-separated pair of integers, was ' - '"${argResults[optionName]}".'); - } -} diff --git a/lib/src/cli/show.dart b/lib/src/cli/show.dart index eea28e1b..ec8c1d51 100644 --- a/lib/src/cli/show.dart +++ b/lib/src/cli/show.dart @@ -1,7 +1,6 @@ // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:path/path.dart' as p; /// Which file paths should be printed. enum Show { @@ -12,34 +11,7 @@ enum Show { all, /// Only files whose formatting changed. - changed, - - /// The legacy dartfmt output style when not overwriting files. - legacy, - - /// The legacy dartfmt output style when overwriting files. - overwrite, - - /// The legacy dartfmt output style in "--dry-run". - dryRun; - - /// The display path to show for [file] which is in [directory]. - /// - /// In the old CLI, this does not include [directory], since the directory - /// name is printed separately. The new CLI only prints file paths, so this - /// includes the root directory to disambiguate which directory the file is - /// in. - String displayPath(String directory, String file) { - switch (this) { - case Show.legacy: - case Show.overwrite: - case Show.dryRun: - return p.relative(file, from: directory); - - default: - return p.normalize(file); - } - } + changed; /// Describes a file that was processed. /// @@ -47,7 +19,6 @@ enum Show { bool file(String path, {required bool changed, required bool overwritten}) { switch (this) { case Show.all: - case Show.overwrite: if (changed) { _showFileChange(path, overwritten: overwritten); } else { @@ -59,36 +30,11 @@ enum Show { if (changed) _showFileChange(path, overwritten: overwritten); return changed; - case Show.dryRun: - if (changed) print(path); - return true; - default: return true; } } - /// Describes the directory whose contents are about to be processed. - void directory(String path) { - if (this == Show.legacy || this == Show.overwrite) { - print('Formatting directory $path:'); - } - } - - /// Describes the symlink at [path] that wasn't followed. - void skippedLink(String path) { - if (this == Show.legacy || this == Show.overwrite) { - print('Skipping link $path'); - } - } - - /// Describes the hidden [path] that wasn't processed. - void hiddenPath(String path) { - if (this == Show.legacy || this == Show.overwrite) { - print('Skipping hidden path $path'); - } - } - void _showFileChange(String path, {required bool overwritten}) { if (overwritten) { print('Formatted $path'); diff --git a/lib/src/io.dart b/lib/src/io.dart index 01aa2492..96429ece 100644 --- a/lib/src/io.dart +++ b/lib/src/io.dart @@ -100,46 +100,23 @@ Future formatPaths(FormatterOptions options, List paths) async { /// files. Future _processDirectory(LanguageVersionCache? cache, FormatterOptions options, Directory directory) async { - options.showDirectory(directory.path); - var success = true; - var shownHiddenPaths = {}; var entries = directory.listSync(recursive: true, followLinks: options.followLinks); entries.sort((a, b) => a.path.compareTo(b.path)); for (var entry in entries) { - var displayPath = options.show.displayPath(directory.path, entry.path); - - if (entry is Link) { - options.showSkippedLink(displayPath); - continue; - } + if (entry is Link) continue; if (entry is! File || !entry.path.endsWith('.dart')) continue; // If the path is in a subdirectory starting with ".", ignore it. var parts = p.split(p.relative(entry.path, from: directory.path)); - int? hiddenIndex; - for (var i = 0; i < parts.length; i++) { - if (parts[i].startsWith('.')) { - hiddenIndex = i; - break; - } - } - - if (hiddenIndex != null) { - // Since we'll hide everything inside the directory starting with ".", - // show the directory name once instead of once for each file. - var hiddenPath = p.joinAll(parts.take(hiddenIndex + 1)); - if (shownHiddenPaths.add(hiddenPath)) { - options.showHiddenPath(hiddenPath); - } - continue; - } + if (parts.any((part) => part.startsWith('.'))) continue; - if (!await _processFile(cache, options, entry, displayPath: displayPath)) { + if (!await _processFile(cache, options, entry, + displayPath: p.normalize(entry.path))) { success = false; } } diff --git a/pubspec.yaml b/pubspec.yaml index a11be0a9..f6d98b09 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,7 +24,3 @@ dev_dependencies: test_descriptor: ^2.0.0 test_process: ^2.0.0 yaml: ">=2.0.0 <4.0.0" - -executables: - dartfmt: format - dartformat: format # Allow the old name for compatibility. diff --git a/test/command_test.dart b/test/cli_test.dart similarity index 86% rename from test/command_test.dart rename to test/cli_test.dart index 90e3570a..0ad70c34 100644 --- a/test/command_test.dart +++ b/test/cli_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. @@ -11,7 +11,7 @@ import 'package:test_descriptor/test_descriptor.dart' as d; import 'utils.dart'; void main() { - compileCommandExecutable(); + compileFormatter(); test('formats a directory', () async { await d.dir('code', [ @@ -20,7 +20,7 @@ void main() { d.file('c.dart', unformattedSource) ]).create(); - var process = await runCommandOnDir(); + var process = await runFormatterOnDir(); expect(await process.stdout.next, 'Formatted ${p.join('code', 'a.dart')}'); expect(await process.stdout.next, 'Formatted ${p.join('code', 'c.dart')}'); expect(await process.stdout.next, @@ -41,8 +41,8 @@ void main() { d.file('c.dart', unformattedSource) ]).create(); - var process = - await runCommand([p.join('code', 'subdir'), p.join('code', 'c.dart')]); + var process = await runFormatter( + [p.join('code', 'subdir'), p.join('code', 'c.dart')]); expect(await process.stdout.next, 'Formatted ${p.join('code', 'subdir', 'a.dart')}'); expect(await process.stdout.next, 'Formatted ${p.join('code', 'c.dart')}'); @@ -61,14 +61,14 @@ void main() { }); test('exits with 64 on a command line argument error', () async { - var process = await runCommand(['-wat']); + var process = await runFormatter(['-wat']); await process.shouldExit(64); }); test('exits with 65 on a parse error', () async { await d.dir('code', [d.file('a.dart', 'herp derp i are a dart')]).create(); - var process = await runCommandOnDir(); + var process = await runFormatterOnDir(); await process.shouldExit(65); }); @@ -80,7 +80,7 @@ void main() { d.file('c.dart', unformattedSource) ]).create(); - var process = await runCommandOnDir(['--show=all']); + var process = await runFormatterOnDir(['--show=all']); expect( await process.stdout.next, 'Formatted ${p.join('code', 'a.dart')}'); expect( @@ -99,7 +99,7 @@ void main() { d.file('c.dart', unformattedSource) ]).create(); - var process = await runCommandOnDir(['--show=none']); + var process = await runFormatterOnDir(['--show=none']); expect(await process.stdout.next, startsWith(r'Formatted 3 files (2 changed)')); await process.shouldExit(0); @@ -112,7 +112,7 @@ void main() { d.file('c.dart', unformattedSource) ]).create(); - var process = await runCommandOnDir(['--show=changed']); + var process = await runFormatterOnDir(['--show=changed']); expect( await process.stdout.next, 'Formatted ${p.join('code', 'a.dart')}'); expect( @@ -131,7 +131,7 @@ void main() { d.file('b.dart', formattedSource) ]).create(); - var process = await runCommandOnDir(['--output=show']); + var process = await runFormatterOnDir(['--output=show']); expect(await process.stdout.next, formattedOutput); expect(await process.stdout.next, formattedOutput); expect(await process.stdout.next, @@ -148,7 +148,7 @@ void main() { d.file('b.dart', formattedSource) ]).create(); - var process = await runCommandOnDir(['--output=show', '--show=all']); + var process = await runFormatterOnDir(['--output=show', '--show=all']); expect( await process.stdout.next, 'Changed ${p.join('code', 'a.dart')}'); expect(await process.stdout.next, formattedOutput); @@ -170,7 +170,7 @@ void main() { ]).create(); var process = - await runCommandOnDir(['--output=show', '--show=changed']); + await runFormatterOnDir(['--output=show', '--show=changed']); expect( await process.stdout.next, 'Changed ${p.join('code', 'a.dart')}'); expect(await process.stdout.next, formattedOutput); @@ -202,7 +202,7 @@ void main() { 'selection': {'offset': -1, 'length': -1} }); - var process = await runCommandOnDir(['--output=json']); + var process = await runFormatterOnDir(['--output=json']); expect(await process.stdout.next, jsonA); expect(await process.stdout.next, jsonB); @@ -211,7 +211,7 @@ void main() { test('errors if the summary is not none', () async { var process = - await runCommandOnDir(['--output=json', '--summary=line']); + await runFormatterOnDir(['--output=json', '--summary=line']); await process.shouldExit(64); }); }); @@ -223,7 +223,7 @@ void main() { d.file('b.dart', formattedSource) ]).create(); - var process = await runCommandOnDir(['--output=none', '--show=all']); + var process = await runFormatterOnDir(['--output=none', '--show=all']); expect( await process.stdout.next, 'Changed ${p.join('code', 'a.dart')}'); expect( @@ -243,7 +243,7 @@ void main() { ]).create(); var process = - await runCommandOnDir(['--output=none', '--show=changed']); + await runFormatterOnDir(['--output=none', '--show=changed']); expect( await process.stdout.next, 'Changed ${p.join('code', 'a.dart')}'); expect(await process.stdout.next, @@ -263,7 +263,7 @@ void main() { d.file('b.dart', formattedSource) ]).create(); - var process = await runCommandOnDir(['--summary=line']); + var process = await runFormatterOnDir(['--summary=line']); expect( await process.stdout.next, 'Formatted ${p.join('code', 'a.dart')}'); expect(await process.stdout.next, @@ -273,7 +273,7 @@ void main() { }); test('--version prints the version number', () async { - var process = await runCommand(['--version']); + var process = await runFormatter(['--version']); // Match something roughly semver-like. expect(await process.stdout.next, matches(RegExp(r'\d+\.\d+\.\d+.*'))); @@ -282,7 +282,7 @@ void main() { group('--help', () { test('non-verbose shows description and common options', () async { - var process = await runCommand(['--help']); + var process = await runFormatter(['--help']); expect( await process.stdout.next, 'Idiomatically format Dart source code.'); await expectLater(process.stdout, emitsThrough(contains('-o, --output'))); @@ -291,7 +291,7 @@ void main() { }); test('verbose shows description and all options', () async { - var process = await runCommand(['--help', '--verbose']); + var process = await runFormatter(['--help', '--verbose']); expect( await process.stdout.next, 'Idiomatically format Dart source code.'); await expectLater(process.stdout, emitsThrough(contains('-o, --output'))); @@ -302,14 +302,14 @@ void main() { }); test('--verbose errors if not used with --help', () async { - var process = await runCommandOnDir(['--verbose']); + var process = await runFormatterOnDir(['--verbose']); expect(await process.stderr.next, 'Can only use --verbose with --help.'); await process.shouldExit(64); }); group('--indent', () { test('sets the leading indentation of the output', () async { - var process = await runCommand(['--indent=3']); + var process = await runFormatter(['--indent=3']); process.stdin.writeln("main() {'''"); process.stdin.writeln("a flush left multi-line string''';}"); await process.stdin.close(); @@ -322,10 +322,10 @@ void main() { }); test('errors if the indent is not a non-negative number', () async { - var process = await runCommand(['--indent=notanum']); + var process = await runFormatter(['--indent=notanum']); await process.shouldExit(64); - process = await runCommand(['--indent=-4']); + process = await runFormatter(['--indent=-4']); await process.shouldExit(64); }); }); @@ -334,14 +334,14 @@ void main() { test('gives exit code 0 if there are no changes', () async { await d.dir('code', [d.file('a.dart', formattedSource)]).create(); - var process = await runCommandOnDir(['--set-exit-if-changed']); + var process = await runFormatterOnDir(['--set-exit-if-changed']); await process.shouldExit(0); }); test('gives exit code 1 if there are changes', () async { await d.dir('code', [d.file('a.dart', unformattedSource)]).create(); - var process = await runCommandOnDir(['--set-exit-if-changed']); + var process = await runFormatterOnDir(['--set-exit-if-changed']); await process.shouldExit(1); }); @@ -349,32 +349,32 @@ void main() { await d.dir('code', [d.file('a.dart', unformattedSource)]).create(); var process = - await runCommandOnDir(['--set-exit-if-changed', '--show=none']); + await runFormatterOnDir(['--set-exit-if-changed', '--show=none']); await process.shouldExit(1); }); }); group('--selection', () { test('errors if given path', () async { - var process = await runCommand(['--selection', 'path']); + var process = await runFormatter(['--selection', 'path']); await process.shouldExit(64); }); test('errors on wrong number of components', () async { - var process = await runCommand(['--selection', '1']); + var process = await runFormatter(['--selection', '1']); await process.shouldExit(64); - process = await runCommand(['--selection', '1:2:3']); + process = await runFormatter(['--selection', '1:2:3']); await process.shouldExit(64); }); test('errors on non-integer component', () async { - var process = await runCommand(['--selection', '1:2.3']); + var process = await runFormatter(['--selection', '1:2.3']); await process.shouldExit(64); }); test('updates selection', () async { - var process = await runCommand(['--output=json', '--selection=6:10']); + var process = await runFormatter(['--output=json', '--selection=6:10']); process.stdin.writeln(unformattedSource); await process.stdin.close(); @@ -391,7 +391,7 @@ void main() { group('--stdin-name', () { test('errors if given path', () async { - var process = await runCommand(['--stdin-name=name', 'path']); + var process = await runFormatter(['--stdin-name=name', 'path']); await process.shouldExit(64); }); }); @@ -414,7 +414,7 @@ extension type Meters(int value) { test('defaults to latest language version if omitted', () async { await d.dir('code', [d.file('a.dart', extensionTypeBefore)]).create(); - var process = await runCommandOnDir(); + var process = await runFormatterOnDir(); await process.shouldExit(0); await d.dir('code', [d.file('a.dart', extensionTypeAfter)]).validate(); @@ -436,7 +436,7 @@ main() { // Use an older language version where `1 + 2` was still a valid switch // case. - var process = await runCommandOnDir(['--language-version=2.19']); + var process = await runFormatterOnDir(['--language-version=2.19']); await process.shouldExit(0); await d.dir('code', [d.file('a.dart', after)]).validate(); @@ -445,14 +445,14 @@ main() { test('uses the latest language version if "latest"', () async { await d.dir('code', [d.file('a.dart', extensionTypeBefore)]).create(); - var process = await runCommandOnDir(['--language-version=latest']); + var process = await runFormatterOnDir(['--language-version=latest']); await process.shouldExit(0); await d.dir('code', [d.file('a.dart', extensionTypeAfter)]).validate(); }); test("errors if the language version can't be parsed", () async { - var process = await runCommand(['--language-version=123']); + var process = await runFormatter(['--language-version=123']); await process.shouldExit(64); }); }); @@ -460,7 +460,7 @@ main() { group('--enable-experiment', () { test('passes experiment flags to parser', () async { var process = - await runCommand(['--enable-experiment=test-experiment,variance']); + await runFormatter(['--enable-experiment=test-experiment,variance']); process.stdin.writeln('class Writer {}'); await process.stdin.close(); @@ -484,19 +484,19 @@ main() { group('with no paths', () { test('errors on --output=write', () async { - var process = await runCommand(['--output=write']); + var process = await runFormatter(['--output=write']); await process.shouldExit(64); }); test('exits with 65 on parse error', () async { - var process = await runCommand(); + var process = await runFormatter(); process.stdin.writeln('herp derp i are a dart'); await process.stdin.close(); await process.shouldExit(65); }); test('reads from stdin', () async { - var process = await runCommand(); + var process = await runFormatter(); process.stdin.writeln(unformattedSource); await process.stdin.close(); @@ -507,7 +507,7 @@ main() { test('allows specifying stdin path name', () async { var path = p.join('some', 'path.dart'); - var process = await runCommand(['--stdin-name=$path']); + var process = await runFormatter(['--stdin-name=$path']); process.stdin.writeln('herp'); await process.stdin.close(); @@ -531,7 +531,7 @@ main() { d.file('main.dart', 'main(){ }'), ]).create(); - var process = await runCommandOnDir(); + var process = await runFormatterOnDir(); await process.shouldExit(0); // Should format the file without any error reading the package config. @@ -548,7 +548,7 @@ main() { d.file('main.dart', 'main(){ }'), ]).create(); - var process = await runCommandOnDir( + var process = await runFormatterOnDir( ['--language-version=latest', '--enable-experiment=tall-style']); await process.shouldExit(0); @@ -570,7 +570,7 @@ main() { var path = p.join(d.sandbox, 'foo', 'main.dart'); // TODO(rnystrom): Remove experiment flag when it ships. var process = - await runCommand([path, '--enable-experiment=tall-style']); + await runFormatter([path, '--enable-experiment=tall-style']); expect(await process.stderr.next, 'Could not format because the source could not be parsed:'); @@ -593,7 +593,7 @@ main() { '''), ]).create(); - var process = await runCommandOnDir(); + var process = await runFormatterOnDir(); await process.shouldExit(0); // Formats the file. @@ -620,7 +620,7 @@ main() { var path = p.join(d.sandbox, 'foo', 'main.dart'); // TODO(rnystrom): Remove experiment flag when it ships. var process = - await runCommand([path, '--enable-experiment=tall-style']); + await runFormatter([path, '--enable-experiment=tall-style']); expect( await process.stderr.next, diff --git a/test/command_line_test.dart b/test/command_line_test.dart deleted file mode 100644 index 83683386..00000000 --- a/test/command_line_test.dart +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:convert'; - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; -import 'package:test_descriptor/test_descriptor.dart' as d; - -import 'utils.dart'; - -void main() { - compileFormatterExecutable(); - - test('formats a directory', () async { - await d.dir('code', [ - d.file('a.dart', unformattedSource), - d.file('b.dart', formattedSource), - d.file('c.dart', unformattedSource) - ]).create(); - - var process = await runFormatterOnDir(); - await expectLater( - process.stdout, emits(startsWith('Formatting directory'))); - - // Prints the formatting result. - await expectLater(process.stdout, emits(formattedOutput)); - await expectLater(process.stdout, emits(formattedOutput)); - await expectLater(process.stdout, emits(formattedOutput)); - await process.shouldExit(0); - - // Does not overwrite by default. - await d.dir('code', [d.file('a.dart', unformattedSource)]).validate(); - await d.dir('code', [d.file('c.dart', unformattedSource)]).validate(); - }); - - test('Overwrites files', () async { - await d.dir('code', [ - d.file('a.dart', unformattedSource), - d.file('b.dart', formattedSource), - d.file('c.dart', unformattedSource) - ]).create(); - - var process = await runFormatterOnDir(['--overwrite']); - await expectLater( - process.stdout, emits(startsWith('Formatting directory'))); - - // Prints whether each file was changed. - await expectLater( - process.stdout, emits('Formatted ${p.join('code', 'a.dart')}')); - await expectLater( - process.stdout, emits('Unchanged ${p.join('code', 'b.dart')}')); - await expectLater( - process.stdout, emits('Formatted ${p.join('code', 'c.dart')}')); - await process.shouldExit(0); - - // Overwrites the files. - await d.dir('code', [d.file('a.dart', formattedSource)]).validate(); - await d.dir('code', [d.file('c.dart', formattedSource)]).validate(); - }); - - test('exits with 64 on a command line argument error', () async { - var process = await runFormatter(['-wat']); - await process.shouldExit(64); - }); - - test('exits with 65 on a parse error', () async { - await d.dir('code', [d.file('a.dart', 'herp derp i are a dart')]).create(); - - var process = await runFormatterOnDir(); - await process.shouldExit(65); - }); - - test('errors if --dry-run and --overwrite are both passed', () async { - var process = await runFormatter(['--dry-run', '--overwrite']); - await process.shouldExit(64); - }); - - test('errors if --dry-run and --machine are both passed', () async { - var process = await runFormatter(['--dry-run', '--machine']); - await process.shouldExit(64); - }); - - test('errors if --machine and --overwrite are both passed', () async { - var process = await runFormatter(['--machine', '--overwrite']); - await process.shouldExit(64); - }); - - test('errors if --dry-run and --machine are both passed', () async { - var process = await runFormatter(['--dry-run', '--machine']); - await process.shouldExit(64); - }); - - test('errors if --machine and --overwrite are both passed', () async { - var process = await runFormatter(['--machine', '--overwrite']); - await process.shouldExit(64); - }); - - test('errors if --stdin-name and a path are both passed', () async { - var process = await runFormatter(['--stdin-name=name', 'path.dart']); - await process.shouldExit(64); - }); - - test('--version prints the version number', () async { - var process = await runFormatter(['--version']); - - // Match something roughly semver-like. - expect(await process.stdout.next, matches(RegExp(r'\d+\.\d+\.\d+.*'))); - await process.shouldExit(0); - }); - - group('--help', () { - test('non-verbose shows description and common options', () async { - var process = await runFormatter(['--help']); - await expectLater( - process.stdout, emits('Idiomatically format Dart source code.')); - await expectLater(process.stdout, emits('')); - await expectLater(process.stdout, - emits('Usage: dartfmt [options...] [files or directories...]')); - await expectLater(process.stdout, emitsThrough(contains('--overwrite'))); - await expectLater( - process.stdout, emitsThrough(contains('--set-exit-if-changed'))); - await process.shouldExit(0); - }); - - test('verbose shows description and all options', () async { - var process = await runFormatter(['--help', '--verbose']); - await expectLater( - process.stdout, emits('Idiomatically format Dart source code.')); - await expectLater(process.stdout, emits('')); - await expectLater(process.stdout, - emits('Usage: dartfmt [options...] [files or directories...]')); - await expectLater(process.stdout, emitsThrough(contains('--overwrite'))); - await expectLater( - process.stdout, emitsThrough(contains('--set-exit-if-changed'))); - await process.shouldExit(0); - }); - }); - - test('--verbose errors if not used with --help', () async { - var process = await runFormatterOnDir(['--verbose']); - expect(await process.stdout.next, 'Can only use --verbose with --help.'); - await process.shouldExit(64); - }); - - test('only prints a hidden directory once', () async { - await d.dir('code', [ - d.dir('.skip', [ - d.file('a.dart', unformattedSource), - d.file('b.dart', unformattedSource) - ]) - ]).create(); - - var process = await runFormatterOnDir(); - - expect(await process.stdout.next, startsWith('Formatting directory')); - expect(await process.stdout.next, - "Skipping hidden path ${p.join("code", ".skip")}"); - await process.shouldExit(); - }); - - group('--dry-run', () { - test('prints names of files that would change', () async { - await d.dir('code', [ - d.file('a_bad.dart', unformattedSource), - d.file('b_good.dart', formattedSource), - d.file('c_bad.dart', unformattedSource), - d.file('d_good.dart', formattedSource) - ]).create(); - - var aBad = p.join('code', 'a_bad.dart'); - var cBad = p.join('code', 'c_bad.dart'); - - var process = await runFormatterOnDir(['--dry-run']); - - // The order isn't specified. - expect(await process.stdout.next, anyOf(aBad, cBad)); - expect(await process.stdout.next, anyOf(aBad, cBad)); - await process.shouldExit(); - }); - - test('does not modify files', () async { - await d.dir('code', [d.file('a.dart', unformattedSource)]).create(); - - var process = await runFormatterOnDir(['--dry-run']); - expect(await process.stdout.next, p.join('code', 'a.dart')); - await process.shouldExit(); - - await d.dir('code', [d.file('a.dart', unformattedSource)]).validate(); - }); - }); - - group('--machine', () { - test('writes each output as json', () async { - await d.dir('code', [ - d.file('a.dart', unformattedSource), - d.file('b.dart', unformattedSource) - ]).create(); - - var jsonA = jsonEncode({ - 'path': p.join('code', 'a.dart'), - 'source': formattedSource, - 'selection': {'offset': -1, 'length': -1} - }); - - var jsonB = jsonEncode({ - 'path': p.join('code', 'b.dart'), - 'source': formattedSource, - 'selection': {'offset': -1, 'length': -1} - }); - - var process = await runFormatterOnDir(['--machine']); - - // The order isn't specified. - expect(await process.stdout.next, anyOf(jsonA, jsonB)); - expect(await process.stdout.next, anyOf(jsonA, jsonB)); - await process.shouldExit(); - }); - }); - - group('--preserve', () { - test('errors if given paths', () async { - var process = await runFormatter(['--preserve', 'path', 'another']); - await process.shouldExit(64); - }); - - test('errors on wrong number of components', () async { - var process = await runFormatter(['--preserve', '1']); - await process.shouldExit(64); - - process = await runFormatter(['--preserve', '1:2:3']); - await process.shouldExit(64); - }); - - test('errors on non-integer component', () async { - var process = await runFormatter(['--preserve', '1:2.3']); - await process.shouldExit(64); - }); - - test('updates selection', () async { - var process = await runFormatter(['--preserve', '6:10', '-m']); - process.stdin.writeln(unformattedSource); - await process.stdin.close(); - - var json = jsonEncode({ - 'path': 'stdin', - 'source': formattedSource, - 'selection': {'offset': 5, 'length': 9} - }); - - expect(await process.stdout.next, json); - await process.shouldExit(); - }); - }); - - group('--indent', () { - test('sets the leading indentation of the output', () async { - var process = await runFormatter(['--indent', '3']); - process.stdin.writeln("main() {'''"); - process.stdin.writeln("a flush left multi-line string''';}"); - await process.stdin.close(); - - expect(await process.stdout.next, ' main() {'); - expect(await process.stdout.next, " '''"); - expect(await process.stdout.next, "a flush left multi-line string''';"); - expect(await process.stdout.next, ' }'); - await process.shouldExit(0); - }); - - test('errors if the indent is not a non-negative number', () async { - var process = await runFormatter(['--indent', 'notanum']); - await process.shouldExit(64); - - process = await runFormatter(['--indent', '-4']); - await process.shouldExit(64); - }); - }); - - group('--set-exit-if-changed', () { - test('gives exit code 0 if there are no changes', () async { - await d.dir('code', [d.file('a.dart', formattedSource)]).create(); - - var process = await runFormatterOnDir(['--set-exit-if-changed']); - await process.shouldExit(0); - }); - - test('gives exit code 1 if there are changes', () async { - await d.dir('code', [d.file('a.dart', unformattedSource)]).create(); - - var process = await runFormatterOnDir(['--set-exit-if-changed']); - await process.shouldExit(1); - }); - - test('gives exit code 1 if there are changes even in dry run', () async { - await d.dir('code', [d.file('a.dart', unformattedSource)]).create(); - - var process = - await runFormatterOnDir(['--set-exit-if-changed', '--dry-run']); - await process.shouldExit(1); - }); - }); - - group('with no paths', () { - test('errors on --overwrite', () async { - var process = await runFormatter(['--overwrite']); - await process.shouldExit(64); - }); - - test('exits with 65 on parse error', () async { - var process = await runFormatter(); - process.stdin.writeln('herp derp i are a dart'); - await process.stdin.close(); - await process.shouldExit(65); - }); - - test('reads from stdin', () async { - var process = await runFormatter(); - process.stdin.writeln(unformattedSource); - await process.stdin.close(); - - // No trailing newline at the end. - expect(await process.stdout.next, formattedOutput); - await process.shouldExit(0); - }); - - test('allows specifying stdin path name', () async { - var path = p.join('some', 'path.dart'); - var process = await runFormatter(['--stdin-name=$path']); - process.stdin.writeln('herp'); - await process.stdin.close(); - - expect(await process.stderr.next, - 'Could not format because the source could not be parsed:'); - expect(await process.stderr.next, ''); - expect(await process.stderr.next, contains(path)); - await process.stderr.cancel(); - await process.shouldExit(65); - }); - }); -} diff --git a/test/utils.dart b/test/utils.dart index 0dbd1d7b..b36cde16 100644 --- a/test/utils.dart +++ b/test/utils.dart @@ -20,115 +20,63 @@ const formattedSource = 'void main() => print("hello");\n'; /// [TestProcess] filters those when it strips command line output into lines. const formattedOutput = 'void main() => print("hello");'; -/// If tool/command_shell.dart has been compiled to a snapshot, this is the path -/// to it. -String? _commandExecutablePath; +/// If `bin/format.dart` has been compiled to a snapshot, this is the path to +/// it. +String? _formatterPath; -/// If bin/format.dart has been compiled to a snapshot, this is the path to it. -String? _formatterExecutablePath; - -/// Compiles format.dart to a native executable for tests to use. +/// Compiles `bin/format.dart` to a native executable for tests to use. /// -/// Calls [setupAll()] and [tearDownAll()] to coordinate this when the +/// Calls [setupAll()] and [tearDownAll()] to coordinate this with the /// subsequent tests and to clean up the executable. -void compileFormatterExecutable() { +void compileFormatter() { setUpAll(() async { - _formatterExecutablePath = await _compileSnapshot('bin/format.dart'); - }); - - tearDownAll(() async { - await _deleteSnapshot(_formatterExecutablePath!); - _formatterExecutablePath = null; - }); -} - -/// Compiles command_shell.dart to a native executable for tests to use. -/// -/// Calls [setupAll()] and [tearDownAll()] to coordinate this when the -/// subsequent tests and to clean up the executable. -void compileCommandExecutable() { - setUpAll(() async { - _commandExecutablePath = await _compileSnapshot('tool/command_shell.dart'); + var tempDir = + await Directory.systemTemp.createTemp(p.withoutExtension('format')); + _formatterPath = p.join(tempDir.path, 'format.dart.snapshot'); + var scriptPath = + p.normalize(p.join(await findTestDirectory(), '../bin/format.dart')); + + var compileResult = await Process.run(Platform.resolvedExecutable, [ + '--snapshot-kind=app-jit', + '--snapshot=$_formatterPath', + scriptPath, + '--help' + ]); + + if (compileResult.exitCode != 0) { + fail('Could not compile format.dart to a snapshot (exit code ' + '${compileResult.exitCode}):\n${compileResult.stdout}\n\n' + '${compileResult.stderr}'); + } }); tearDownAll(() async { - await _deleteSnapshot(_commandExecutablePath!); - _commandExecutablePath = null; + try { + await Directory(p.dirname(_formatterPath!)).delete(recursive: true); + } on IOException { + // Do nothing if we failed to delete it. The OS will eventually clean it + // up. + } }); } -/// Compile the Dart [script] to an app-JIT snapshot. -/// -/// We do this instead of spawning the script from source each time because it's -/// much faster when the same script needs to be run several times. -Future _compileSnapshot(String script) async { - var scriptName = p.basename(script); - var tempDir = - await Directory.systemTemp.createTemp(p.withoutExtension(scriptName)); - var snapshot = p.join(tempDir.path, '$scriptName.snapshot'); - var scriptPath = p.normalize(p.join(await findTestDirectory(), '..', script)); - - var compileResult = await Process.run(Platform.resolvedExecutable, [ - '--snapshot-kind=app-jit', - '--snapshot=$snapshot', - scriptPath, - '--help' - ]); - - if (compileResult.exitCode != 0) { - fail('Could not compile $scriptName to a snapshot (exit code ' - '${compileResult.exitCode}):\n${compileResult.stdout}\n\n' - '${compileResult.stderr}'); - } - - return snapshot; -} - -/// Attempts to delete to temporary directory created for [snapshot] by -/// [_compileSnapshot()]. -Future _deleteSnapshot(String snapshot) async { - try { - await Directory(p.dirname(snapshot)).delete(recursive: true); - } on IOException { - // Do nothing if we failed to delete it. The OS will eventually clean it - // up. - } -} - -/// Runs the command line formatter, passing it [args]. +/// Runs the command-line formatter, passing it [args]. Future runFormatter([List? args]) { - if (_formatterExecutablePath == null) { - fail('Must call createFormatterExecutable() before running commands.'); + if (_formatterPath == null) { + fail('Must call createCommandExecutable() before running commands.'); } return TestProcess.start( - Platform.resolvedExecutable, [_formatterExecutablePath!, ...?args], + Platform.resolvedExecutable, [_formatterPath!, ...?args], workingDirectory: d.sandbox); } -/// Runs the command line formatter, passing it the test directory followed by +/// Runs the command-line formatter, passing it the test directory followed by /// [args]. Future runFormatterOnDir([List? args]) { return runFormatter(['.', ...?args]); } -/// Runs the test shell for the [Command]-based formatter, passing it [args]. -Future runCommand([List? args]) { - if (_commandExecutablePath == null) { - fail('Must call createCommandExecutable() before running commands.'); - } - - return TestProcess.start(Platform.resolvedExecutable, - [_commandExecutablePath!, 'format', ...?args], - workingDirectory: d.sandbox); -} - -/// Runs the test shell for the [Command]-based formatter, passing it the test -/// directory followed by [args]. -Future runCommandOnDir([List? args]) { - return runCommand(['.', ...?args]); -} - /// Run tests defined in "*.unit" and "*.stmt" files inside directory [path]. Future testDirectory(String path) async { for (var test in await TestFile.listDirectory(path)) { diff --git a/tool/command_shell.dart b/tool/command_shell.dart deleted file mode 100644 index 672ac1c7..00000000 --- a/tool/command_shell.dart +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -import 'dart:io'; - -import 'package:args/command_runner.dart'; - -import 'package:dart_style/src/cli/format_command.dart'; - -/// A simple executable wrapper around the [Command] API defined by dart_style. -/// -/// This enables tests to spawn this executable in order to verify the output -/// it prints. -void main(List arguments) async { - var runner = CommandRunner( - 'command_shell', 'Idiomatically format Dart source code.'); - runner.argParser.addFlag('verbose', - abbr: 'v', negatable: false, help: 'Show verbose help.'); - runner.addCommand(FormatCommand( - verbose: arguments.contains('-v') || arguments.contains('--verbose'))); - - try { - await runner.runCommand(runner.parse(arguments)); - } on UsageException catch (exception) { - stderr.writeln(exception); - exit(64); - } -}