[flutter_plugin_tools] Add a new base command for looping over packages (#4067)

Most of our commands are generally of the form:
```
  for (each plugin as defined by the tool flags)
    check some things for success or failure
  print a summary all of the failing things
  exit non-zero if anything failed
```

Currently all that logic not consistent, having been at various points copied and pasted around, modified, in some cases rewritten. There's unnecessary boilerplate in each new command, and there's unnecessary variation that makes it harder both to maintain the tool, and to consume the test output:
- There's no standard format for separating each plugin's run to search within a log
- There's no standard format for the summary at the end
- In some cases commands have been written to ToolExit on failure, which means we don't actually get the rest of the runs

This makes a new base class for commands that follow this structure to use, with shared code for all the common bits. This makes it harder to accidentally write new commands incorrectly, easier to maintain the code, and lets us standardize output so that searching within large logs will be easier.

This ports two commands over as a proof of concept to demonstrate that it works; more will be converted in follow-ups.

Related to https://github.com/flutter/flutter/issues/83413
This commit is contained in:
stuartmorgan
2021-06-22 13:32:03 -07:00
committed by GitHub
parent f0967e5186
commit 356d316717
9 changed files with 710 additions and 96 deletions

View File

@ -4,11 +4,9 @@
import 'package:file/file.dart';
import 'package:git/git.dart';
import 'package:path/path.dart' as p;
import 'package:pubspec_parse/pubspec_parse.dart';
import 'common/core.dart';
import 'common/plugin_command.dart';
import 'common/package_looping_command.dart';
import 'common/process_runner.dart';
/// A command to enforce pubspec conventions across the repository.
@ -16,7 +14,7 @@ import 'common/process_runner.dart';
/// This both ensures that repo best practices for which optional fields are
/// used are followed, and that the structure is consistent to make edits
/// across multiple pubspec files easier.
class PubspecCheckCommand extends PluginCommand {
class PubspecCheckCommand extends PackageLoopingCommand {
/// Creates an instance of the version check command.
PubspecCheckCommand(
Directory packagesDir, {
@ -52,29 +50,20 @@ class PubspecCheckCommand extends PluginCommand {
'Checks that pubspecs follow repository conventions.';
@override
Future<void> run() async {
final List<String> failingPackages = <String>[];
await for (final Directory package in getPackages()) {
final String relativePackagePath =
p.relative(package.path, from: packagesDir.path);
print('Checking $relativePackagePath...');
final File pubspec = package.childFile('pubspec.yaml');
final bool passesCheck = !pubspec.existsSync() ||
await _checkPubspec(pubspec, packageName: package.basename);
if (!passesCheck) {
failingPackages.add(relativePackagePath);
}
}
bool get hasLongOutput => false;
if (failingPackages.isNotEmpty) {
print('The following packages have pubspec issues:');
for (final String package in failingPackages) {
print(' $package');
}
throw ToolExit(1);
}
@override
bool get includeSubpackages => true;
print('\nNo pubspec issues found!');
@override
Future<List<String>> runForPackage(Directory package) async {
final File pubspec = package.childFile('pubspec.yaml');
final bool passesCheck = !pubspec.existsSync() ||
await _checkPubspec(pubspec, packageName: package.basename);
if (!passesCheck) {
return PackageLoopingCommand.failure;
}
return PackageLoopingCommand.success;
}
Future<bool> _checkPubspec(