| // 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'; | |
| import 'package:args/command_runner.dart'; | |
| import 'package:cli_util/cli_logging.dart'; | |
| import 'package:dartdev/src/commands/fix.dart'; | |
| import 'package:dartdev/src/core.dart'; | |
| import 'package:dartdev/src/utils.dart'; | |
| Future<int?> main(List<String> args) async { | |
| var runner = FixRunner(logger: Logger.standard()); | |
| var result = await runner.runFix(args); | |
| return result.returnCode; | |
| } | |
| class CapturedProgress extends Progress { | |
| final LoggerOutput output; | |
| bool canceled = false; | |
| bool finished = false; | |
| CapturedProgress(this.output, String message) : super(message) { | |
| output.progress.writeln(message); | |
| } | |
| @override | |
| void cancel() { | |
| canceled = true; | |
| } | |
| @override | |
| void finish({String? message, bool showTiming = false}) { | |
| // todo (pq): consider capturing / tracking finish display updates. | |
| finished = true; | |
| } | |
| } | |
| class CapturingLogger implements Logger { | |
| final LoggerOutput output = LoggerOutput(); | |
| @override | |
| final Ansi ansi = Ansi(Ansi.terminalSupportsAnsi); | |
| @override | |
| bool isVerbose; | |
| CapturingLogger({this.isVerbose = false}); | |
| @override | |
| void flush() { | |
| // deprecated. | |
| } | |
| @override | |
| Progress progress(String message) => CapturedProgress(output, message); | |
| @override | |
| void stderr(String message) { | |
| output.stderr.writeln(message); | |
| } | |
| @override | |
| void stdout(String message) { | |
| output.stdout.writeln(message); | |
| } | |
| @override | |
| void trace(String message) { | |
| output.trace.writeln(message); | |
| } | |
| @override | |
| void write(String message) { | |
| output.stdout.write(message); | |
| } | |
| @override | |
| void writeCharCode(int charCode) { | |
| output.stdout.writeCharCode(charCode); | |
| } | |
| } | |
| class FixResult<T extends Logger> { | |
| /// The value returned by [FixCommand.run]. | |
| final int? returnCode; | |
| /// The logger used in driving fixes. | |
| final T logger; | |
| FixResult(this.logger, this.returnCode); | |
| } | |
| class FixRunner<T extends Logger> extends CommandRunner<int> { | |
| final _supportedOptions = ['dry-run', 'apply']; | |
| T logger; | |
| @override | |
| final ArgParser argParser = globalDartdevOptionsParser(); | |
| FixRunner({required this.logger}) | |
| : super( | |
| 'fix_runner', | |
| 'A command-line utility for testing the `dart fix` command.', | |
| ) { | |
| addCommand(FixCommand()); | |
| _supportedOptions.forEach(argParser.addOption); | |
| } | |
| @override | |
| Future<int?> runCommand(ArgResults topLevelResults) async { | |
| var result = await super.runCommand(topLevelResults); | |
| return result; | |
| } | |
| Future<FixResult<T>> runFix(List<String> args) async { | |
| var argResults = argParser.parse(['fix', ...args]); | |
| var result = await withLogger(logger, () => runCommand(argResults)); | |
| return FixResult(logger, result); | |
| } | |
| } | |
| class LoggerOutput { | |
| /// Messages reported to progress. | |
| final StringBuffer progress = StringBuffer(); | |
| /// Messages reported to stdout. | |
| final StringBuffer stdout = StringBuffer(); | |
| /// Messages reported to stderr. | |
| final StringBuffer stderr = StringBuffer(); | |
| /// Messages reported to trace. | |
| final StringBuffer trace = StringBuffer(); | |
| } |