未验证 提交 c6542d74 编写于 作者: G Greg Spencer 提交者: GitHub

Convert format and lint scripts to null safety. (#25078)

上级 e3f5ff7c
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
// TODO(gspencergoog): Support clang formatting on Windows. // TODO(gspencergoog): Support clang formatting on Windows.
// TODO(gspencergoog): Support Java formatting on Windows. // TODO(gspencergoog): Support Java formatting on Windows.
// TODO(gspencergoog): Convert to null safety.
import 'dart:io'; import 'dart:io';
import 'package:args/args.dart'; import 'package:args/args.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:isolate/isolate.dart'; import 'package:isolate/isolate.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
...@@ -23,7 +23,7 @@ class FormattingException implements Exception { ...@@ -23,7 +23,7 @@ class FormattingException implements Exception {
FormattingException(this.message, [this.result]); FormattingException(this.message, [this.result]);
final String message; final String message;
final ProcessResult /*?*/ result; final ProcessResult? result;
int get exitCode => result?.exitCode ?? -1; int get exitCode => result?.exitCode ?? -1;
...@@ -31,7 +31,7 @@ class FormattingException implements Exception { ...@@ -31,7 +31,7 @@ class FormattingException implements Exception {
String toString() { String toString() {
final StringBuffer output = StringBuffer(runtimeType.toString()); final StringBuffer output = StringBuffer(runtimeType.toString());
output.write(': $message'); output.write(': $message');
final String stderr = result?.stderr as String ?? ''; final String stderr = result?.stderr! as String;
if (stderr.isNotEmpty) { if (stderr.isNotEmpty) {
output.write(':\n$stderr'); output.write(':\n$stderr');
} }
...@@ -62,9 +62,9 @@ FormatCheck nameToFormatCheck(String name) { ...@@ -62,9 +62,9 @@ FormatCheck nameToFormatCheck(String name) {
return FormatCheck.whitespace; return FormatCheck.whitespace;
case 'gn': case 'gn':
return FormatCheck.gn; return FormatCheck.gn;
default:
throw FormattingException('Unknown FormatCheck type $name');
} }
assert(false, 'Unknown FormatCheck type $name');
return null;
} }
String formatCheckToName(FormatCheck check) { String formatCheckToName(FormatCheck check) {
...@@ -78,8 +78,6 @@ String formatCheckToName(FormatCheck check) { ...@@ -78,8 +78,6 @@ String formatCheckToName(FormatCheck check) {
case FormatCheck.gn: case FormatCheck.gn:
return 'GN'; return 'GN';
} }
assert(false, 'Unhandled FormatCheck type $check');
return null;
} }
List<String> formatCheckNames() { List<String> formatCheckNames() {
...@@ -106,33 +104,33 @@ Future<String> _runGit( ...@@ -106,33 +104,33 @@ Future<String> _runGit(
return result.stdout; return result.stdout;
} }
typedef MessageCallback = Function(String message, {MessageType type}); typedef MessageCallback = Function(String? message, {MessageType type});
/// Base class for format checkers. /// Base class for format checkers.
/// ///
/// Provides services that all format checkers need. /// Provides services that all format checkers need.
abstract class FormatChecker { abstract class FormatChecker {
FormatChecker({ FormatChecker({
ProcessManager /*?*/ processManager, ProcessManager processManager = const LocalProcessManager(),
@required this.baseGitRef, required this.baseGitRef,
@required this.repoDir, required this.repoDir,
@required this.srcDir, required this.srcDir,
this.allFiles = false, this.allFiles = false,
this.messageCallback, this.messageCallback,
}) : _processRunner = ProcessRunner( }) : _processRunner = ProcessRunner(
defaultWorkingDirectory: repoDir, defaultWorkingDirectory: repoDir,
processManager: processManager ?? const LocalProcessManager(), processManager: processManager,
); );
/// Factory method that creates subclass format checkers based on the type of check. /// Factory method that creates subclass format checkers based on the type of check.
factory FormatChecker.ofType( factory FormatChecker.ofType(
FormatCheck check, { FormatCheck check, {
ProcessManager /*?*/ processManager, ProcessManager processManager = const LocalProcessManager(),
@required String baseGitRef, required String baseGitRef,
@required Directory repoDir, required Directory repoDir,
@required Directory srcDir, required Directory srcDir,
bool allFiles = false, bool allFiles = false,
MessageCallback messageCallback, MessageCallback? messageCallback,
}) { }) {
switch (check) { switch (check) {
case FormatCheck.clang: case FormatCheck.clang:
...@@ -144,7 +142,6 @@ abstract class FormatChecker { ...@@ -144,7 +142,6 @@ abstract class FormatChecker {
allFiles: allFiles, allFiles: allFiles,
messageCallback: messageCallback, messageCallback: messageCallback,
); );
break;
case FormatCheck.java: case FormatCheck.java:
return JavaFormatChecker( return JavaFormatChecker(
processManager: processManager, processManager: processManager,
...@@ -154,7 +151,6 @@ abstract class FormatChecker { ...@@ -154,7 +151,6 @@ abstract class FormatChecker {
allFiles: allFiles, allFiles: allFiles,
messageCallback: messageCallback, messageCallback: messageCallback,
); );
break;
case FormatCheck.whitespace: case FormatCheck.whitespace:
return WhitespaceFormatChecker( return WhitespaceFormatChecker(
processManager: processManager, processManager: processManager,
...@@ -164,7 +160,6 @@ abstract class FormatChecker { ...@@ -164,7 +160,6 @@ abstract class FormatChecker {
allFiles: allFiles, allFiles: allFiles,
messageCallback: messageCallback, messageCallback: messageCallback,
); );
break;
case FormatCheck.gn: case FormatCheck.gn:
return GnFormatChecker( return GnFormatChecker(
processManager: processManager, processManager: processManager,
...@@ -174,17 +169,14 @@ abstract class FormatChecker { ...@@ -174,17 +169,14 @@ abstract class FormatChecker {
allFiles: allFiles, allFiles: allFiles,
messageCallback: messageCallback, messageCallback: messageCallback,
); );
break;
} }
assert(false, 'Unhandled FormatCheck type $check');
return null;
} }
final ProcessRunner _processRunner; final ProcessRunner _processRunner;
final Directory srcDir; final Directory srcDir;
final Directory repoDir; final Directory repoDir;
final bool allFiles; final bool allFiles;
MessageCallback /*?*/ messageCallback; MessageCallback? messageCallback;
final String baseGitRef; final String baseGitRef;
/// Override to provide format checking for a specific type. /// Override to provide format checking for a specific type.
...@@ -194,7 +186,7 @@ abstract class FormatChecker { ...@@ -194,7 +186,7 @@ abstract class FormatChecker {
Future<bool> fixFormatting(); Future<bool> fixFormatting();
@protected @protected
void message(String string) => messageCallback?.call(string, type: MessageType.message); void message(String? string) => messageCallback?.call(string, type: MessageType.message);
@protected @protected
void error(String string) => messageCallback?.call(string, type: MessageType.error); void error(String string) => messageCallback?.call(string, type: MessageType.error);
...@@ -208,8 +200,10 @@ abstract class FormatChecker { ...@@ -208,8 +200,10 @@ abstract class FormatChecker {
/// Uses to convert the stdout of a previous command into an input stream for /// Uses to convert the stdout of a previous command into an input stream for
/// the next command. /// the next command.
@protected @protected
Stream<List<int>> codeUnitsAsStream(List<int> input) async* { Stream<List<int>> codeUnitsAsStream(List<int>? input) async* {
yield input; if (input != null) {
yield input;
}
} }
@protected @protected
...@@ -299,12 +293,12 @@ abstract class FormatChecker { ...@@ -299,12 +293,12 @@ abstract class FormatChecker {
/// Checks and formats C++/ObjC files using clang-format. /// Checks and formats C++/ObjC files using clang-format.
class ClangFormatChecker extends FormatChecker { class ClangFormatChecker extends FormatChecker {
ClangFormatChecker({ ClangFormatChecker({
ProcessManager /*?*/ processManager, ProcessManager processManager = const LocalProcessManager(),
@required String baseGitRef, required String baseGitRef,
@required Directory repoDir, required Directory repoDir,
@required Directory srcDir, required Directory srcDir,
bool allFiles = false, bool allFiles = false,
MessageCallback messageCallback, MessageCallback? messageCallback,
}) : super( }) : super(
processManager: processManager, processManager: processManager,
baseGitRef: baseGitRef, baseGitRef: baseGitRef,
...@@ -334,7 +328,7 @@ class ClangFormatChecker extends FormatChecker { ...@@ -334,7 +328,7 @@ class ClangFormatChecker extends FormatChecker {
); );
} }
/*late*/ File clangFormat; late final File clangFormat;
@override @override
Future<bool> checkFormatting() async { Future<bool> checkFormatting() async {
...@@ -392,7 +386,7 @@ class ClangFormatChecker extends FormatChecker { ...@@ -392,7 +386,7 @@ class ClangFormatChecker extends FormatChecker {
final Stream<WorkerJob> completedClangFormats = clangPool.startWorkers(clangJobs); final Stream<WorkerJob> completedClangFormats = clangPool.startWorkers(clangJobs);
final List<WorkerJob> diffJobs = <WorkerJob>[]; final List<WorkerJob> diffJobs = <WorkerJob>[];
await for (final WorkerJob completedJob in completedClangFormats) { await for (final WorkerJob completedJob in completedClangFormats) {
if (completedJob.result != null && completedJob.result.exitCode == 0) { if (completedJob.result.exitCode == 0) {
diffJobs.add( diffJobs.add(
WorkerJob(<String>['diff', '-u', completedJob.command.last, '-'], WorkerJob(<String>['diff', '-u', completedJob.command.last, '-'],
stdinRaw: codeUnitsAsStream(completedJob.result.stdoutRaw), failOk: true), stdinRaw: codeUnitsAsStream(completedJob.result.stdoutRaw), failOk: true),
...@@ -432,12 +426,12 @@ class ClangFormatChecker extends FormatChecker { ...@@ -432,12 +426,12 @@ class ClangFormatChecker extends FormatChecker {
/// Checks the format of Java files uing the Google Java format checker. /// Checks the format of Java files uing the Google Java format checker.
class JavaFormatChecker extends FormatChecker { class JavaFormatChecker extends FormatChecker {
JavaFormatChecker({ JavaFormatChecker({
ProcessManager /*?*/ processManager, ProcessManager processManager = const LocalProcessManager(),
@required String baseGitRef, required String baseGitRef,
@required Directory repoDir, required Directory repoDir,
@required Directory srcDir, required Directory srcDir,
bool allFiles = false, bool allFiles = false,
MessageCallback messageCallback, MessageCallback? messageCallback,
}) : super( }) : super(
processManager: processManager, processManager: processManager,
baseGitRef: baseGitRef, baseGitRef: baseGitRef,
...@@ -459,7 +453,7 @@ class JavaFormatChecker extends FormatChecker { ...@@ -459,7 +453,7 @@ class JavaFormatChecker extends FormatChecker {
); );
} }
/*late*/ File googleJavaFormatJar; late final File googleJavaFormatJar;
Future<String> _getGoogleJavaFormatVersion() async { Future<String> _getGoogleJavaFormatVersion() async {
final ProcessRunnerResult result = await _processRunner final ProcessRunnerResult result = await _processRunner
...@@ -532,7 +526,7 @@ class JavaFormatChecker extends FormatChecker { ...@@ -532,7 +526,7 @@ class JavaFormatChecker extends FormatChecker {
final Stream<WorkerJob> completedClangFormats = formatPool.startWorkers(formatJobs); final Stream<WorkerJob> completedClangFormats = formatPool.startWorkers(formatJobs);
final List<WorkerJob> diffJobs = <WorkerJob>[]; final List<WorkerJob> diffJobs = <WorkerJob>[];
await for (final WorkerJob completedJob in completedClangFormats) { await for (final WorkerJob completedJob in completedClangFormats) {
if (completedJob.result != null && completedJob.result.exitCode == 0) { if (completedJob.result.exitCode == 0) {
diffJobs.add( diffJobs.add(
WorkerJob( WorkerJob(
<String>['diff', '-u', completedJob.command.last, '-'], <String>['diff', '-u', completedJob.command.last, '-'],
...@@ -575,12 +569,12 @@ class JavaFormatChecker extends FormatChecker { ...@@ -575,12 +569,12 @@ class JavaFormatChecker extends FormatChecker {
/// Checks the format of any BUILD.gn files using the "gn format" command. /// Checks the format of any BUILD.gn files using the "gn format" command.
class GnFormatChecker extends FormatChecker { class GnFormatChecker extends FormatChecker {
GnFormatChecker({ GnFormatChecker({
ProcessManager /*?*/ processManager, ProcessManager processManager = const LocalProcessManager(),
@required String baseGitRef, required String baseGitRef,
@required Directory repoDir, required Directory repoDir,
@required Directory srcDir, required Directory srcDir,
bool allFiles = false, bool allFiles = false,
MessageCallback messageCallback, MessageCallback? messageCallback,
}) : super( }) : super(
processManager: processManager, processManager: processManager,
baseGitRef: baseGitRef, baseGitRef: baseGitRef,
...@@ -599,7 +593,7 @@ class GnFormatChecker extends FormatChecker { ...@@ -599,7 +593,7 @@ class GnFormatChecker extends FormatChecker {
); );
} }
/*late*/ File gnBinary; late final File gnBinary;
@override @override
Future<bool> checkFormatting() async { Future<bool> checkFormatting() async {
...@@ -615,7 +609,7 @@ class GnFormatChecker extends FormatChecker { ...@@ -615,7 +609,7 @@ class GnFormatChecker extends FormatChecker {
return true; return true;
} }
Future<int> _runGnCheck({@required bool fixing}) async { Future<int> _runGnCheck({required bool fixing}) async {
final List<String> filesToCheck = await getFileList(<String>['*.gn', '*.gni']); final List<String> filesToCheck = await getFileList(<String>['*.gn', '*.gni']);
final List<String> cmd = <String>[ final List<String> cmd = <String>[
...@@ -665,7 +659,8 @@ class GnFormatChecker extends FormatChecker { ...@@ -665,7 +659,8 @@ class GnFormatChecker extends FormatChecker {
@immutable @immutable
class _GrepResult { class _GrepResult {
const _GrepResult(this.file, this.hits, this.lineNumbers); const _GrepResult(this.file, [this.hits = const <String>[], this.lineNumbers = const <int>[]]);
bool get isEmpty => hits.isEmpty && lineNumbers.isEmpty;
final File file; final File file;
final List<String> hits; final List<String> hits;
final List<int> lineNumbers; final List<int> lineNumbers;
...@@ -674,12 +669,12 @@ class _GrepResult { ...@@ -674,12 +669,12 @@ class _GrepResult {
/// Checks for trailing whitspace in Dart files. /// Checks for trailing whitspace in Dart files.
class WhitespaceFormatChecker extends FormatChecker { class WhitespaceFormatChecker extends FormatChecker {
WhitespaceFormatChecker({ WhitespaceFormatChecker({
ProcessManager /*?*/ processManager, ProcessManager processManager = const LocalProcessManager(),
@required String baseGitRef, required String baseGitRef,
@required Directory repoDir, required Directory repoDir,
@required Directory srcDir, required Directory srcDir,
bool allFiles = false, bool allFiles = false,
MessageCallback messageCallback, MessageCallback? messageCallback,
}) : super( }) : super(
processManager: processManager, processManager: processManager,
baseGitRef: baseGitRef, baseGitRef: baseGitRef,
...@@ -723,7 +718,7 @@ class WhitespaceFormatChecker extends FormatChecker { ...@@ -723,7 +718,7 @@ class WhitespaceFormatChecker extends FormatChecker {
lineNumber++; lineNumber++;
} }
if (hits.isEmpty) { if (hits.isEmpty) {
return null; return _GrepResult(file);
} }
return _GrepResult(file, hits, lineNumbers); return _GrepResult(file, hits, lineNumbers);
} }
...@@ -776,7 +771,7 @@ class WhitespaceFormatChecker extends FormatChecker { ...@@ -776,7 +771,7 @@ class WhitespaceFormatChecker extends FormatChecker {
), ),
), ),
)) { )) {
if (result == null) { if (result.isEmpty) {
completed++; completed++;
} else { } else {
failed++; failed++;
...@@ -804,7 +799,7 @@ class WhitespaceFormatChecker extends FormatChecker { ...@@ -804,7 +799,7 @@ class WhitespaceFormatChecker extends FormatChecker {
Future<String> _getDiffBaseRevision(ProcessManager processManager, Directory repoDir) async { Future<String> _getDiffBaseRevision(ProcessManager processManager, Directory repoDir) async {
final ProcessRunner processRunner = ProcessRunner( final ProcessRunner processRunner = ProcessRunner(
defaultWorkingDirectory: repoDir, defaultWorkingDirectory: repoDir,
processManager: processManager ?? const LocalProcessManager(), processManager: processManager,
); );
String upstream = 'upstream'; String upstream = 'upstream';
final String upstreamUrl = await _runGit( final String upstreamUrl = await _runGit(
...@@ -861,7 +856,7 @@ Future<int> main(List<String> arguments) async { ...@@ -861,7 +856,7 @@ Future<int> main(List<String> arguments) async {
'On Windows, only whitespace and gn checks are currently supported.'); 'On Windows, only whitespace and gn checks are currently supported.');
parser.addFlag('verbose', help: 'Print verbose output.', defaultsTo: verbose); parser.addFlag('verbose', help: 'Print verbose output.', defaultsTo: verbose);
ArgResults options; late final ArgResults options;
try { try {
options = parser.parse(arguments); options = parser.parse(arguments);
} on FormatException catch (e) { } on FormatException catch (e) {
...@@ -883,7 +878,8 @@ Future<int> main(List<String> arguments) async { ...@@ -883,7 +878,8 @@ Future<int> main(List<String> arguments) async {
stderr.writeln('Src: $srcDir'); stderr.writeln('Src: $srcDir');
} }
void message(String message, {MessageType type = MessageType.message}) { void message(String? message, {MessageType type = MessageType.message}) {
message ??= '';
switch (type) { switch (type) {
case MessageType.message: case MessageType.message:
stderr.writeln(message); stderr.writeln(message);
......
...@@ -141,7 +141,7 @@ Future<LintAction> getLintAction(File file) async { ...@@ -141,7 +141,7 @@ Future<LintAction> getLintAction(File file) async {
.transform(utf8.decoder) .transform(utf8.decoder)
.transform(const LineSplitter()); .transform(const LineSplitter());
await for (String line in lines) { await for (String line in lines) {
final RegExpMatch match = exp.firstMatch(line); final RegExpMatch? match = exp.firstMatch(line);
if (match != null) { if (match != null) {
return match.group(1) != null return match.group(1) != null
? LintAction.skipNoLint ? LintAction.skipNoLint
...@@ -158,7 +158,7 @@ Future<LintAction> getLintAction(File file) async { ...@@ -158,7 +158,7 @@ Future<LintAction> getLintAction(File file) async {
WorkerJob createLintJob(Command command, String checks, String tidyPath) { WorkerJob createLintJob(Command command, String checks, String tidyPath) {
final String tidyArgs = calcTidyArgs(command); final String tidyArgs = calcTidyArgs(command);
final List<String> args = <String>[command.file.path, checks, '--']; final List<String> args = <String>[command.file.path, checks, '--'];
args.addAll(tidyArgs?.split(' ') ?? <String>[]); args.addAll(tidyArgs.split(' '));
return WorkerJob( return WorkerJob(
<String>[tidyPath, ...args], <String>[tidyPath, ...args],
workingDirectory: command.directory, workingDirectory: command.directory,
...@@ -286,10 +286,10 @@ void main(List<String> arguments) async { ...@@ -286,10 +286,10 @@ void main(List<String> arguments) async {
final ProcessPool pool = ProcessPool(); final ProcessPool pool = ProcessPool();
await for (final WorkerJob job in pool.startWorkers(jobs)) { await for (final WorkerJob job in pool.startWorkers(jobs)) {
if (job.result?.exitCode == 0) { if (job.result.exitCode == 0) {
continue; continue;
} }
if (job.result == null) { if (job.exception != null) {
print('\n❗ A clang-tidy job failed to run, aborting:\n${job.exception}'); print('\n❗ A clang-tidy job failed to run, aborting:\n${job.exception}');
exitCode = 1; exitCode = 1;
break; break;
......
...@@ -29,4 +29,5 @@ cd "%ci_dir%" ...@@ -29,4 +29,5 @@ cd "%ci_dir%"
REM Do not use the CALL command in the next line to execute Dart. CALL causes REM Do not use the CALL command in the next line to execute Dart. CALL causes
REM Windows to re-read the line from disk after the CALL command has finished REM Windows to re-read the line from disk after the CALL command has finished
REM regardless of the ampersand chain. REM regardless of the ampersand chain.
"%pub%" get & "%dart%" --disable-dart-dev bin\format.dart %* & exit /B !ERRORLEVEL! REM TODO(gspencergoog): Remove --no-sound-null-safety once isolate package is null-safe.
"%pub%" get & "%dart%" --no-sound-null-safety --disable-dart-dev bin\format.dart %* & exit /B !ERRORLEVEL!
...@@ -34,8 +34,10 @@ DART_SDK_DIR="${SRC_DIR}/third_party/dart/tools/sdks/dart-sdk" ...@@ -34,8 +34,10 @@ DART_SDK_DIR="${SRC_DIR}/third_party/dart/tools/sdks/dart-sdk"
DART="${DART_SDK_DIR}/bin/dart" DART="${DART_SDK_DIR}/bin/dart"
PUB="${DART_SDK_DIR}/bin/pub" PUB="${DART_SDK_DIR}/bin/pub"
# TODO(gspencergoog): Remove --no-sound-null-safety once isolate package is null-safe.
cd "$SCRIPT_DIR" cd "$SCRIPT_DIR"
"$PUB" get && "$DART" \ "$PUB" get && "$DART" \
--disable-dart-dev \ --disable-dart-dev \
--no-sound-null-safety \
bin/format.dart \ bin/format.dart \
"$@" "$@"
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
name: ci_scripts name: ci_scripts
dependencies: dependencies:
args: ^1.6.0 args: ^2.0.0
path: ^1.7.0 meta: ^1.3.0
path: ^1.8.0
isolate: ^2.0.3 isolate: ^2.0.3
process_runner: ^3.1.1 process_runner: ^4.0.0
environment: environment:
sdk: '>=2.8.0 <3.0.0' sdk: '>=2.12.0-0 <3.0.0'
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册