[flutter_conductor] Rewrite writeStateToFile to be in an overidable method. (#93171)

This commit is contained in:
Christopher Fujino 2021-11-08 12:13:04 -08:00 committed by GitHub
parent 223f8ed68b
commit 6bc33812ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 29 deletions

View File

@ -48,12 +48,20 @@ class NextCommand extends Command<void> {
@override @override
Future<void> run() async { Future<void> run() async {
final File stateFile = checkouts.fileSystem.file(argResults![kStateOption]);
if (!stateFile.existsSync()) {
throw ConductorException(
'No persistent state file found at ${stateFile.path}.',
);
}
final pb.ConductorState state = state_import.readStateFromFile(stateFile);
await NextContext( await NextContext(
autoAccept: argResults![kYesFlag] as bool, autoAccept: argResults![kYesFlag] as bool,
checkouts: checkouts, checkouts: checkouts,
force: argResults![kForceFlag] as bool, force: argResults![kForceFlag] as bool,
stateFile: checkouts.fileSystem.file(argResults![kStateOption]), stateFile: stateFile,
).run(); ).run(state);
} }
} }
@ -74,20 +82,12 @@ class NextContext {
final Checkouts checkouts; final Checkouts checkouts;
final File stateFile; final File stateFile;
Future<void> run() async { Future<void> run(pb.ConductorState state) async {
final Stdio stdio = checkouts.stdio; final Stdio stdio = checkouts.stdio;
const List<CherrypickState> finishedStates = <CherrypickState>[ const List<CherrypickState> finishedStates = <CherrypickState>[
CherrypickState.COMPLETED, CherrypickState.COMPLETED,
CherrypickState.ABANDONED, CherrypickState.ABANDONED,
]; ];
if (!stateFile.existsSync()) {
throw ConductorException(
'No persistent state file found at ${stateFile.path}.',
);
}
final pb.ConductorState state = readStateFromFile(stateFile);
switch (state.currentPhase) { switch (state.currentPhase) {
case pb.ReleasePhase.APPLY_ENGINE_CHERRYPICKS: case pb.ReleasePhase.APPLY_ENGINE_CHERRYPICKS:
final Remote upstream = Remote( final Remote upstream = Remote(
@ -149,7 +149,7 @@ class NextContext {
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
return; return;
} }
} }
@ -175,7 +175,7 @@ class NextContext {
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
return; return;
} }
} }
@ -284,7 +284,7 @@ class NextContext {
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
return; return;
} }
} }
@ -319,7 +319,7 @@ class NextContext {
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
return; return;
} }
} }
@ -354,7 +354,7 @@ class NextContext {
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
return; return;
} }
} }
@ -377,7 +377,7 @@ class NextContext {
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
return; return;
} }
} }
@ -390,13 +390,17 @@ class NextContext {
state.currentPhase = nextPhase; state.currentPhase = nextPhase;
stdio.printStatus(state_import.phaseInstructions(state)); stdio.printStatus(state_import.phaseInstructions(state));
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
} }
/// Persist the state to a file. /// 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.
@visibleForOverriding @visibleForOverriding
void writeStateToFile(File file, pb.ConductorState state, [List<String> logs = const <String>[]]) { void updateState(pb.ConductorState state, [List<String> logs = const <String>[]]) {
state_import.writeStateToFile(file, state, logs); state_import.writeStateToFile(stateFile, state, logs);
} }
@visibleForTesting @visibleForTesting
@ -414,8 +418,4 @@ class NextContext {
'Unknown user input (expected "y" or "n"): $response', 'Unknown user input (expected "y" or "n"): $response',
); );
} }
/// Read the state from a file.
@visibleForOverriding
pb.ConductorState readStateFromFile(File file) => state_import.readStateFromFile(file);
} }

View File

@ -6,6 +6,7 @@ import 'package:args/args.dart';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
import 'package:meta/meta.dart' show visibleForOverriding;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
@ -14,7 +15,7 @@ import './globals.dart';
import './proto/conductor_state.pb.dart' as pb; import './proto/conductor_state.pb.dart' as pb;
import './proto/conductor_state.pbenum.dart' show ReleasePhase; import './proto/conductor_state.pbenum.dart' show ReleasePhase;
import './repository.dart'; import './repository.dart';
import './state.dart'; import './state.dart' as state_import;
import './stdio.dart'; import './stdio.dart';
import './version.dart'; import './version.dart';
@ -39,7 +40,7 @@ class StartCommand extends Command<void> {
processManager = checkouts.processManager, processManager = checkouts.processManager,
fileSystem = checkouts.fileSystem, fileSystem = checkouts.fileSystem,
stdio = checkouts.stdio { stdio = checkouts.stdio {
final String defaultPath = defaultStateFilePath(platform); final String defaultPath = state_import.defaultStateFilePath(platform);
argParser.addOption( argParser.addOption(
kCandidateOption, kCandidateOption,
help: 'The candidate branch the release will be based on.', help: 'The candidate branch the release will be based on.',
@ -401,9 +402,19 @@ class StartContext {
stdio.printTrace('Writing state to file ${stateFile.path}...'); stdio.printTrace('Writing state to file ${stateFile.path}...');
writeStateToFile(stateFile, state, stdio.logs); updateState(state, stdio.logs);
stdio.printStatus(presentState(state)); stdio.printStatus(state_import.presentState(state));
}
/// 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.
@visibleForOverriding
void updateState(pb.ConductorState state, List<String> logs) {
state_import.writeStateToFile(stateFile, state, logs);
} }
// To minimize merge conflicts, sort the commits by rev-list order. // To minimize merge conflicts, sort the commits by rev-list order.