Commit 223f4161 authored by Dan Rubel's avatar Dan Rubel Committed by GitHub

Flutter run with machine output (#6645)

* add flutter run --machine flag
* refactor daemon stdin/out command stream/response
* extract daemon startApp method
* refactor flutter run --machine to call daemon.startApp
parent 1c2be027
......@@ -52,31 +52,14 @@ class DaemonCommand extends FlutterCommand {
Cache.releaseLockEarly();
return appContext.runInZone(() {
Stream<Map<String, dynamic>> commandStream = stdin
.transform(UTF8.decoder)
.transform(const LineSplitter())
.where((String line) => line.startsWith('[{') && line.endsWith('}]'))
.map((String line) {
line = line.substring(1, line.length - 1);
return JSON.decode(line);
});
Daemon daemon = new Daemon(commandStream, (Map<String, dynamic> command) {
stdout.writeln('[${JSON.encode(command, toEncodable: _jsonEncodeObject)}]');
}, daemonCommand: this, notifyingLogger: notifyingLogger);
Daemon daemon = new Daemon(
stdinCommandStream, stdoutCommandResponse,
daemonCommand: this, notifyingLogger: notifyingLogger);
return daemon.onExit;
}, onError: _handleError);
}
dynamic _jsonEncodeObject(dynamic object) {
if (object is Device)
return _deviceToMap(object);
if (object is OperationResult)
return _operationResultToMap(object);
return object;
}
dynamic _handleError(dynamic error, StackTrace stackTrace) {
printError('Error from flutter daemon: $error', stackTrace);
return null;
......@@ -306,6 +289,23 @@ class AppDomain extends Domain {
throw "'$projectDirectory' does not exist";
BuildMode buildMode = getBuildModeForName(mode) ?? BuildMode.debug;
AppInstance app = startApp(
device, projectDirectory, target, route,
buildMode, startPaused, enableHotReload);
return <String, dynamic>{
'appId': app.id,
'deviceId': device.id,
'directory': projectDirectory,
'supportsRestart': isRestartSupported(enableHotReload, device)
};
}
AppInstance startApp(
Device device, String projectDirectory, String target, String route,
BuildMode buildMode, bool startPaused, bool enableHotReload) {
DebuggingOptions options;
switch (buildMode) {
......@@ -342,14 +342,12 @@ class AppDomain extends Domain {
);
}
bool supportsRestart = enableHotReload ? device.supportsHotMode : device.supportsRestart;
AppInstance app = new AppInstance(_getNewAppId(), runner);
_apps.add(app);
_sendAppEvent(app, 'start', <String, dynamic>{
'deviceId': deviceId,
'deviceId': device.id,
'directory': projectDirectory,
'supportsRestart': supportsRestart
'supportsRestart': isRestartSupported(enableHotReload, device)
});
Completer<DebugConnectionInfo> connectionInfoCompleter;
......@@ -375,14 +373,12 @@ class AppDomain extends Domain {
});
});
return <String, dynamic>{
'appId': app.id,
'deviceId': deviceId,
'directory': projectDirectory,
'supportsRestart': supportsRestart
};
return app;
}
bool isRestartSupported(bool enableHotReload, Device device) =>
enableHotReload ? device.supportsHotMode : device.supportsRestart;
Future<OperationResult> restart(Map<String, dynamic> args) async {
String appId = _getStringArg(args, 'appId', required: true);
bool fullRestart = _getBoolArg(args, 'fullRestart') ?? false;
......@@ -561,6 +557,27 @@ class DeviceDomain extends Domain {
}
}
Stream<Map<String, dynamic>> get stdinCommandStream => stdin
.transform(UTF8.decoder)
.transform(const LineSplitter())
.where((String line) => line.startsWith('[{') && line.endsWith('}]'))
.map((String line) {
line = line.substring(1, line.length - 1);
return JSON.decode(line);
});
void stdoutCommandResponse(Map<String, dynamic> command) {
stdout.writeln('[${JSON.encode(command, toEncodable: _jsonEncodeObject)}]');
}
dynamic _jsonEncodeObject(dynamic object) {
if (object is Device)
return _deviceToMap(object);
if (object is OperationResult)
return _operationResultToMap(object);
return object;
}
Map<String, dynamic> _deviceToMap(Device device) {
return <String, dynamic>{
'id': device.id,
......
......@@ -19,6 +19,7 @@ import '../resident_runner.dart';
import '../run.dart';
import '../runner/flutter_command.dart';
import 'build_apk.dart';
import 'daemon.dart';
import 'install.dart';
import 'trace.dart';
......@@ -61,6 +62,10 @@ class RunCommand extends RunCommandBase {
argParser.addOption('use-application-binary',
hide: !verboseHelp,
help: 'Specify a pre-built application binary to use when running.');
argParser.addFlag('machine',
hide: !verboseHelp,
help: 'Handle machine structured JSON command input\n'
'and provide output and progress in machine friendly format.');
usesPubOption();
// Option to enable hot reloading.
......@@ -79,7 +84,6 @@ class RunCommand extends RunCommandBase {
'and SIGUSR2 to trigger a full restart.'
);
// Hidden option to enable a benchmarking mode. This will run the given
// application, measure the startup time and the app restart time, write the
// results out to 'refresh_benchmark.json', and exit. This flag is intended
......@@ -153,8 +157,23 @@ class RunCommand extends RunCommandBase {
@override
Future<int> runCommand() async {
int debugPort;
Cache.releaseLockEarly();
// Enable hot mode by default if `--no-hot` was not passed and we are in
// debug mode.
final bool hotMode = shouldUseHotMode();
if (argResults['machine']) {
Daemon daemon = new Daemon(stdinCommandStream, stdoutCommandResponse,
notifyingLogger: new NotifyingLogger());
AppInstance app = daemon.appDomain.startApp(
device, Directory.current.path, targetFile, route,
getBuildMode(), argResults['start-paused'], hotMode);
return app.runner.waitForAppToFinish();
}
int debugPort;
if (argResults['debug-port'] != null) {
try {
debugPort = int.parse(argResults['debug-port']);
......@@ -181,12 +200,6 @@ class RunCommand extends RunCommandBase {
);
}
Cache.releaseLockEarly();
// Enable hot mode by default if ``--no-hot` was not passed and we are in
// debug mode.
final bool hotMode = shouldUseHotMode();
if (hotMode) {
if (!device.supportsHotMode) {
printError('Hot mode is not supported by this device. '
......@@ -207,7 +220,7 @@ class RunCommand extends RunCommandBase {
device,
target: targetFile,
debuggingOptions: options,
benchmarkMode: argResults['benchmark'],
benchmarkMode: argResults['benchmark']
);
} else {
runner = new RunAndStayResident(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment