Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Conversation

stuartmorgan-g
Copy link
Contributor

@stuartmorgan-g stuartmorgan-g commented Jun 30, 2021

Add a summary to the end of successful runs for everything using the new looping base command, similar to what we do for summarizing failures. This will make it easy to manually check results for PRs that we know should be changing the set of run packages (adding a new package, adding a new test type to a package, adding a new test type to the tool), as well as spot-checking when we see unexpected results (e.g., looking back and why a PR didn't fail CI when we discover that it should have).

To support better surfacing skips, this restructures the return value of runForPackage to have "skip" as one of the options. As a result of it being a return value, packages that used printSkip to indicate that parts of the command were being skipped have been changed to no longer do that.

Fixes flutter/flutter#85626

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Note that unlike the flutter/flutter repo, the flutter/plugins repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt.
  • All existing and new tests are passing.

int _otherWarningCount = 0;

/// The package currently being run by [runForPackage].
Directory? _currentPackage;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This doesn't have to be an instance variable. It would be better off as a parameter to logSkip and logWarning. Keeping it around could lead to some weird bugs at some point because the coupling between logSkip and _currentPackage isn't obvious to the client. If you think it's cumbersome to have to pass the package to logSkip you could pass an apropos version of logSkip to the implementor of runForPackage that has the currentPackage bound.

tldr functional good, oop bad

Copy link
Contributor Author

@stuartmorgan-g stuartmorgan-g Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better off as a parameter to logSkip and logWarning.

I strongly considered that, since this approach feels a bit sketchy, but in practice that would be worse. With this version, the possible bugs are contained entirely within this one base class, which is short and has unit tests ensuring that these work correctly. With the parameter version, however, it's possible to write things like:

logWarning(message, example) // Oops, this was supposed to be package, not the example subdirectory.

and thus causing the warning not be summarized anywhere. That can happen in any command implementation, and is unlikely to be covered by tests.

For logSkip, the more I think about the summary, the more I think I should actually make it a return value option instead. Originally I had created printSkip for logging any case where something is being skipped, which for some commands might be, say, a subset of the examples. But with the summary we don't actually want to allow that, so I need to rework the return value. I'll land out the outstanding other conversions, then change the value to a return class with state (pass/skip/error)+error messages.

Keeping it around could lead to some weird bugs at some point because the coupling between logSkip and _currentPackage isn't obvious to the client.

For logSkip I agree. For logWarning I think that's actually a feature; a command can just logging warnings whenever it wants to as output, and doesn't have to care about what the base class might be doing with them. How they are tracked and summarized is entirely an implementation detail of the base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has been updated to eliminate logSkip by changing the return from a run to a small data class and making "skipped" a first-class result rather than a possibly-partial bit based on a log.

Commands that used to log formal skips for subsets of the command while running other subsets now just use simple print statements to indicate what is and isn't being run, and "skip" is reserved for cases where nothing is run.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a huge improvement. You could eliminate _currentPackage if you created a way for PackageResult to carry the warnings too. It's not a huge deal, _currentPackage bugs me a bit since it's a looping parameter in an instance variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's valid to print warnings outside the loop though; I don't want to have two different ways of handling warnings in the subclasses.

final String skippedWarningSummary =
runWarningCount > 0 ? ' ($skippedWarningCount with warnings)' : '';
print('------------------------------------------------------------');
if (hasLongOutput) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is hasLongOutput suppose to mean "verbose" in this case? We had another place in the code where the same verbiage meant "compress the output because it's long" I thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that in practice, the output of a given runForPackage call is likely to be long. The existing use is that it changes the header format from a single line to the ====-wrapped banner style, to make it easier to skim for a run break.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I deliberately called it "long" rather than "verbose" because I don't want to imply that underlying commands are being called with a -v or similar flag; some commands print a lot even when you don't make them explicitly verbose.)

@@ -45,7 +84,7 @@ abstract class PackageLoopingCommand extends PluginCommand {
/// be included in the final error summary (e.g., a command that only has a
/// single failure mode), or strings that should be listed for that package
/// in the final summary. An empty list indicates success.
Future<List<String>> runForPackage(Directory package);
Future<PackageResult> runForPackage(Directory package);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the fact that I had to give the magic values [] and [''] special names in the original API should have been more of a red flag to me than it was.

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice update.

Comment on lines +292 to +293
for (final Directory package in packages) {
final PackageResult result = results[package]!;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think you need to pass in packages here, you can just loop over results.values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Results is a map, and thus doesn't have a guaranteed order; it's important that the summary be in the same order as the packages for ease of referencing up to the details.

int _otherWarningCount = 0;

/// The package currently being run by [runForPackage].
Directory? _currentPackage;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a huge improvement. You could eliminate _currentPackage if you created a way for PackageResult to carry the warnings too. It's not a huge deal, _currentPackage bugs me a bit since it's a looping parameter in an instance variable.

@stuartmorgan-g stuartmorgan-g merged commit 719a675 into flutter:master Jul 1, 2021
@stuartmorgan-g stuartmorgan-g deleted the package-looping-run-summary branch July 1, 2021 23:25
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jul 1, 2021
amantoux pushed a commit to amantoux/plugins that referenced this pull request Jul 10, 2021
Add a summary to the end of successful runs for everything using the new looping base command, similar to what we do for summarizing failures. This will make it easy to manually check results for PRs that we know should be changing the set of run packages (adding a new package, adding a new test type to a package, adding a new test type to the tool), as well as spot-checking when we see unexpected results (e.g., looking back and why a PR didn't fail CI when we discover that it should have).

To support better surfacing skips, this restructures the return value of `runForPackage` to have "skip" as one of the options. As a result of it being a return value, packages that used `printSkip` to indicate that *parts* of the command were being skipped have been changed to no longer do that.

Fixes flutter/flutter#85626
fotiDim pushed a commit to fotiDim/plugins that referenced this pull request Sep 13, 2021
Add a summary to the end of successful runs for everything using the new looping base command, similar to what we do for summarizing failures. This will make it easy to manually check results for PRs that we know should be changing the set of run packages (adding a new package, adding a new test type to a package, adding a new test type to the tool), as well as spot-checking when we see unexpected results (e.g., looking back and why a PR didn't fail CI when we discover that it should have).

To support better surfacing skips, this restructures the return value of `runForPackage` to have "skip" as one of the options. As a result of it being a return value, packages that used `printSkip` to indicate that *parts* of the command were being skipped have been changed to no longer do that.

Fixes flutter/flutter#85626
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[flutter_plugin_tools] Add results summary to long-form output commands
2 participants