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