Unverified Commit 0acf53e3 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Run `dart fix` on customer tests as promised (#83944)

parent ab06d7dd
...@@ -31,13 +31,21 @@ Future<bool> runTests({ ...@@ -31,13 +31,21 @@ Future<bool> runTests({
if (verbose) { if (verbose) {
final String s = files.length == 1 ? '' : 's'; final String s = files.length == 1 ? '' : 's';
final String ss = shardedFiles.length == 1 ? '' : 's'; if (numberShards > 1) {
print('${files.length} file$s specified. ${shardedFiles.length} test$ss in shard #$shardIndex.'); final String ss = shardedFiles.length == 1 ? '' : 's';
print('${files.length} file$s specified. ${shardedFiles.length} test$ss in shard #$shardIndex ($numberShards shards total).');
} else {
print('${files.length} file$s specified.');
}
print(''); print('');
} }
if (verbose) { if (verbose) {
print('Tests in this shard:'); if (numberShards > 1) {
print('Tests in this shard:');
} else {
print('Tests:');
}
for (final File file in shardedFiles) for (final File file in shardedFiles)
print(file.path); print(file.path);
} }
...@@ -46,30 +54,40 @@ Future<bool> runTests({ ...@@ -46,30 +54,40 @@ Future<bool> runTests({
for (final File file in shardedFiles) { for (final File file in shardedFiles) {
if (verbose) if (verbose)
print('Processing ${file.path}...'); print('Processing ${file.path}...');
void printHeader() {
if (!verbose)
print('Processing ${file.path}...');
}
void failure(String message) {
printHeader();
print('ERROR: $message');
failures += 1;
}
CustomerTest instructions; CustomerTest instructions;
try { try {
instructions = CustomerTest(file); instructions = CustomerTest(file);
} on FormatException catch (error) { } on FormatException catch (error) {
print('ERROR: ${error.message}'); failure(error.message);
print(''); print('');
failures += 1;
continue; continue;
} on FileSystemException catch (error) { } on FileSystemException catch (error) {
print('ERROR: ${error.message}'); failure(error.message);
print(' ${file.path}');
print(''); print('');
failures += 1;
continue; continue;
} }
bool success = true;
final Directory checkout = Directory.systemTemp.createTempSync('flutter_customer_testing.${path.basenameWithoutExtension(file.path)}.'); final Directory checkout = Directory.systemTemp.createTempSync('flutter_customer_testing.${path.basenameWithoutExtension(file.path)}.');
if (verbose) if (verbose)
print('Created temporary directory: ${checkout.path}'); print('Created temporary directory: ${checkout.path}');
try { try {
bool? success; assert(instructions.fetch.isNotEmpty);
bool showContacts = false;
for (final String fetchCommand in instructions.fetch) { for (final String fetchCommand in instructions.fetch) {
success = await shell(fetchCommand, checkout, verbose: verbose, silentFailure: skipOnFetchFailure); success = await shell(fetchCommand, checkout, verbose: verbose, silentFailure: skipOnFetchFailure, failedCallback: printHeader);
if (!success) { if (!success) {
if (skipOnFetchFailure) { if (skipOnFetchFailure) {
if (verbose) { if (verbose) {
...@@ -78,39 +96,51 @@ Future<bool> runTests({ ...@@ -78,39 +96,51 @@ Future<bool> runTests({
print('Skipping ${file.path} (fetch failed).'); print('Skipping ${file.path} (fetch failed).');
} }
} else { } else {
print('ERROR: Failed to fetch repository.'); failure('Failed to fetch repository.');
failures += 1;
showContacts = true;
} }
break; break;
} }
} }
assert(success != null); if (success) {
if (success == true) { final Directory customerRepo = Directory(path.join(checkout.path, 'tests'));
if (verbose) for (final Directory updateDirectory in instructions.update) {
print('Running tests...'); final Directory resolvedUpdateDirectory = Directory(path.join(customerRepo.path, updateDirectory.path));
final Directory tests = Directory(path.join(checkout.path, 'tests')); if (verbose)
// TODO(ianh): Once we have a way to update source code, run that command in each directory of instructions.update print('Updating code in ${resolvedUpdateDirectory.path}...');
for (int iteration = 0; iteration < repeat; iteration += 1) { if (!File(path.join(resolvedUpdateDirectory.path, 'pubspec.yaml')).existsSync()) {
if (verbose && repeat > 1) failure('The directory ${updateDirectory.path}, which was specified as an update directory, does not contain a "pubspec.yaml" file.');
print('Round ${iteration + 1} of $repeat.'); success = false;
for (final String testCommand in instructions.tests) { break;
testCount += 1; }
success = await shell(testCommand, tests, verbose: verbose); success = await shell('flutter packages get', resolvedUpdateDirectory, verbose: verbose, failedCallback: printHeader);
if (!success) { if (!success) {
print('ERROR: One or more tests from ${path.basenameWithoutExtension(file.path)} failed.'); failure('Could not run "flutter pub get" in ${updateDirectory.path}, which was specified as an update directory.');
failures += 1; break;
showContacts = true; }
break; success = await shell('dart fix --apply', resolvedUpdateDirectory, verbose: verbose, failedCallback: printHeader);
if (!success) {
failure('Could not run "dart fix" in ${updateDirectory.path}, which was specified as an update directory.');
break;
}
}
if (success) {
if (verbose)
print('Running tests...');
for (int iteration = 0; iteration < repeat; iteration += 1) {
if (verbose && repeat > 1)
print('Round ${iteration + 1} of $repeat.');
for (final String testCommand in instructions.tests) {
testCount += 1;
success = await shell(testCommand, customerRepo, verbose: verbose, failedCallback: printHeader);
if (!success) {
failure('One or more tests from ${path.basenameWithoutExtension(file.path)} failed.');
break;
}
} }
} }
if (verbose && success)
print('Tests finished.');
} }
if (verbose && success == true)
print('Tests finished.');
}
if (showContacts) {
final String s = instructions.contacts.length == 1 ? '' : 's';
print('Contact$s: ${instructions.contacts.join(", ")}');
} }
} finally { } finally {
if (verbose) if (verbose)
...@@ -121,7 +151,11 @@ Future<bool> runTests({ ...@@ -121,7 +151,11 @@ Future<bool> runTests({
print('Failed to delete "${checkout.path}".'); print('Failed to delete "${checkout.path}".');
} }
} }
if (verbose) if (!success) {
final String s = instructions.contacts.length == 1 ? '' : 's';
print('Contact$s: ${instructions.contacts.join(", ")}');
}
if (verbose || !success)
print(''); print('');
} }
if (failures > 0) { if (failures > 0) {
...@@ -135,7 +169,7 @@ Future<bool> runTests({ ...@@ -135,7 +169,7 @@ Future<bool> runTests({
final RegExp _spaces = RegExp(r' +'); final RegExp _spaces = RegExp(r' +');
Future<bool> shell(String command, Directory directory, { bool verbose = false, bool silentFailure = false }) async { Future<bool> shell(String command, Directory directory, { bool verbose = false, bool silentFailure = false, void Function()? failedCallback }) async {
if (verbose) if (verbose)
print('>> $command'); print('>> $command');
Process process; Process process;
...@@ -152,6 +186,8 @@ Future<bool> shell(String command, Directory directory, { bool verbose = false, ...@@ -152,6 +186,8 @@ Future<bool> shell(String command, Directory directory, { bool verbose = false,
if (success || silentFailure) if (success || silentFailure)
return success; return success;
if (!verbose) { if (!verbose) {
if (failedCallback != null)
failedCallback();
print('>> $command'); print('>> $command');
output.forEach(printLog); output.forEach(printLog);
} }
......
...@@ -15,6 +15,7 @@ Future<void> main(List<String> arguments) async { ...@@ -15,6 +15,7 @@ Future<void> main(List<String> arguments) async {
exit(await run(arguments) ? 0 : 1); exit(await run(arguments) ? 0 : 1);
} }
// Return true if successful, false if failed.
Future<bool> run(List<String> arguments) async { Future<bool> run(List<String> arguments) async {
final ArgParser argParser = ArgParser( final ArgParser argParser = ArgParser(
allowTrailingOptions: false, allowTrailingOptions: false,
...@@ -92,11 +93,21 @@ Future<bool> run(List<String> arguments) async { ...@@ -92,11 +93,21 @@ Future<bool> run(List<String> arguments) async {
.where((File file) => !skipTemplate || path.basename(file.path) != 'template.test') .where((File file) => !skipTemplate || path.basename(file.path) != 'template.test')
.toList(); .toList();
if (help || repeat == null || files.isEmpty) { if (help || repeat == null || files.isEmpty || numberShards == null || numberShards <= 0 || shardIndex == null || shardIndex < 0) {
printHelp(); printHelp();
if (verbose) { if (verbose) {
if (repeat == null) if (repeat == null)
print('Error: Could not parse repeat count ("${parsedArguments['repeat']}")'); print('Error: Could not parse repeat count ("${parsedArguments['repeat']}")');
if (numberShards == null) {
print('Error: Could not parse shards count ("${parsedArguments['shards']}")');
} else if (numberShards < 1) {
print('Error: The specified shards count ($numberShards) is less than 1. It must be greater than zero.');
}
if (shardIndex == null) {
print('Error: Could not parse shard index ("${parsedArguments['shard-index']}")');
} else if (shardIndex < 0) {
print('Error: The specified shard index ($shardIndex) is negative. It must be in the range [0 .. shards - 1].');
}
if (parsedArguments.rest.isEmpty) { if (parsedArguments.rest.isEmpty) {
print('Error: No file arguments specified.'); print('Error: No file arguments specified.');
} else if (files.isEmpty) { } else if (files.isEmpty) {
...@@ -106,14 +117,17 @@ Future<bool> run(List<String> arguments) async { ...@@ -106,14 +117,17 @@ Future<bool> run(List<String> arguments) async {
return help; return help;
} }
if (files.length < shardIndex!) if (shardIndex > numberShards - 1) {
print('Warning: There are more shards than tests. Some shards will not run any tests.'); print(
'Error: The specified shard index ($shardIndex) is more than the specified number of shards ($numberShards). '
if (numberShards! <= shardIndex) { 'It must be in the range [0 .. shards - 1].'
print('Error: There are more shard indexes than shards.'); );
return help; return false;
} }
if (files.length < numberShards)
print('Warning: There are more shards than tests. Some shards will not run any tests.');
return runTests( return runTests(
repeat: repeat, repeat: repeat,
skipOnFetchFailure: skipOnFetchFailure, skipOnFetchFailure: skipOnFetchFailure,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment