mirror of
https://github.com/flutter/packages.git
synced 2025-06-08 04:18:49 +08:00
148 lines
5.1 KiB
Dart
148 lines
5.1 KiB
Dart
// 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;
|
|
}
|
|
}
|