2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ import 'dart:async' ;
6
+
5
7
import 'package:colorize/colorize.dart' ;
6
8
import 'package:file/file.dart' ;
7
9
import 'package:git/git.dart' ;
@@ -90,6 +92,10 @@ abstract class PackageLoopingCommand extends PluginCommand {
90
92
/// opportunity to do any cleanup of run-level state.
91
93
Future <void > completeRun () async {}
92
94
95
+ /// If [captureOutput] , this is called just before exiting with all captured
96
+ /// [output] .
97
+ Future <void > handleCapturedOutput (List <String > output) async {}
98
+
93
99
/// Whether or not the output (if any) of [runForPackage] is long, or short.
94
100
///
95
101
/// This changes the logging that happens at the start of each package's
@@ -120,6 +126,14 @@ abstract class PackageLoopingCommand extends PluginCommand {
120
126
/// context.
121
127
String get failureListFooter => 'See above for full details.' ;
122
128
129
+ /// If true, all printing (including the summary) will be redirected to a
130
+ /// buffer, and provided in a call to [handleCapturedOutput] at the end of
131
+ /// the run.
132
+ ///
133
+ /// Capturing output will disable any colorizing of output from this base
134
+ /// class.
135
+ bool get captureOutput => false ;
136
+
123
137
// ----------------------------------------
124
138
125
139
/// Logs that a warning occurred, and prints `warningMessage` in yellow.
@@ -162,6 +176,26 @@ abstract class PackageLoopingCommand extends PluginCommand {
162
176
163
177
@override
164
178
Future <void > run () async {
179
+ bool succeeded;
180
+ if (captureOutput) {
181
+ final List <String > output = < String > [];
182
+ final ZoneSpecification logSwitchSpecification = ZoneSpecification (
183
+ print: (Zone self, ZoneDelegate parent, Zone zone, String message) {
184
+ output.add (message);
185
+ });
186
+ succeeded = await runZoned <Future <bool >>(_runInternal,
187
+ zoneSpecification: logSwitchSpecification);
188
+ await handleCapturedOutput (output);
189
+ } else {
190
+ succeeded = await _runInternal ();
191
+ }
192
+
193
+ if (! succeeded) {
194
+ throw ToolExit (exitCommandFoundErrors);
195
+ }
196
+ }
197
+
198
+ Future <bool > _runInternal () async {
165
199
_packagesWithWarnings.clear ();
166
200
_otherWarningCount = 0 ;
167
201
_currentPackage = null ;
@@ -178,28 +212,39 @@ abstract class PackageLoopingCommand extends PluginCommand {
178
212
_printPackageHeading (package);
179
213
final PackageResult result = await runForPackage (package);
180
214
if (result.state == RunState .skipped) {
181
- print (Colorize ('${indentation }SKIPPING: ${result .details .first }' )
182
- ..darkGray ());
215
+ final String message =
216
+ '${indentation }SKIPPING: ${result .details .first }' ;
217
+ captureOutput ? print (message) : print (Colorize (message)..darkGray ());
183
218
}
184
219
results[package] = result;
185
220
}
186
221
_currentPackage = null ;
187
222
188
223
completeRun ();
189
224
225
+ print ('\n ' );
190
226
// If there were any errors reported, summarize them and exit.
191
227
if (results.values
192
228
.any ((PackageResult result) => result.state == RunState .failed)) {
193
229
_printFailureSummary (packages, results);
194
- throw ToolExit (exitCommandFoundErrors) ;
230
+ return false ;
195
231
}
196
232
197
233
// Otherwise, print a summary of what ran for ease of auditing that all the
198
234
// expected tests ran.
199
235
_printRunSummary (packages, results);
200
236
201
237
print ('\n ' );
202
- printSuccess ('No issues found!' );
238
+ _printSuccess ('No issues found!' );
239
+ return true ;
240
+ }
241
+
242
+ void _printSuccess (String message) {
243
+ captureOutput ? print (message) : printSuccess (message);
244
+ }
245
+
246
+ void _printError (String message) {
247
+ captureOutput ? print (message) : printError (message);
203
248
}
204
249
205
250
/// Prints the status message indicating that the command is being run for
@@ -220,7 +265,7 @@ abstract class PackageLoopingCommand extends PluginCommand {
220
265
} else {
221
266
heading = '$heading ...' ;
222
267
}
223
- print (Colorize (heading)..cyan ());
268
+ captureOutput ? print (heading) : print (Colorize (heading)..cyan ());
224
269
}
225
270
226
271
/// Prints a summary of packges run, packages skipped, and warnings.
@@ -265,19 +310,21 @@ abstract class PackageLoopingCommand extends PluginCommand {
265
310
print ('Run overview:' );
266
311
for (final Directory package in packages) {
267
312
final bool hadWarning = _packagesWithWarnings.contains (package);
268
- Colorize summary;
313
+ Styles style;
314
+ String summary;
269
315
if (skipped.contains (package)) {
270
- if (hadWarning) {
271
- summary = Colorize ('skipped (with warning)' )..lightYellow ();
272
- } else {
273
- summary = Colorize ('skipped' )..darkGray ();
274
- }
316
+ summary = 'skipped' ;
317
+ style = hadWarning ? Styles .LIGHT_YELLOW : Styles .DARK_GRAY ;
275
318
} else {
276
- if (hadWarning) {
277
- summary = Colorize ('ran (with warning)' )..yellow ();
278
- } else {
279
- summary = Colorize ('ran' )..green ();
280
- }
319
+ summary = 'ran' ;
320
+ style = hadWarning ? Styles .YELLOW : Styles .GREEN ;
321
+ }
322
+ if (hadWarning) {
323
+ summary += ' (with warning)' ;
324
+ }
325
+
326
+ if (! captureOutput) {
327
+ summary = (Colorize (summary)..apply (style)).toString ();
281
328
}
282
329
print (' ${getPackageDescription (package )} - $summary ' );
283
330
}
@@ -288,7 +335,7 @@ abstract class PackageLoopingCommand extends PluginCommand {
288
335
void _printFailureSummary (
289
336
List <Directory > packages, Map <Directory , PackageResult > results) {
290
337
const String indentation = ' ' ;
291
- printError (failureListHeader);
338
+ _printError (failureListHeader);
292
339
for (final Directory package in packages) {
293
340
final PackageResult result = results[package]! ;
294
341
if (result.state == RunState .failed) {
@@ -298,10 +345,10 @@ abstract class PackageLoopingCommand extends PluginCommand {
298
345
errorDetails =
299
346
':\n $errorIndentation ${result .details .join ('\n $errorIndentation ' )}' ;
300
347
}
301
- printError (
348
+ _printError (
302
349
'$indentation ${getPackageDescription (package )}$errorDetails ' );
303
350
}
304
351
}
305
- printError (failureListFooter);
352
+ _printError (failureListFooter);
306
353
}
307
354
}
0 commit comments