@@ -22,6 +22,10 @@ enum RunState {
2222 /// The command was skipped for the package.
2323 skipped,
2424
25+ /// The command was skipped for the package because it was explicitly excluded
26+ /// in the command arguments.
27+ excluded,
28+
2529 /// The command failed for the package.
2630 failed,
2731}
@@ -35,6 +39,9 @@ class PackageResult {
3539 PackageResult .skip (String reason)
3640 : this ._(RunState .skipped, < String > [reason]);
3741
42+ /// A run that was excluded by the command invocation.
43+ PackageResult .exclude () : this ._(RunState .excluded);
44+
3845 /// A run that failed.
3946 ///
4047 /// If [errors] are provided, they will be listed in the summary, otherwise
@@ -70,13 +77,14 @@ abstract class PackageLoopingCommand extends PluginCommand {
7077 processRunner: processRunner, platform: platform, gitDir: gitDir);
7178
7279 /// Packages that had at least one [logWarning] call.
73- final Set <Directory > _packagesWithWarnings = < Directory > {};
80+ final Set <PackageEnumerationEntry > _packagesWithWarnings =
81+ < PackageEnumerationEntry > {};
7482
7583 /// Number of warnings that happened outside of a [runForPackage] call.
7684 int _otherWarningCount = 0 ;
7785
7886 /// The package currently being run by [runForPackage] .
79- Directory ? _currentPackage;
87+ PackageEnumerationEntry ? _currentPackage;
8088
8189 /// Called during [run] before any calls to [runForPackage] . This provides an
8290 /// opportunity to fail early if the command can't be run (e.g., because the
@@ -215,15 +223,24 @@ abstract class PackageLoopingCommand extends PluginCommand {
215223
216224 await initializeRun ();
217225
218- final List <Directory > packages = includeSubpackages
219- ? await getPackages ( ).toList ()
220- : await getPlugins ( ).toList ();
226+ final List <PackageEnumerationEntry > packages = includeSubpackages
227+ ? await getTargetPackagesAndSubpackages (filterExcluded : false ).toList ()
228+ : await getTargetPackages (filterExcluded : false ).toList ();
221229
222- final Map <Directory , PackageResult > results = < Directory , PackageResult > {};
223- for (final Directory package in packages) {
230+ final Map <PackageEnumerationEntry , PackageResult > results =
231+ < PackageEnumerationEntry , PackageResult > {};
232+ for (final PackageEnumerationEntry package in packages) {
224233 _currentPackage = package;
225234 _printPackageHeading (package);
226- final PackageResult result = await runForPackage (package);
235+
236+ // Command implementations should never see excluded packages; they are
237+ // included at this level only for logging.
238+ if (package.excluded) {
239+ results[package] = PackageResult .exclude ();
240+ continue ;
241+ }
242+
243+ final PackageResult result = await runForPackage (package.directory);
227244 if (result.state == RunState .skipped) {
228245 final String message =
229246 '${indentation }SKIPPING: ${result .details .first }' ;
@@ -266,33 +283,47 @@ abstract class PackageLoopingCommand extends PluginCommand {
266283 /// Something is always printed to make it easier to distinguish between
267284 /// a command running for a package and producing no output, and a command
268285 /// not having been run for a package.
269- void _printPackageHeading (Directory package) {
270- String heading = 'Running for ${getPackageDescription (package )}' ;
286+ void _printPackageHeading (PackageEnumerationEntry package) {
287+ final String packageDisplayName = getPackageDescription (package.directory);
288+ String heading = package.excluded
289+ ? 'Not running for $packageDisplayName ; excluded'
290+ : 'Running for $packageDisplayName ' ;
271291 if (hasLongOutput) {
272292 heading = '''
273293
274294============================================================
275295|| $heading
276296============================================================
277297''' ;
278- } else {
298+ } else if ( ! package.excluded) {
279299 heading = '$heading ...' ;
280300 }
281- captureOutput ? print (heading) : print (Colorize (heading)..cyan ());
301+ if (captureOutput) {
302+ print (heading);
303+ } else {
304+ final Colorize colorizeHeading = Colorize (heading);
305+ print (package.excluded
306+ ? colorizeHeading.darkGray ()
307+ : colorizeHeading.cyan ());
308+ }
282309 }
283310
284311 /// Prints a summary of packges run, packages skipped, and warnings.
285- void _printRunSummary (
286- List < Directory > packages, Map <Directory , PackageResult > results) {
287- final Set <Directory > skippedPackages = results.entries
288- .where ((MapEntry <Directory , PackageResult > entry) =>
312+ void _printRunSummary (List < PackageEnumerationEntry > packages,
313+ Map <PackageEnumerationEntry , PackageResult > results) {
314+ final Set <PackageEnumerationEntry > skippedPackages = results.entries
315+ .where ((MapEntry <PackageEnumerationEntry , PackageResult > entry) =>
289316 entry.value.state == RunState .skipped)
290- .map ((MapEntry <Directory , PackageResult > entry) => entry.key)
317+ .map ((MapEntry <PackageEnumerationEntry , PackageResult > entry) =>
318+ entry.key)
291319 .toSet ();
292- final int skipCount = skippedPackages.length;
320+ final int skipCount = skippedPackages.length +
321+ packages
322+ .where ((PackageEnumerationEntry package) => package.excluded)
323+ .length;
293324 // Split the warnings into those from packages that ran, and those that
294325 // were skipped.
295- final Set <Directory > _skippedPackagesWithWarnings =
326+ final Set <PackageEnumerationEntry > _skippedPackagesWithWarnings =
296327 _packagesWithWarnings.intersection (skippedPackages);
297328 final int skippedWarningCount = _skippedPackagesWithWarnings.length;
298329 final int runWarningCount =
@@ -318,14 +349,17 @@ abstract class PackageLoopingCommand extends PluginCommand {
318349
319350 /// Prints a one-line-per-package overview of the run results for each
320351 /// package.
321- void _printPerPackageRunOverview (List <Directory > packages,
322- {required Set <Directory > skipped}) {
352+ void _printPerPackageRunOverview (List <PackageEnumerationEntry > packages,
353+ {required Set <PackageEnumerationEntry > skipped}) {
323354 print ('Run overview:' );
324- for (final Directory package in packages) {
355+ for (final PackageEnumerationEntry package in packages) {
325356 final bool hadWarning = _packagesWithWarnings.contains (package);
326357 Styles style;
327358 String summary;
328- if (skipped.contains (package)) {
359+ if (package.excluded) {
360+ summary = 'excluded' ;
361+ style = Styles .DARK_GRAY ;
362+ } else if (skipped.contains (package)) {
329363 summary = 'skipped' ;
330364 style = hadWarning ? Styles .LIGHT_YELLOW : Styles .DARK_GRAY ;
331365 } else {
@@ -339,17 +373,17 @@ abstract class PackageLoopingCommand extends PluginCommand {
339373 if (! captureOutput) {
340374 summary = (Colorize (summary)..apply (style)).toString ();
341375 }
342- print (' ${getPackageDescription (package )} - $summary ' );
376+ print (' ${getPackageDescription (package . directory )} - $summary ' );
343377 }
344378 print ('' );
345379 }
346380
347381 /// Prints a summary of all of the failures from [results] .
348- void _printFailureSummary (
349- List < Directory > packages, Map <Directory , PackageResult > results) {
382+ void _printFailureSummary (List < PackageEnumerationEntry > packages,
383+ Map <PackageEnumerationEntry , PackageResult > results) {
350384 const String indentation = ' ' ;
351385 _printError (failureListHeader);
352- for (final Directory package in packages) {
386+ for (final PackageEnumerationEntry package in packages) {
353387 final PackageResult result = results[package]! ;
354388 if (result.state == RunState .failed) {
355389 final String errorIndentation = indentation * 2 ;
@@ -359,7 +393,7 @@ abstract class PackageLoopingCommand extends PluginCommand {
359393 ':\n $errorIndentation ${result .details .join ('\n $errorIndentation ' )}' ;
360394 }
361395 _printError (
362- '$indentation ${getPackageDescription (package )}$errorDetails ' );
396+ '$indentation ${getPackageDescription (package . directory )}$errorDetails ' );
363397 }
364398 }
365399 _printError (failureListFooter);
0 commit comments