| // Copyright 2014 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 'package:file/file.dart' show File; |
| |
| import 'globals.dart'; |
| import 'proto/conductor_state.pb.dart' as pb; |
| import 'repository.dart'; |
| import 'state.dart'; |
| import 'stdio.dart' show Stdio; |
| |
| /// Interface for shared functionality across all sub-commands. |
| /// |
| /// Different frontends (e.g. CLI vs desktop) can share [Context]s, although |
| /// methods for capturing user interaction may be overridden. |
| abstract class Context { |
| const Context({ |
| required this.checkouts, |
| required this.stateFile, |
| }); |
| |
| final Checkouts checkouts; |
| final File stateFile; |
| Stdio get stdio => checkouts.stdio; |
| |
| /// Confirm an action with the user before proceeding. |
| /// |
| /// The default implementation reads from STDIN. This can be overriden in UI |
| /// implementations that capture user interaction differently. |
| Future<bool> prompt(String message) async { |
| stdio.write('${message.trim()} (y/n) '); |
| final String response = stdio.readLineSync().trim(); |
| final String firstChar = response[0].toUpperCase(); |
| if (firstChar == 'Y') { |
| return true; |
| } |
| if (firstChar == 'N') { |
| return false; |
| } |
| throw ConductorException( |
| 'Unknown user input (expected "y" or "n"): $response', |
| ); |
| } |
| |
| /// Save the release's [state]. |
| /// |
| /// This can be overridden by frontends that may not persist the state to |
| /// disk, and/or may need to call additional update hooks each time the state |
| /// is updated. |
| void updateState(pb.ConductorState state, [List<String> logs = const <String>[]]) { |
| writeStateToFile(stateFile, state, logs); |
| } |
| } |