@@ -11,7 +11,8 @@ import 'package:meta/meta.dart';
1111
1212import 'common/core.dart' ;
1313import 'common/output_utils.dart' ;
14- import 'common/package_command.dart' ;
14+ import 'common/package_looping_command.dart' ;
15+ import 'common/repository_package.dart' ;
1516
1617/// In theory this should be 8191, but in practice that was still resulting in
1718/// "The input line is too long" errors. This was chosen as a value that worked
@@ -40,7 +41,7 @@ final Uri _kotlinFormatterUrl = Uri.https('maven.org',
4041 '/maven2/com/facebook/ktfmt/0.46/ktfmt-0.46-jar-with-dependencies.jar' );
4142
4243/// A command to format all package code.
43- class FormatCommand extends PackageCommand {
44+ class FormatCommand extends PackageLoopingCommand {
4445 /// Creates an instance of the format command.
4546 FormatCommand (
4647 super .packagesDir, {
@@ -85,18 +86,19 @@ class FormatCommand extends PackageCommand {
8586 'to be in your path.' ;
8687
8788 @override
88- Future <void > run () async {
89+ Future <void > initializeRun () async {
8990 final String javaFormatterPath = await _getJavaFormatterPath ();
9091 final String kotlinFormatterPath = await _getKotlinFormatterPath ();
9192
92- // This class is not based on PackageLoopingCommand because running the
93- // formatters separately for each package is an order of magnitude slower,
94- // due to the startup overhead of the formatters.
93+ // All but Dart is formatted here rather than in runForPackage because
94+ // running the formatters separately for each package is an order of
95+ // magnitude slower, due to the startup overhead of the formatters.
96+ //
97+ // Dart has to be run per-package because the formatter can have different
98+ // behavior based on the package's SDK, which can't be determined if the
99+ // formatter isn't running in the context of the package.
95100 final Iterable <String > files =
96101 await _getFilteredFilePaths (getFiles (), relativeTo: packagesDir);
97- if (getBoolArg (_dartArg)) {
98- await _formatDart (files);
99- }
100102 if (getBoolArg (_javaArg)) {
101103 await _formatJava (files, javaFormatterPath);
102104 }
@@ -109,7 +111,28 @@ class FormatCommand extends PackageCommand {
109111 if (getBoolArg (_swiftArg)) {
110112 await _formatAndLintSwift (files);
111113 }
114+ }
115+
116+ @override
117+ Future <PackageResult > runForPackage (RepositoryPackage package) async {
118+ final Iterable <String > files = await _getFilteredFilePaths (
119+ getFilesForPackage (package),
120+ relativeTo: package.directory,
121+ );
122+ if (getBoolArg (_dartArg)) {
123+ await _formatDart (files, workingDir: package.directory);
124+ }
125+ // Success or failure is determined overall in completeRun, since most code
126+ // isn't being validated per-package, so just always return success at the
127+ // package level.
128+ // TODO(stuartmorgan): Consider doing _didModifyAnything checks per-package
129+ // instead, since the other languages are already formatted by the time
130+ // this code is being run.
131+ return PackageResult .success ();
132+ }
112133
134+ @override
135+ Future <void > completeRun () async {
113136 if (getBoolArg (_failonChangeArg)) {
114137 final bool modified = await _didModifyAnything ();
115138 if (modified) {
@@ -291,13 +314,16 @@ class FormatCommand extends PackageCommand {
291314 }
292315 }
293316
294- Future <void > _formatDart (Iterable <String > files) async {
317+ Future <void > _formatDart (
318+ Iterable <String > files, {
319+ Directory ? workingDir,
320+ }) async {
295321 final Iterable <String > dartFiles =
296322 _getPathsWithExtensions (files, < String > {'.dart' });
297323 if (dartFiles.isNotEmpty) {
298324 print ('Formatting .dart files...' );
299- final int exitCode =
300- await _runBatched ( 'dart' , < String > [ 'format' ], files : dartFiles );
325+ final int exitCode = await _runBatched ( 'dart' , < String > [ 'format' ],
326+ files : dartFiles, workingDir : workingDir );
301327 if (exitCode != 0 ) {
302328 printError ('Failed to format Dart files: exit code $exitCode .' );
303329 throw ToolExit (_exitFlutterFormatFailed);
@@ -440,11 +466,8 @@ class FormatCommand extends PackageCommand {
440466 ///
441467 /// Returns the exit code of the first failure, which stops the run, or 0
442468 /// on success.
443- Future <int > _runBatched (
444- String command,
445- List <String > arguments, {
446- required Iterable <String > files,
447- }) async {
469+ Future <int > _runBatched (String command, List <String > arguments,
470+ {required Iterable <String > files, Directory ? workingDir}) async {
448471 final int commandLineMax =
449472 platform.isWindows ? windowsCommandLineMax : nonWindowsCommandLineMax;
450473
@@ -462,7 +485,7 @@ class FormatCommand extends PackageCommand {
462485 batch.sort (); // For ease of testing.
463486 final int exitCode = await processRunner.runAndStream (
464487 command, < String > [...arguments, ...batch],
465- workingDir: packagesDir);
488+ workingDir: workingDir ?? packagesDir);
466489 if (exitCode != 0 ) {
467490 return exitCode;
468491 }
0 commit comments