| // Copyright 2016 The Chromium 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:convert'; | |
| import 'dart:io'; | |
| import 'package:args/args.dart'; | |
| import 'package:path/path.dart' as path; | |
| import 'package:flutter_devicelab/framework/manifest.dart'; | |
| import 'package:flutter_devicelab/framework/runner.dart'; | |
| import 'package:flutter_devicelab/framework/utils.dart'; | |
| List<String> _taskNames = <String>[]; | |
| /// Runs tasks. | |
| /// | |
| /// The tasks are chosen depending on the command-line options | |
| /// (see [_argParser]). | |
| Future<void> main(List<String> rawArgs) async { | |
| ArgResults args; | |
| try { | |
| args = _argParser.parse(rawArgs); | |
| } on FormatException catch (error) { | |
| stderr.writeln('${error.message}\n'); | |
| stderr.writeln('Usage:\n'); | |
| stderr.writeln(_argParser.usage); | |
| exitCode = 1; | |
| return null; | |
| } | |
| if (!args.wasParsed('task')) { | |
| if (args.wasParsed('stage')) { | |
| final String stageName = args['stage']; | |
| final List<ManifestTask> tasks = loadTaskManifest().tasks; | |
| for (ManifestTask task in tasks) { | |
| if (task.stage == stageName) | |
| _taskNames.add(task.name); | |
| } | |
| } else if (args.wasParsed('all')) { | |
| final List<ManifestTask> tasks = loadTaskManifest().tasks; | |
| for (ManifestTask task in tasks) { | |
| _taskNames.add(task.name); | |
| } | |
| } | |
| } | |
| if (_taskNames.isEmpty) { | |
| stderr.writeln('Failed to find tasks to run based on supplied options.'); | |
| exitCode = 1; | |
| return null; | |
| } | |
| final bool silent = args['silent']; | |
| for (String taskName in _taskNames) { | |
| section('Running task "$taskName"'); | |
| final Map<String, dynamic> result = await runTask(taskName, silent: silent); | |
| if (!result['success']) | |
| exitCode = 1; | |
| print('Task result:'); | |
| print(const JsonEncoder.withIndent(' ').convert(result)); | |
| section('Finished task "$taskName"'); | |
| } | |
| } | |
| /// Command-line options for the `run.dart` command. | |
| final ArgParser _argParser = ArgParser() | |
| ..addMultiOption( | |
| 'task', | |
| abbr: 't', | |
| splitCommas: true, | |
| help: 'Either:\n' | |
| ' - the name of a task defined in manifest.yaml. Example: complex_layout__start_up.\n' | |
| ' - the path to a Dart file corresponding to a task, which resides in bin/tasks. Example: bin/tasks/complex_layout__start_up.dart.\n' | |
| '\n' | |
| 'This option may be repeated to specify multiple tasks.', | |
| callback: (List<String> value) { | |
| for (String nameOrPath in value) { | |
| final List<String> fragments = path.split(nameOrPath); | |
| final bool isDartFile = fragments.last.endsWith('.dart'); | |
| if (fragments.length == 1 && !isDartFile) { | |
| // Not a path | |
| _taskNames.add(nameOrPath); | |
| } else if (!isDartFile || fragments.length != 3 || !_listsEqual(<String>['bin', 'tasks'], fragments.take(2).toList())) { | |
| // Unsupported executable location | |
| throw FormatException('Invalid value for option -t (--task): $nameOrPath'); | |
| } else { | |
| _taskNames.add(path.withoutExtension(fragments.last)); | |
| } | |
| } | |
| }, | |
| ) | |
| ..addOption( | |
| 'stage', | |
| abbr: 's', | |
| help: 'Name of the stage. Runs all tasks for that stage. ' | |
| 'The tasks and their stages are read from manifest.yaml.', | |
| ) | |
| ..addFlag( | |
| 'all', | |
| abbr: 'a', | |
| help: 'Runs all tasks defined in manifest.yaml.', | |
| ) | |
| ..addMultiOption( | |
| 'test', | |
| hide: true, | |
| splitCommas: true, | |
| callback: (List<String> value) { | |
| if (value.isNotEmpty) { | |
| throw const FormatException( | |
| 'Invalid option --test. Did you mean --task (-t)?', | |
| ); | |
| } | |
| }, | |
| ) | |
| ..addFlag( | |
| 'silent', | |
| negatable: true, | |
| defaultsTo: false, | |
| ); | |
| bool _listsEqual(List<dynamic> a, List<dynamic> b) { | |
| if (a.length != b.length) | |
| return false; | |
| for (int i = 0; i < a.length; i++) { | |
| if (a[i] != b[i]) | |
| return false; | |
| } | |
| return true; | |
| } |