| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import 'dart:async'; | |
| import 'dart:io' as io; | |
| import 'package:args/command_runner.dart'; | |
| import 'common.dart'; | |
| import 'pipeline.dart'; | |
| import 'steps/compile_tests_step.dart'; | |
| import 'steps/run_tests_step.dart'; | |
| import 'utils.dart'; | |
| /// Runs build and test steps. | |
| /// | |
| /// This command is designed to be invoked by the LUCI build graph. However, it | |
| /// is also usable locally. | |
| /// | |
| /// Usage: | |
| /// | |
| /// felt run name_of_build_step | |
| class RunCommand extends Command<bool> with ArgUtils<bool> { | |
| RunCommand() { | |
| argParser.addFlag( | |
| 'list', | |
| abbr: 'l', | |
| help: 'Lists all available build steps.', | |
| ); | |
| argParser.addFlag( | |
| 'require-skia-gold', | |
| help: 'Whether we require Skia Gold to be available or not. When this ' | |
| 'flag is true, the tests will fail if Skia Gold is not available.', | |
| ); | |
| argParser.addFlag( | |
| 'wasm', | |
| help: 'Whether the test we are running are compiled to webassembly.' | |
| ); | |
| } | |
| @override | |
| String get name => 'run'; | |
| bool get isWasm => boolArg('wasm'); | |
| bool get isListSteps => boolArg('list'); | |
| /// When running screenshot tests, require Skia Gold to be available and | |
| /// reachable. | |
| bool get requireSkiaGold => boolArg('require-skia-gold'); | |
| @override | |
| String get description => 'Runs a build step.'; | |
| /// Build steps to run, in order specified. | |
| List<String> get stepNames => argResults!.rest; | |
| @override | |
| FutureOr<bool> run() async { | |
| // All available build steps. | |
| final Map<String, PipelineStep> buildSteps = <String, PipelineStep>{ | |
| 'compile_tests': CompileTestsStep(), | |
| for (final String browserName in kAllBrowserNames) | |
| 'run_tests_$browserName': RunTestsStep( | |
| browserName: browserName, | |
| isDebug: false, | |
| isWasm: isWasm, | |
| doUpdateScreenshotGoldens: false, | |
| requireSkiaGold: requireSkiaGold, | |
| overridePathToCanvasKit: null, | |
| ), | |
| }; | |
| if (isListSteps) { | |
| buildSteps.keys.forEach(print); | |
| return true; | |
| } | |
| if (stepNames.isEmpty) { | |
| throw UsageException('No build steps specified.', argParser.usage); | |
| } | |
| final List<String> unrecognizedStepNames = <String>[]; | |
| for (final String stepName in stepNames) { | |
| if (!buildSteps.containsKey(stepName)) { | |
| unrecognizedStepNames.add(stepName); | |
| } | |
| } | |
| if (unrecognizedStepNames.isNotEmpty) { | |
| io.stderr.writeln( | |
| 'Unknown build steps specified: ${unrecognizedStepNames.join(', ')}', | |
| ); | |
| return false; | |
| } | |
| final List<PipelineStep> steps = <PipelineStep>[]; | |
| print('Running steps ${steps.join(', ')}'); | |
| for (final String stepName in stepNames) { | |
| steps.add(buildSteps[stepName]!); | |
| } | |
| final Stopwatch stopwatch = Stopwatch()..start(); | |
| final Pipeline pipeline = Pipeline(steps: steps); | |
| await pipeline.run(); | |
| stopwatch.stop(); | |
| print('Finished running steps in ${stopwatch.elapsedMilliseconds / 1000} seconds.'); | |
| return true; | |
| } | |
| } |