Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions script/tool/lib/src/analyze_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import 'dart:async';

import 'package:file/file.dart';
import 'package:flutter_plugin_tools/src/common/plugin_command.dart';
import 'package:platform/platform.dart';
import 'package:yaml/yaml.dart';

import 'common/core.dart';
import 'common/package_looping_command.dart';
import 'common/plugin_command.dart';
import 'common/process_runner.dart';
import 'common/repository_package.dart';

const int _exitPackagesGetFailed = 3;

Expand Down Expand Up @@ -55,8 +56,9 @@ class AnalyzeCommand extends PackageLoopingCommand {
final bool hasLongOutput = false;

/// Checks that there are no unexpected analysis_options.yaml files.
bool _hasUnexpecetdAnalysisOptions(Directory package) {
final List<FileSystemEntity> files = package.listSync(recursive: true);
bool _hasUnexpecetdAnalysisOptions(RepositoryPackage package) {
final List<FileSystemEntity> files =
package.directory.listSync(recursive: true);
for (final FileSystemEntity file in files) {
if (file.basename != 'analysis_options.yaml' &&
file.basename != '.analysis_options') {
Expand Down Expand Up @@ -87,7 +89,7 @@ class AnalyzeCommand extends PackageLoopingCommand {
Future<bool> _runPackagesGetOnTargetPackages() async {
final List<Directory> packageDirectories =
await getTargetPackagesAndSubpackages()
.map((PackageEnumerationEntry package) => package.directory)
.map((PackageEnumerationEntry entry) => entry.package.directory)
.toList();
final Set<String> packagePaths =
packageDirectories.map((Directory dir) => dir.path).toSet();
Expand Down Expand Up @@ -135,13 +137,13 @@ class AnalyzeCommand extends PackageLoopingCommand {
}

@override
Future<PackageResult> runForPackage(Directory package) async {
Future<PackageResult> runForPackage(RepositoryPackage package) async {
if (_hasUnexpecetdAnalysisOptions(package)) {
return PackageResult.fail(<String>['Unexpected local analysis options']);
}
final int exitCode = await processRunner.runAndStream(
_dartBinaryPath, <String>['analyze', '--fatal-infos'],
workingDir: package);
workingDir: package.directory);
if (exitCode != 0) {
return PackageResult.fail();
}
Expand Down
11 changes: 6 additions & 5 deletions script/tool/lib/src/build_examples_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'common/core.dart';
import 'common/package_looping_command.dart';
import 'common/plugin_utils.dart';
import 'common/process_runner.dart';
import 'common/repository_package.dart';

/// Key for APK.
const String _platformFlagApk = 'apk';
Expand Down Expand Up @@ -96,7 +97,7 @@ class BuildExamplesCommand extends PackageLoopingCommand {
}

@override
Future<PackageResult> runForPackage(Directory package) async {
Future<PackageResult> runForPackage(RepositoryPackage package) async {
final List<String> errors = <String>[];

final Iterable<_PlatformDetails> requestedPlatforms = _platforms.entries
Expand Down Expand Up @@ -126,9 +127,9 @@ class BuildExamplesCommand extends PackageLoopingCommand {
}
print('');

for (final Directory example in getExamplesForPlugin(package)) {
for (final RepositoryPackage example in package.getExamples()) {
final String packageName =
getRelativePosixPath(example, from: packagesDir);
getRelativePosixPath(example.directory, from: packagesDir);

for (final _PlatformDetails platform in buildPlatforms) {
String buildPlatform = platform.label;
Expand All @@ -149,7 +150,7 @@ class BuildExamplesCommand extends PackageLoopingCommand {
}

Future<bool> _buildExample(
Directory example,
RepositoryPackage example,
String flutterBuildType, {
List<String> extraBuildFlags = const <String>[],
}) async {
Expand All @@ -164,7 +165,7 @@ class BuildExamplesCommand extends PackageLoopingCommand {
if (enableExperiment.isNotEmpty)
'--enable-experiment=$enableExperiment',
],
workingDir: example,
workingDir: example.directory,
);
return exitCode == 0;
}
Expand Down
86 changes: 34 additions & 52 deletions script/tool/lib/src/common/package_looping_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:platform/platform.dart';
import 'core.dart';
import 'plugin_command.dart';
import 'process_runner.dart';
import 'repository_package.dart';

/// Possible outcomes of a command run for a package.
enum RunState {
Expand Down Expand Up @@ -84,7 +85,7 @@ abstract class PackageLoopingCommand extends PluginCommand {
int _otherWarningCount = 0;

/// The package currently being run by [runForPackage].
PackageEnumerationEntry? _currentPackage;
PackageEnumerationEntry? _currentPackageEntry;

/// Called during [run] before any calls to [runForPackage]. This provides an
/// opportunity to fail early if the command can't be run (e.g., because the
Expand All @@ -97,7 +98,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<PackageResult> runForPackage(Directory package);
Future<PackageResult> runForPackage(RepositoryPackage package);

/// Called during [run] after all calls to [runForPackage]. This provides an
/// opportunity to do any cleanup of run-level state.
Expand Down Expand Up @@ -155,31 +156,13 @@ abstract class PackageLoopingCommand extends PluginCommand {
/// things that might be useful to someone debugging an unexpected result.
void logWarning(String warningMessage) {
print(Colorize(warningMessage)..yellow());
if (_currentPackage != null) {
_packagesWithWarnings.add(_currentPackage!);
if (_currentPackageEntry != null) {
_packagesWithWarnings.add(_currentPackageEntry!);
} else {
++_otherWarningCount;
}
}

/// Returns the identifying name to use for [package].
///
/// Implementations should not expect a specific format for this string, since
/// it uses heuristics to try to be precise without being overly verbose. If
/// an exact format (e.g., published name, or basename) is required, that
/// should be used instead.
String getPackageDescription(Directory package) {
String packageName = getRelativePosixPath(package, from: packagesDir);
final List<String> components = p.posix.split(packageName);
// For the common federated plugin pattern of `foo/foo_subpackage`, drop
// the first part since it's not useful.
if (components.length >= 2 &&
components[1].startsWith('${components[0]}_')) {
packageName = p.posix.joinAll(components.sublist(1));
}
return packageName;
}

/// Returns the relative path from [from] to [entity] in Posix style.
///
/// This should be used when, for example, printing package-relative paths in
Expand Down Expand Up @@ -219,50 +202,50 @@ abstract class PackageLoopingCommand extends PluginCommand {
Future<bool> _runInternal() async {
_packagesWithWarnings.clear();
_otherWarningCount = 0;
_currentPackage = null;
_currentPackageEntry = null;

await initializeRun();

final List<PackageEnumerationEntry> packages = includeSubpackages
final List<PackageEnumerationEntry> targetPackages = includeSubpackages
? await getTargetPackagesAndSubpackages(filterExcluded: false).toList()
: await getTargetPackages(filterExcluded: false).toList();

final Map<PackageEnumerationEntry, PackageResult> results =
<PackageEnumerationEntry, PackageResult>{};
for (final PackageEnumerationEntry package in packages) {
_currentPackage = package;
_printPackageHeading(package);
for (final PackageEnumerationEntry entry in targetPackages) {
_currentPackageEntry = entry;
_printPackageHeading(entry);

// Command implementations should never see excluded packages; they are
// included at this level only for logging.
if (package.excluded) {
results[package] = PackageResult.exclude();
if (entry.excluded) {
results[entry] = PackageResult.exclude();
continue;
}

final PackageResult result = await runForPackage(package.directory);
final PackageResult result = await runForPackage(entry.package);
if (result.state == RunState.skipped) {
final String message =
'${indentation}SKIPPING: ${result.details.first}';
captureOutput ? print(message) : print(Colorize(message)..darkGray());
}
results[package] = result;
results[entry] = result;
}
_currentPackage = null;
_currentPackageEntry = null;

completeRun();

print('\n');
// If there were any errors reported, summarize them and exit.
if (results.values
.any((PackageResult result) => result.state == RunState.failed)) {
_printFailureSummary(packages, results);
_printFailureSummary(targetPackages, results);
return false;
}

// Otherwise, print a summary of what ran for ease of auditing that all the
// expected tests ran.
_printRunSummary(packages, results);
_printRunSummary(targetPackages, results);

print('\n');
_printSuccess('No issues found!');
Expand All @@ -283,9 +266,9 @@ abstract class PackageLoopingCommand extends PluginCommand {
/// Something is always printed to make it easier to distinguish between
/// a command running for a package and producing no output, and a command
/// not having been run for a package.
void _printPackageHeading(PackageEnumerationEntry package) {
final String packageDisplayName = getPackageDescription(package.directory);
String heading = package.excluded
void _printPackageHeading(PackageEnumerationEntry entry) {
final String packageDisplayName = entry.package.displayName;
String heading = entry.excluded
? 'Not running for $packageDisplayName; excluded'
: 'Running for $packageDisplayName';
if (hasLongOutput) {
Expand All @@ -295,16 +278,15 @@ abstract class PackageLoopingCommand extends PluginCommand {
|| $heading
============================================================
''';
} else if (!package.excluded) {
} else if (!entry.excluded) {
heading = '$heading...';
}
if (captureOutput) {
print(heading);
} else {
final Colorize colorizeHeading = Colorize(heading);
print(package.excluded
? colorizeHeading.darkGray()
: colorizeHeading.cyan());
print(
entry.excluded ? colorizeHeading.darkGray() : colorizeHeading.cyan());
}
}

Expand Down Expand Up @@ -349,17 +331,18 @@ abstract class PackageLoopingCommand extends PluginCommand {

/// Prints a one-line-per-package overview of the run results for each
/// package.
void _printPerPackageRunOverview(List<PackageEnumerationEntry> packages,
void _printPerPackageRunOverview(
List<PackageEnumerationEntry> packageEnumeration,
{required Set<PackageEnumerationEntry> skipped}) {
print('Run overview:');
for (final PackageEnumerationEntry package in packages) {
final bool hadWarning = _packagesWithWarnings.contains(package);
for (final PackageEnumerationEntry entry in packageEnumeration) {
final bool hadWarning = _packagesWithWarnings.contains(entry);
Styles style;
String summary;
if (package.excluded) {
if (entry.excluded) {
summary = 'excluded';
style = Styles.DARK_GRAY;
} else if (skipped.contains(package)) {
} else if (skipped.contains(entry)) {
summary = 'skipped';
style = hadWarning ? Styles.LIGHT_YELLOW : Styles.DARK_GRAY;
} else {
Expand All @@ -373,27 +356,26 @@ abstract class PackageLoopingCommand extends PluginCommand {
if (!captureOutput) {
summary = (Colorize(summary)..apply(style)).toString();
}
print(' ${getPackageDescription(package.directory)} - $summary');
print(' ${entry.package.displayName} - $summary');
}
print('');
}

/// Prints a summary of all of the failures from [results].
void _printFailureSummary(List<PackageEnumerationEntry> packages,
void _printFailureSummary(List<PackageEnumerationEntry> packageEnumeration,
Map<PackageEnumerationEntry, PackageResult> results) {
const String indentation = ' ';
_printError(failureListHeader);
for (final PackageEnumerationEntry package in packages) {
final PackageResult result = results[package]!;
for (final PackageEnumerationEntry entry in packageEnumeration) {
final PackageResult result = results[entry]!;
if (result.state == RunState.failed) {
final String errorIndentation = indentation * 2;
String errorDetails = '';
if (result.details.isNotEmpty) {
errorDetails =
':\n$errorIndentation${result.details.join('\n$errorIndentation')}';
}
_printError(
'$indentation${getPackageDescription(package.directory)}$errorDetails');
_printError('$indentation${entry.package.displayName}$errorDetails');
}
}
_printError(failureListFooter);
Expand Down
Loading