diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md index 9b6bbb1f71..098e57a8c6 100644 --- a/script/tool/CHANGELOG.md +++ b/script/tool/CHANGELOG.md @@ -1,6 +1,8 @@ -## NEXT +## 0.7.0 - `native-test` now supports `--linux` for unit tests. +- Formatting now skips Dart files that contain a line that exactly + matches the string `// This file is hand-formatted.`. ## 0.6.0+1 diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index d09a94b1ae..f24a99436c 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -206,7 +206,27 @@ class FormatCommand extends PluginCommand { final String fromPath = relativeTo.path; + // Dart files are allowed to have a pragma to disable auto-formatting. This + // was added because Hixie hurts when dealing with what dartfmt does to + // artisanally-formatted Dart, while Stuart gets really frustrated when + // dealing with PRs from newer contributors who don't know how to make Dart + // readable. After much discussion, it was decided that files in the plugins + // and packages repos that really benefit from hand-formatting (e.g. files + // with large blobs of hex literals) could be opted-out of the requirement + // that they be autoformatted, so long as the code's owner was willing to + // bear the cost of this during code reviews. + // In the event that code ownership moves to someone who does not hold the + // same views as the original owner, the pragma can be removed and the file + // auto-formatted. + const String handFormattedExtension = '.dart'; + const String handFormattedPragma = '// This file is hand-formatted.'; + return files + .where((File file) { + // See comment above near [handFormattedPragma]. + return path.extension(file.path) != handFormattedExtension || + !file.readAsLinesSync().contains(handFormattedPragma); + }) .map((File file) => path.relative(file.path, from: fromPath)) .where((String path) => // Ignore files in build/ directories (e.g., headers of frameworks) diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index adf62ca35a..2569e0ede8 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_plugin_tools description: Productivity utils for flutter/plugins and flutter/packages repository: https://github.com/flutter/plugins/tree/master/script/tool -version: 0.6.0+1 +version: 0.7.0 dependencies: args: ^2.1.0 diff --git a/script/tool/test/format_command_test.dart b/script/tool/test/format_command_test.dart index e2bf1e3e6e..d278bb2940 100644 --- a/script/tool/test/format_command_test.dart +++ b/script/tool/test/format_command_test.dart @@ -8,6 +8,7 @@ import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_plugin_tools/src/common/core.dart'; +import 'package:flutter_plugin_tools/src/common/file_utils.dart'; import 'package:flutter_plugin_tools/src/format_command.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; @@ -106,6 +107,42 @@ void main() { ])); }); + test('does not format .dart files with pragma', () async { + const List formattedFiles = [ + 'lib/a.dart', + 'lib/src/b.dart', + 'lib/src/c.dart', + ]; + const String unformattedFile = 'lib/src/d.dart'; + final Directory pluginDir = createFakePlugin( + 'a_plugin', + packagesDir, + extraFiles: [ + ...formattedFiles, + unformattedFile, + ], + ); + + final p.Context posixContext = p.posix; + childFileWithSubcomponents(pluginDir, posixContext.split(unformattedFile)) + .writeAsStringSync( + '// copyright bla bla\n// This file is hand-formatted.\ncode...'); + + await runCapturingPrint(runner, ['format']); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + getFlutterCommand(mockPlatform), + [ + 'format', + ..._getPackagesDirRelativePaths(pluginDir, formattedFiles) + ], + packagesDir.path), + ])); + }); + test('fails if flutter format fails', () async { const List files = [ 'lib/a.dart',