Enabling pre-push checks on Windows (flutter/engine#36123)
Re-submit the changes to enable windows pre-push checks. This patch changes how `ci/bin/format.dart` generate diffs from `diff` and `patch` commands to `git diff` and `git apply` in order to have a common method for these operations on all platforms. Windows installations don't have diff and patch commands available by default and many implementations which provide such commands work differently than the UN*X tools. Git however works consistently across all platforms. Additionally, this patch also changes the python executable in some of the pre-push components affected by this to `vpython3` to continue the effort started at flutter/flutter#108474 and I also removed the `--no-sound-null-safety` parameter in the ci/format.sh, ci/format.bat files NOTE: Since the original patch caused some issues, I suggest that this should be tested more carefully before it is merged. ### Issues fixed by this PR * flutter/flutter#108122 * flutter/flutter#107920 * flutter/flutter#86506 * flutter/flutter#106615 ### [flutter/tests] repo impact None. writing and running engine tests. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
@@ -6,9 +6,6 @@
|
||||
//
|
||||
// Run with --help for usage.
|
||||
|
||||
// TODO(gspencergoog): Support clang formatting on Windows.
|
||||
// TODO(gspencergoog): Support Java formatting on Windows.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
@@ -84,14 +81,9 @@ String formatCheckToName(FormatCheck check) {
|
||||
}
|
||||
|
||||
List<String> formatCheckNames() {
|
||||
List<FormatCheck> allowed;
|
||||
if (!Platform.isWindows) {
|
||||
allowed = FormatCheck.values;
|
||||
} else {
|
||||
allowed = <FormatCheck>[FormatCheck.gn, FormatCheck.whitespace];
|
||||
}
|
||||
return allowed
|
||||
.map<String>((FormatCheck check) => check.toString().replaceFirst('$FormatCheck.', ''))
|
||||
return FormatCheck.values
|
||||
.map<String>((FormatCheck check) =>
|
||||
check.toString().replaceFirst('$FormatCheck.', ''))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -226,7 +218,7 @@ abstract class FormatChecker {
|
||||
);
|
||||
final List<WorkerJob> jobs = patches.map<WorkerJob>((String patch) {
|
||||
return WorkerJob(
|
||||
<String>['patch', '-p0'],
|
||||
<String>['git', 'apply', '--ignore-space-change'],
|
||||
stdinRaw: codeUnitsAsStream(patch.codeUnits),
|
||||
);
|
||||
}).toList();
|
||||
@@ -318,6 +310,8 @@ class ClangFormatChecker extends FormatChecker {
|
||||
clangOs = 'linux-x64';
|
||||
} else if (Platform.isMacOS) {
|
||||
clangOs = 'mac-x64';
|
||||
} else if (Platform.isWindows) {
|
||||
clangOs = 'windows-x64';
|
||||
} else {
|
||||
throw FormattingException(
|
||||
"Unknown operating system: don't know how to run clang-format here.");
|
||||
@@ -401,9 +395,23 @@ class ClangFormatChecker extends FormatChecker {
|
||||
await for (final WorkerJob completedJob in completedClangFormats) {
|
||||
if (completedJob.result.exitCode == 0) {
|
||||
diffJobs.add(
|
||||
WorkerJob(<String>['diff', '-u', completedJob.command.last, '-'],
|
||||
WorkerJob(<String>[
|
||||
'git',
|
||||
'diff',
|
||||
'--no-index',
|
||||
'--no-color',
|
||||
'--ignore-cr-at-eol',
|
||||
'--',
|
||||
completedJob.command.last,
|
||||
'-',
|
||||
],
|
||||
stdinRaw: codeUnitsAsStream(completedJob.result.stdoutRaw)),
|
||||
);
|
||||
} else {
|
||||
final String formatterCommand = completedJob.command.join(' ');
|
||||
error("Formatter command '$formatterCommand' failed with exit code "
|
||||
'${completedJob.result.exitCode}. Command output follows:\n\n'
|
||||
'${completedJob.result.output}');
|
||||
}
|
||||
}
|
||||
final ProcessPool diffPool = ProcessPool(
|
||||
@@ -425,9 +433,11 @@ class ClangFormatChecker extends FormatChecker {
|
||||
' which ${plural ? 'were' : 'was'} formatted incorrectly.');
|
||||
stdout.writeln('To fix, run:');
|
||||
stdout.writeln();
|
||||
stdout.writeln('patch -p0 <<DONE');
|
||||
stdout.writeln('git apply <<DONE');
|
||||
for (final WorkerJob job in failed) {
|
||||
stdout.write(job.result.stdout);
|
||||
stdout.write(job.result.stdout
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}')
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}'));
|
||||
}
|
||||
stdout.writeln('DONE');
|
||||
stdout.writeln();
|
||||
@@ -436,7 +446,9 @@ class ClangFormatChecker extends FormatChecker {
|
||||
message('Completed checking ${diffJobs.length} C++/ObjC/Shader files with no formatting problems.');
|
||||
}
|
||||
return failed.map<String>((WorkerJob job) {
|
||||
return job.result.stdout;
|
||||
return job.result.stdout
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}')
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}');
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
@@ -536,16 +548,30 @@ class JavaFormatChecker extends FormatChecker {
|
||||
processRunner: _processRunner,
|
||||
printReport: namedReport('Java format'),
|
||||
);
|
||||
final Stream<WorkerJob> completedClangFormats = formatPool.startWorkers(formatJobs);
|
||||
final Stream<WorkerJob> completedJavaFormats = formatPool.startWorkers(formatJobs);
|
||||
final List<WorkerJob> diffJobs = <WorkerJob>[];
|
||||
await for (final WorkerJob completedJob in completedClangFormats) {
|
||||
await for (final WorkerJob completedJob in completedJavaFormats) {
|
||||
if (completedJob.result.exitCode == 0) {
|
||||
diffJobs.add(
|
||||
WorkerJob(
|
||||
<String>['diff', '-u', completedJob.command.last, '-'],
|
||||
<String>[
|
||||
'git',
|
||||
'diff',
|
||||
'--no-index',
|
||||
'--no-color',
|
||||
'--ignore-cr-at-eol',
|
||||
'--',
|
||||
completedJob.command.last,
|
||||
'-',
|
||||
],
|
||||
stdinRaw: codeUnitsAsStream(completedJob.result.stdoutRaw),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final String formatterCommand = completedJob.command.join(' ');
|
||||
error("Formatter command '$formatterCommand' failed with exit code "
|
||||
'${completedJob.result.exitCode}. Command output follows:\n\n'
|
||||
'${completedJob.result.output}');
|
||||
}
|
||||
}
|
||||
final ProcessPool diffPool = ProcessPool(
|
||||
@@ -567,9 +593,11 @@ class JavaFormatChecker extends FormatChecker {
|
||||
' which ${plural ? 'were' : 'was'} formatted incorrectly.');
|
||||
stdout.writeln('To fix, run:');
|
||||
stdout.writeln();
|
||||
stdout.writeln('patch -p0 <<DONE');
|
||||
stdout.writeln('git apply <<DONE');
|
||||
for (final WorkerJob job in failed) {
|
||||
stdout.write(job.result.stdout);
|
||||
stdout.write(job.result.stdout
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}')
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}'));
|
||||
}
|
||||
stdout.writeln('DONE');
|
||||
stdout.writeln();
|
||||
@@ -578,7 +606,9 @@ class JavaFormatChecker extends FormatChecker {
|
||||
message('Completed checking ${diffJobs.length} Java files with no formatting problems.');
|
||||
}
|
||||
return failed.map<String>((WorkerJob job) {
|
||||
return job.result.stdout;
|
||||
return job.result.stdout
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}')
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}');
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
@@ -627,45 +657,90 @@ class GnFormatChecker extends FormatChecker {
|
||||
final List<String> cmd = <String>[
|
||||
gnBinary.path,
|
||||
'format',
|
||||
if (!fixing) '--dry-run',
|
||||
if (!fixing) '--stdin',
|
||||
];
|
||||
final List<WorkerJob> jobs = <WorkerJob>[];
|
||||
for (final String file in filesToCheck) {
|
||||
jobs.add(WorkerJob(<String>[...cmd, file]));
|
||||
if (fixing) {
|
||||
jobs.add(WorkerJob(
|
||||
<String>[...cmd, file],
|
||||
name: <String>[...cmd, file].join(' '),
|
||||
));
|
||||
} else {
|
||||
final WorkerJob job = WorkerJob(
|
||||
cmd,
|
||||
stdinRaw: codeUnitsAsStream(
|
||||
File(path.join(repoDir.absolute.path, file)).readAsBytesSync(),
|
||||
),
|
||||
name: <String>[...cmd, file].join(' '),
|
||||
);
|
||||
jobs.add(job);
|
||||
}
|
||||
}
|
||||
final ProcessPool gnPool = ProcessPool(
|
||||
processRunner: _processRunner,
|
||||
printReport: namedReport('gn format'),
|
||||
);
|
||||
final List<WorkerJob> completedJobs = await gnPool.runToCompletion(jobs);
|
||||
reportDone();
|
||||
final List<String> incorrect = <String>[];
|
||||
for (final WorkerJob job in completedJobs) {
|
||||
if (job.result.exitCode == 2) {
|
||||
incorrect.add(' ${job.command.last}');
|
||||
}
|
||||
if (job.result.exitCode == 1) {
|
||||
// GN has exit code 1 if it had some problem formatting/checking the
|
||||
// file.
|
||||
throw FormattingException(
|
||||
'Unable to format ${job.command.last}:\n${job.result.output}',
|
||||
final Stream<WorkerJob> completedJobs = gnPool.startWorkers(jobs);
|
||||
final List<WorkerJob> diffJobs = <WorkerJob>[];
|
||||
await for (final WorkerJob completedJob in completedJobs) {
|
||||
if (completedJob.result.exitCode == 0) {
|
||||
diffJobs.add(
|
||||
WorkerJob(
|
||||
<String>[
|
||||
'git',
|
||||
'diff',
|
||||
'--no-index',
|
||||
'--no-color',
|
||||
'--ignore-cr-at-eol',
|
||||
'--',
|
||||
completedJob.name.split(' ').last,
|
||||
'-'
|
||||
],
|
||||
stdinRaw: codeUnitsAsStream(completedJob.result.stdoutRaw),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final String formatterCommand = completedJob.command.join(' ');
|
||||
error("Formatter command '$formatterCommand' failed with exit code "
|
||||
'${completedJob.result.exitCode}. Command output follows:\n\n'
|
||||
'${completedJob.result.output}');
|
||||
}
|
||||
}
|
||||
if (incorrect.isNotEmpty) {
|
||||
final bool plural = incorrect.length > 1;
|
||||
final ProcessPool diffPool = ProcessPool(
|
||||
processRunner: _processRunner,
|
||||
printReport: namedReport('diff'),
|
||||
);
|
||||
final List<WorkerJob> completedDiffs =
|
||||
await diffPool.runToCompletion(diffJobs);
|
||||
final Iterable<WorkerJob> failed = completedDiffs.where((WorkerJob job) {
|
||||
return job.result.exitCode != 0;
|
||||
});
|
||||
reportDone();
|
||||
if (failed.isNotEmpty) {
|
||||
final bool plural = failed.length > 1;
|
||||
if (fixing) {
|
||||
message('Fixed ${incorrect.length} GN file${plural ? 's' : ''}'
|
||||
message('Fixed ${failed.length} GN file${plural ? 's' : ''}'
|
||||
' which ${plural ? 'were' : 'was'} formatted incorrectly.');
|
||||
} else {
|
||||
error('Found ${incorrect.length} GN file${plural ? 's' : ''}'
|
||||
' which ${plural ? 'were' : 'was'} formatted incorrectly:');
|
||||
incorrect.forEach(stderr.writeln);
|
||||
error('Found ${failed.length} GN file${plural ? 's' : ''}'
|
||||
' which ${plural ? 'were' : 'was'} formatted incorrectly.');
|
||||
stdout.writeln('To fix, run:');
|
||||
stdout.writeln();
|
||||
stdout.writeln('git apply <<DONE');
|
||||
for (final WorkerJob job in failed) {
|
||||
stdout.write(job.result.stdout
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}')
|
||||
.replaceFirst('b/-', 'b/${job.command[job.command.length - 2]}'));
|
||||
}
|
||||
stdout.writeln('DONE');
|
||||
stdout.writeln();
|
||||
}
|
||||
} else {
|
||||
message('All GN files formatted correctly.');
|
||||
message('Completed checking ${completedDiffs.length} GN files with no '
|
||||
'formatting problems.');
|
||||
}
|
||||
return incorrect.length;
|
||||
return failed.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,7 +759,7 @@ class PythonFormatChecker extends FormatChecker {
|
||||
yapfBin = File(path.join(
|
||||
repoDir.absolute.path,
|
||||
'tools',
|
||||
'yapf.sh',
|
||||
Platform.isWindows ? 'yapf.bat' : 'yapf.sh',
|
||||
));
|
||||
_yapfStyle = File(path.join(
|
||||
repoDir.absolute.path,
|
||||
@@ -937,8 +1012,7 @@ Future<int> main(List<String> arguments) async {
|
||||
allowed: formatCheckNames(),
|
||||
defaultsTo: formatCheckNames(),
|
||||
help: 'Specifies which checks will be performed. Defaults to all checks. '
|
||||
'May be specified more than once to perform multiple types of checks. '
|
||||
'On Windows, only whitespace and gn checks are currently supported.');
|
||||
'May be specified more than once to perform multiple types of checks. ');
|
||||
parser.addFlag('verbose', help: 'Print verbose output.', defaultsTo: verbose);
|
||||
|
||||
late final ArgResults options;
|
||||
|
||||
@@ -20,7 +20,16 @@ where /q git || ECHO Error: Unable to find git in your PATH. && EXIT /B 1
|
||||
|
||||
SET repo_dir=%SRC_DIR%\flutter
|
||||
SET ci_dir=%repo_dir%\ci
|
||||
SET dart_sdk_path=%SRC_DIR%\third_party\dart\tools\sdks\dart-sdk
|
||||
|
||||
REM Determine which platform we are on and use the right prebuilt Dart SDK
|
||||
IF "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
|
||||
SET dart_sdk_path=%SRC_DIR%\flutter\prebuilts\windows-x64\dart-sdk
|
||||
) ELSE IF "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
|
||||
SET dart_sdk_path=%SRC_DIR%\flutter\prebuilts\windows-arm64\dart-sdk
|
||||
) ELSE (
|
||||
ECHO "Windows x86 (32-bit) is not supported" && EXIT /B 1
|
||||
)
|
||||
|
||||
SET dart=%dart_sdk_path%\bin\dart.exe
|
||||
|
||||
cd "%ci_dir%"
|
||||
|
||||
@@ -23,15 +23,26 @@ dependencies:
|
||||
process_runner: any
|
||||
process: any
|
||||
|
||||
dev_dependencies:
|
||||
async_helper: any
|
||||
expect: any
|
||||
litetest: any
|
||||
|
||||
dependency_overrides:
|
||||
args:
|
||||
path: ../../third_party/dart/third_party/pkg/args
|
||||
async:
|
||||
path: ../../third_party/dart/third_party/pkg/async
|
||||
async_helper:
|
||||
path: ../../third_party/dart/pkg/async_helper
|
||||
collection:
|
||||
path: ../../third_party/dart/third_party/pkg/collection
|
||||
expect:
|
||||
path: ../../third_party/dart/pkg/expect
|
||||
file:
|
||||
path: ../../third_party/pkg/file/packages/file
|
||||
litetest:
|
||||
path: ../testing/litetest
|
||||
meta:
|
||||
path: ../../third_party/dart/pkg/meta
|
||||
path:
|
||||
@@ -42,3 +53,5 @@ dependency_overrides:
|
||||
path: ../../third_party/pkg/process
|
||||
process_runner:
|
||||
path: ../../third_party/pkg/process_runner
|
||||
smith:
|
||||
path: ../../third_party/dart/pkg/smith
|
||||
|
||||
227
engine/src/flutter/ci/test/format_test.dart
Normal file
227
engine/src/flutter/ci/test/format_test.dart
Normal file
@@ -0,0 +1,227 @@
|
||||
// Copyright 2013 The Flutter 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:io' as io;
|
||||
|
||||
import 'package:litetest/litetest.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:process_runner/process_runner.dart';
|
||||
|
||||
import '../bin/format.dart' as target;
|
||||
|
||||
final io.File script = io.File.fromUri(io.Platform.script).absolute;
|
||||
final io.Directory repoDir = script.parent.parent.parent;
|
||||
final ProcessPool pool = ProcessPool(
|
||||
numWorkers: 1,
|
||||
processRunner: ProcessRunner(defaultWorkingDirectory: repoDir),
|
||||
);
|
||||
|
||||
class FileContentPair {
|
||||
FileContentPair(this.original, this.formatted, this.fileExtension);
|
||||
|
||||
final String original;
|
||||
final String formatted;
|
||||
final String fileExtension;
|
||||
}
|
||||
|
||||
final FileContentPair ccContentPair = FileContentPair(
|
||||
'int main(){return 0;}\n', 'int main() {\n return 0;\n}\n', '.cc');
|
||||
final FileContentPair hContentPair =
|
||||
FileContentPair('int\nmain\n()\n;\n', 'int main();\n', '.h');
|
||||
final FileContentPair gnContentPair = FileContentPair(
|
||||
'test\n(){testvar=true}\n', 'test() {\n testvar = true\n}\n', '.gn');
|
||||
final FileContentPair javaContentPair = FileContentPair(
|
||||
'class Test{public static void main(String args[]){System.out.println("Test");}}\n',
|
||||
'class Test {\n public static void main(String args[]) {\n System.out.println("Test");\n }\n}\n',
|
||||
'.java');
|
||||
final FileContentPair pythonContentPair = FileContentPair(
|
||||
"if __name__=='__main__':\n sys.exit(\nMain(sys.argv)\n)\n",
|
||||
"if __name__ == '__main__':\n sys.exit(Main(sys.argv))\n",
|
||||
'.py');
|
||||
final FileContentPair whitespaceContentPair = FileContentPair(
|
||||
'int main() {\n return 0; \n}\n',
|
||||
'int main() {\n return 0;\n}\n',
|
||||
'.c');
|
||||
|
||||
class TestFileFixture {
|
||||
TestFileFixture(this.type) {
|
||||
switch (type) {
|
||||
case target.FormatCheck.clang:
|
||||
final io.File ccFile = io.File('${repoDir.path}/format_test.cc');
|
||||
ccFile.writeAsStringSync(ccContentPair.original);
|
||||
files.add(ccFile);
|
||||
|
||||
final io.File hFile = io.File('${repoDir.path}/format_test.h');
|
||||
hFile.writeAsStringSync(hContentPair.original);
|
||||
files.add(hFile);
|
||||
case target.FormatCheck.gn:
|
||||
final io.File gnFile = io.File('${repoDir.path}/format_test.gn');
|
||||
gnFile.writeAsStringSync(gnContentPair.original);
|
||||
files.add(gnFile);
|
||||
case target.FormatCheck.java:
|
||||
final io.File javaFile = io.File('${repoDir.path}/format_test.java');
|
||||
javaFile.writeAsStringSync(javaContentPair.original);
|
||||
files.add(javaFile);
|
||||
case target.FormatCheck.python:
|
||||
final io.File pyFile = io.File('${repoDir.path}/format_test.py');
|
||||
pyFile.writeAsStringSync(pythonContentPair.original);
|
||||
files.add(pyFile);
|
||||
case target.FormatCheck.whitespace:
|
||||
final io.File whitespaceFile = io.File('${repoDir.path}/format_test.c');
|
||||
whitespaceFile.writeAsStringSync(whitespaceContentPair.original);
|
||||
files.add(whitespaceFile);
|
||||
}
|
||||
}
|
||||
|
||||
final target.FormatCheck type;
|
||||
final List<io.File> files = <io.File>[];
|
||||
|
||||
void gitAdd() {
|
||||
final List<String> args = <String>['add'];
|
||||
for (final io.File file in files) {
|
||||
args.add(file.path);
|
||||
}
|
||||
|
||||
io.Process.runSync('git', args);
|
||||
}
|
||||
|
||||
void gitRemove() {
|
||||
final List<String> args = <String>['rm', '-f'];
|
||||
for (final io.File file in files) {
|
||||
args.add(file.path);
|
||||
}
|
||||
io.Process.runSync('git', args);
|
||||
}
|
||||
|
||||
Iterable<FileContentPair> getFileContents() {
|
||||
return files.map((io.File file) {
|
||||
String content = file.readAsStringSync();
|
||||
// Avoid clang-tidy formatting CRLF EOL on Windows
|
||||
content = content.replaceAll('\r\n', '\n');
|
||||
switch (type) {
|
||||
case target.FormatCheck.clang:
|
||||
return FileContentPair(
|
||||
content,
|
||||
path.extension(file.path) == '.cc'
|
||||
? ccContentPair.formatted
|
||||
: hContentPair.formatted,
|
||||
path.extension(file.path),
|
||||
);
|
||||
case target.FormatCheck.gn:
|
||||
return FileContentPair(
|
||||
content,
|
||||
gnContentPair.formatted,
|
||||
path.extension(file.path),
|
||||
);
|
||||
case target.FormatCheck.java:
|
||||
return FileContentPair(
|
||||
content,
|
||||
javaContentPair.formatted,
|
||||
path.extension(file.path),
|
||||
);
|
||||
case target.FormatCheck.python:
|
||||
return FileContentPair(
|
||||
content,
|
||||
pythonContentPair.formatted,
|
||||
path.extension(file.path),
|
||||
);
|
||||
case target.FormatCheck.whitespace:
|
||||
return FileContentPair(
|
||||
content,
|
||||
whitespaceContentPair.formatted,
|
||||
path.extension(file.path),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
final String formatterPath =
|
||||
'${repoDir.path}/ci/format.${io.Platform.isWindows ? 'bat' : 'sh'}';
|
||||
|
||||
test('Can fix C++ formatting errors', () {
|
||||
final TestFileFixture fixture = TestFileFixture(target.FormatCheck.clang);
|
||||
try {
|
||||
fixture.gitAdd();
|
||||
io.Process.runSync(formatterPath, <String>['--check', 'clang', '--fix'],
|
||||
workingDirectory: repoDir.path);
|
||||
|
||||
final Iterable<FileContentPair> files = fixture.getFileContents();
|
||||
for (final FileContentPair pair in files) {
|
||||
expect(pair.original, equals(pair.formatted));
|
||||
}
|
||||
} finally {
|
||||
fixture.gitRemove();
|
||||
}
|
||||
});
|
||||
|
||||
test('Can fix GN formatting errors', () {
|
||||
final TestFileFixture fixture = TestFileFixture(target.FormatCheck.gn);
|
||||
try {
|
||||
fixture.gitAdd();
|
||||
io.Process.runSync(formatterPath, <String>['--check', 'gn', '--fix'],
|
||||
workingDirectory: repoDir.path);
|
||||
|
||||
final Iterable<FileContentPair> files = fixture.getFileContents();
|
||||
for (final FileContentPair pair in files) {
|
||||
expect(pair.original, equals(pair.formatted));
|
||||
}
|
||||
} finally {
|
||||
fixture.gitRemove();
|
||||
}
|
||||
});
|
||||
|
||||
test('Can fix Java formatting errors', () {
|
||||
final TestFileFixture fixture = TestFileFixture(target.FormatCheck.java);
|
||||
try {
|
||||
fixture.gitAdd();
|
||||
io.Process.runSync(formatterPath, <String>['--check', 'java', '--fix'],
|
||||
workingDirectory: repoDir.path);
|
||||
|
||||
final Iterable<FileContentPair> files = fixture.getFileContents();
|
||||
for (final FileContentPair pair in files) {
|
||||
expect(pair.original, equals(pair.formatted));
|
||||
}
|
||||
} finally {
|
||||
fixture.gitRemove();
|
||||
}
|
||||
// TODO(mtolmacs): Fails if Java dependency is unavailable,
|
||||
// https://github.com/flutter/flutter/issues/129221
|
||||
}, skip: true);
|
||||
|
||||
test('Can fix Python formatting errors', () {
|
||||
final TestFileFixture fixture = TestFileFixture(target.FormatCheck.python);
|
||||
try {
|
||||
fixture.gitAdd();
|
||||
io.Process.runSync(formatterPath, <String>['--check', 'python', '--fix'],
|
||||
workingDirectory: repoDir.path);
|
||||
|
||||
final Iterable<FileContentPair> files = fixture.getFileContents();
|
||||
for (final FileContentPair pair in files) {
|
||||
expect(pair.original, equals(pair.formatted));
|
||||
}
|
||||
} finally {
|
||||
fixture.gitRemove();
|
||||
}
|
||||
});
|
||||
|
||||
test('Can fix whitespace formatting errors', () {
|
||||
final TestFileFixture fixture =
|
||||
TestFileFixture(target.FormatCheck.whitespace);
|
||||
try {
|
||||
fixture.gitAdd();
|
||||
io.Process.runSync(
|
||||
formatterPath, <String>['--check', 'whitespace', '--fix'],
|
||||
workingDirectory: repoDir.path);
|
||||
|
||||
final Iterable<FileContentPair> files = fixture.getFileContents();
|
||||
for (final FileContentPair pair in files) {
|
||||
expect(pair.original, equals(pair.formatted));
|
||||
}
|
||||
} finally {
|
||||
fixture.gitRemove();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -979,6 +979,32 @@ def gather_api_consistency_tests(build_dir):
|
||||
)
|
||||
|
||||
|
||||
def gather_ci_tests(build_dir):
|
||||
test_dir = os.path.join(BUILDROOT_DIR, 'flutter', 'ci')
|
||||
dart_tests = glob.glob('%s/test/*_test.dart' % test_dir)
|
||||
|
||||
run_engine_executable(
|
||||
build_dir,
|
||||
os.path.join('dart-sdk', 'bin', 'dart'),
|
||||
None,
|
||||
flags=['pub', 'get', '--offline'],
|
||||
cwd=test_dir,
|
||||
)
|
||||
|
||||
for dart_test_file in dart_tests:
|
||||
opts = [
|
||||
'--disable-dart-dev', dart_test_file,
|
||||
os.path.join(BUILDROOT_DIR, 'flutter')
|
||||
]
|
||||
yield EngineExecutableTask(
|
||||
build_dir,
|
||||
os.path.join('dart-sdk', 'bin', 'dart'),
|
||||
None,
|
||||
flags=opts,
|
||||
cwd=test_dir
|
||||
)
|
||||
|
||||
|
||||
def run_engine_tasks_in_parallel(tasks):
|
||||
# Work around a bug in Python.
|
||||
#
|
||||
@@ -1217,6 +1243,7 @@ Flutter Wiki page on the subject: https://github.com/flutter/flutter/wiki/Testin
|
||||
tasks += list(gather_path_ops_tests(build_dir))
|
||||
tasks += list(gather_const_finder_tests(build_dir))
|
||||
tasks += list(gather_front_end_server_tests(build_dir))
|
||||
tasks += list(gather_ci_tests(build_dir))
|
||||
tasks += list(gather_dart_tests(build_dir, dart_filter))
|
||||
run_engine_tasks_in_parallel(tasks)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env vpython3
|
||||
# Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
@@ -29,7 +29,6 @@ def Main(argv):
|
||||
githooks = os.path.join(FLUTTER_DIR, 'tools', 'githooks')
|
||||
if IsWindows():
|
||||
git = 'git.bat'
|
||||
githooks = os.path.join(githooks, 'windows')
|
||||
result = subprocess.run([
|
||||
git,
|
||||
'config',
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
YELLOW='[33m'
|
||||
RED='[31m'
|
||||
NC='[0m'
|
||||
BOLD='[1m'
|
||||
echo "${BOLD}${RED}Warning:${NC} ${BOLD}Pre-push checks not supported on Windows${NC}"
|
||||
echo "${BOLD}See: https://github.com/flutter/flutter/issues/86506${NC}"
|
||||
echo "${BOLD}${RED}Warning:${NC} ${BOLD}Pre-push checks are not enabled!${NC}"
|
||||
echo "${YELLOW}${BOLD}Note:${NC} ${BOLD}Please run 'gclient sync -D' to enable pre-push checks on Windows${NC}"
|
||||
|
||||
16
engine/src/flutter/tools/yapf.bat
Normal file
16
engine/src/flutter/tools/yapf.bat
Normal file
@@ -0,0 +1,16 @@
|
||||
@ECHO off
|
||||
REM Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
REM Use of this source code is governed by a BSD-style license that can be
|
||||
REM found in the LICENSE file.
|
||||
|
||||
REM ---------------------------------- NOTE ----------------------------------
|
||||
REM
|
||||
REM Please keep the logic in this file consistent with the logic in the
|
||||
REM `yapf.sh` script in the same directory to ensure that it continues to
|
||||
REM work across all platforms!
|
||||
REM
|
||||
REM --------------------------------------------------------------------------
|
||||
|
||||
SET yapf_path=%~dp0\..\..\third_party\yapf
|
||||
|
||||
cmd /V /C "SET PYTHONPATH=%yapf_path%&& vpython3 %yapf_path%\yapf %*"
|
||||
@@ -3,6 +3,14 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# ---------------------------------- NOTE ----------------------------------
|
||||
#
|
||||
# Please keep the logic in this file consistent with the logic in the
|
||||
# `yapf.bat` script in the same directory to ensure that it continues to
|
||||
# work across all platforms!
|
||||
#
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# Generates objc docs for Flutter iOS libraries.
|
||||
|
||||
set -e
|
||||
|
||||
Reference in New Issue
Block a user