mirror of
https://github.com/flutter/packages.git
synced 2025-08-14 18:12:30 +08:00
Move plugin tools code (#3544)
This commit is contained in:
147
script/tool/lib/src/format_command.dart
Normal file
147
script/tool/lib/src/format_command.dart
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright 2017 The Chromium Authors. 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:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:quiver/iterables.dart';
|
||||
|
||||
import 'common.dart';
|
||||
|
||||
const String _googleFormatterUrl =
|
||||
'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar';
|
||||
|
||||
class FormatCommand extends PluginCommand {
|
||||
FormatCommand(
|
||||
Directory packagesDir,
|
||||
FileSystem fileSystem, {
|
||||
ProcessRunner processRunner = const ProcessRunner(),
|
||||
}) : super(packagesDir, fileSystem, processRunner: processRunner) {
|
||||
argParser.addFlag('travis', hide: true);
|
||||
argParser.addOption('clang-format',
|
||||
defaultsTo: 'clang-format',
|
||||
help: 'Path to executable of clang-format v5.');
|
||||
}
|
||||
|
||||
@override
|
||||
final String name = 'format';
|
||||
|
||||
@override
|
||||
final String description =
|
||||
'Formats the code of all packages (Java, Objective-C, C++, and Dart).\n\n'
|
||||
'This command requires "git", "flutter" and "clang-format" v5 to be in '
|
||||
'your path.';
|
||||
|
||||
@override
|
||||
Future<Null> run() async {
|
||||
checkSharding();
|
||||
final String googleFormatterPath = await _getGoogleFormatterPath();
|
||||
|
||||
await _formatDart();
|
||||
await _formatJava(googleFormatterPath);
|
||||
await _formatCppAndObjectiveC();
|
||||
|
||||
if (argResults['travis']) {
|
||||
final bool modified = await _didModifyAnything();
|
||||
if (modified) {
|
||||
throw ToolExit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _didModifyAnything() async {
|
||||
final io.ProcessResult modifiedFiles = await processRunner
|
||||
.runAndExitOnError('git', <String>['ls-files', '--modified'],
|
||||
workingDir: packagesDir);
|
||||
|
||||
print('\n\n');
|
||||
|
||||
if (modifiedFiles.stdout.isEmpty) {
|
||||
print('All files formatted correctly.');
|
||||
return false;
|
||||
}
|
||||
|
||||
print('These files are not formatted correctly (see diff below):');
|
||||
LineSplitter.split(modifiedFiles.stdout)
|
||||
.map((String line) => ' $line')
|
||||
.forEach(print);
|
||||
|
||||
print('\nTo fix run "pub global activate flutter_plugin_tools && '
|
||||
'pub global run flutter_plugin_tools format" or copy-paste '
|
||||
'this command into your terminal:');
|
||||
|
||||
print('patch -p1 <<DONE');
|
||||
final io.ProcessResult diff = await processRunner
|
||||
.runAndExitOnError('git', <String>['diff'], workingDir: packagesDir);
|
||||
print(diff.stdout);
|
||||
print('DONE');
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<Null> _formatCppAndObjectiveC() async {
|
||||
print('Formatting all .cc, .cpp, .mm, .m, and .h files...');
|
||||
final Iterable<String> allFiles = <String>[]
|
||||
..addAll(await _getFilesWithExtension('.h'))
|
||||
..addAll(await _getFilesWithExtension('.m'))
|
||||
..addAll(await _getFilesWithExtension('.mm'))
|
||||
..addAll(await _getFilesWithExtension('.cc'))
|
||||
..addAll(await _getFilesWithExtension('.cpp'));
|
||||
// Split this into multiple invocations to avoid a
|
||||
// 'ProcessException: Argument list too long'.
|
||||
final Iterable<List<String>> batches = partition(allFiles, 100);
|
||||
for (List<String> batch in batches) {
|
||||
await processRunner.runAndStream(argResults['clang-format'],
|
||||
<String>['-i', '--style=Google']..addAll(batch),
|
||||
workingDir: packagesDir, exitOnError: true);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> _formatJava(String googleFormatterPath) async {
|
||||
print('Formatting all .java files...');
|
||||
final Iterable<String> javaFiles = await _getFilesWithExtension('.java');
|
||||
await processRunner.runAndStream('java',
|
||||
<String>['-jar', googleFormatterPath, '--replace']..addAll(javaFiles),
|
||||
workingDir: packagesDir, exitOnError: true);
|
||||
}
|
||||
|
||||
Future<Null> _formatDart() async {
|
||||
// This actually should be fine for non-Flutter Dart projects, no need to
|
||||
// specifically shell out to dartfmt -w in that case.
|
||||
print('Formatting all .dart files...');
|
||||
final Iterable<String> dartFiles = await _getFilesWithExtension('.dart');
|
||||
if (dartFiles.isEmpty) {
|
||||
print(
|
||||
'No .dart files to format. If you set the `--exclude` flag, most likey they were skipped');
|
||||
} else {
|
||||
await processRunner.runAndStream(
|
||||
'flutter', <String>['format']..addAll(dartFiles),
|
||||
workingDir: packagesDir, exitOnError: true);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<String>> _getFilesWithExtension(String extension) async =>
|
||||
getFiles()
|
||||
.where((File file) => p.extension(file.path) == extension)
|
||||
.map((File file) => file.path)
|
||||
.toList();
|
||||
|
||||
Future<String> _getGoogleFormatterPath() async {
|
||||
final String javaFormatterPath = p.join(
|
||||
p.dirname(p.fromUri(io.Platform.script)),
|
||||
'google-java-format-1.3-all-deps.jar');
|
||||
final File javaFormatterFile = fileSystem.file(javaFormatterPath);
|
||||
|
||||
if (!javaFormatterFile.existsSync()) {
|
||||
print('Downloading Google Java Format...');
|
||||
final http.Response response = await http.get(_googleFormatterUrl);
|
||||
javaFormatterFile.writeAsBytesSync(response.bodyBytes);
|
||||
}
|
||||
|
||||
return javaFormatterPath;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user