Commit bec4a6c7 authored by Devon Carew's avatar Devon Carew Committed by GitHub

updates for flutter run --machine (#7183)

* have flutter run --machine log to stdout

* add a test

* add docs; fix type annotation lint
parent 211fefc2
...@@ -76,7 +76,8 @@ typedef Future<dynamic> CommandHandler(Map<String, dynamic> args); ...@@ -76,7 +76,8 @@ typedef Future<dynamic> CommandHandler(Map<String, dynamic> args);
class Daemon { class Daemon {
Daemon(Stream<Map<String, dynamic>> commandStream, this.sendCommand, { Daemon(Stream<Map<String, dynamic>> commandStream, this.sendCommand, {
this.daemonCommand, this.daemonCommand,
this.notifyingLogger this.notifyingLogger,
this.logToStdout: false
}) { }) {
// Set up domains. // Set up domains.
_registerDomain(daemonDomain = new DaemonDomain(this)); _registerDomain(daemonDomain = new DaemonDomain(this));
...@@ -100,6 +101,7 @@ class Daemon { ...@@ -100,6 +101,7 @@ class Daemon {
final DispatchCommand sendCommand; final DispatchCommand sendCommand;
final DaemonCommand daemonCommand; final DaemonCommand daemonCommand;
final NotifyingLogger notifyingLogger; final NotifyingLogger notifyingLogger;
final bool logToStdout;
final Completer<int> _onExitCompleter = new Completer<int>(); final Completer<int> _onExitCompleter = new Completer<int>();
final Map<String, Domain> _domainMap = <String, Domain>{}; final Map<String, Domain> _domainMap = <String, Domain>{};
...@@ -226,17 +228,29 @@ class DaemonDomain extends Domain { ...@@ -226,17 +228,29 @@ class DaemonDomain extends Domain {
registerHandler('shutdown', shutdown); registerHandler('shutdown', shutdown);
_subscription = daemon.notifyingLogger.onMessage.listen((LogMessage message) { _subscription = daemon.notifyingLogger.onMessage.listen((LogMessage message) {
if (message.stackTrace != null) { if (daemon.logToStdout) {
sendEvent('daemon.logMessage', <String, dynamic>{ if (message.level == 'status') {
'level': message.level, // We use `print()` here instead of `stdout.writeln()` in order to
'message': message.message, // capture the print output for testing.
'stackTrace': message.stackTrace.toString() print(message.message);
}); } else if (message.level == 'error') {
stderr.writeln(message.message);
if (message.stackTrace != null)
stderr.writeln(message.stackTrace.toString().trimRight());
}
} else { } else {
sendEvent('daemon.logMessage', <String, dynamic>{ if (message.stackTrace != null) {
'level': message.level, sendEvent('daemon.logMessage', <String, dynamic>{
'message': message.message 'level': message.level,
}); 'message': message.message,
'stackTrace': message.stackTrace.toString()
});
} else {
sendEvent('daemon.logMessage', <String, dynamic>{
'level': message.level,
'message': message.message
});
}
} }
}); });
} }
...@@ -345,7 +359,7 @@ class AppDomain extends Domain { ...@@ -345,7 +359,7 @@ class AppDomain extends Domain {
); );
} }
AppInstance app = new AppInstance(_getNewAppId(), runner); AppInstance app = new AppInstance(_getNewAppId(), runner: runner, logToStdout: daemon.logToStdout);
_apps.add(app); _apps.add(app);
_sendAppEvent(app, 'start', <String, dynamic>{ _sendAppEvent(app, 'start', <String, dynamic>{
'deviceId': device.id, 'deviceId': device.id,
...@@ -652,10 +666,11 @@ class NotifyingLogger extends Logger { ...@@ -652,10 +666,11 @@ class NotifyingLogger extends Logger {
/// A running application, started by this daemon. /// A running application, started by this daemon.
class AppInstance { class AppInstance {
AppInstance(this.id, [this.runner]); AppInstance(this.id, { this.runner, this.logToStdout = false });
final String id; final String id;
final ResidentRunner runner; final ResidentRunner runner;
final bool logToStdout;
_AppRunLogger _logger; _AppRunLogger _logger;
...@@ -671,7 +686,7 @@ class AppInstance { ...@@ -671,7 +686,7 @@ class AppInstance {
dynamic _runInZone(AppDomain domain, dynamic method()) { dynamic _runInZone(AppDomain domain, dynamic method()) {
if (_logger == null) if (_logger == null)
_logger = new _AppRunLogger(domain, this); _logger = new _AppRunLogger(domain, this, logToStdout: logToStdout);
AppContext appContext = new AppContext(); AppContext appContext = new AppContext();
appContext.setVariable(Logger, _logger); appContext.setVariable(Logger, _logger);
...@@ -681,31 +696,42 @@ class AppInstance { ...@@ -681,31 +696,42 @@ class AppInstance {
/// A [Logger] which sends log messages to a listening daemon client. /// A [Logger] which sends log messages to a listening daemon client.
class _AppRunLogger extends Logger { class _AppRunLogger extends Logger {
_AppRunLogger(this.domain, this.app); _AppRunLogger(this.domain, this.app, { this.logToStdout: false });
AppDomain domain; AppDomain domain;
final AppInstance app; final AppInstance app;
final bool logToStdout;
int _nextProgressId = 0; int _nextProgressId = 0;
@override @override
void printError(String message, [StackTrace stackTrace]) { void printError(String message, [StackTrace stackTrace]) {
if (stackTrace != null) { if (logToStdout) {
_sendLogEvent(<String, dynamic>{ stderr.writeln(message);
'log': message, if (stackTrace != null)
'stackTrace': stackTrace.toString(), stderr.writeln(stackTrace.toString().trimRight());
'error': true
});
} else { } else {
_sendLogEvent(<String, dynamic>{ if (stackTrace != null) {
'log': message, _sendLogEvent(<String, dynamic>{
'error': true 'log': message,
}); 'stackTrace': stackTrace.toString(),
'error': true
});
} else {
_sendLogEvent(<String, dynamic>{
'log': message,
'error': true
});
}
} }
} }
@override @override
void printStatus(String message, { bool emphasis: false, bool newline: true, String ansiAlternative }) { void printStatus(String message, { bool emphasis: false, bool newline: true, String ansiAlternative }) {
_sendLogEvent(<String, dynamic>{ 'log': message }); if (logToStdout) {
print(message);
} else {
_sendLogEvent(<String, dynamic>{ 'log': message });
}
} }
@override @override
......
...@@ -170,13 +170,14 @@ class RunCommand extends RunCommandBase { ...@@ -170,13 +170,14 @@ class RunCommand extends RunCommandBase {
if (argResults['machine']) { if (argResults['machine']) {
Daemon daemon = new Daemon(stdinCommandStream, stdoutCommandResponse, Daemon daemon = new Daemon(stdinCommandStream, stdoutCommandResponse,
notifyingLogger: new NotifyingLogger()); notifyingLogger: new NotifyingLogger(), logToStdout: true);
AppInstance app = daemon.appDomain.startApp( AppInstance app = daemon.appDomain.startApp(
device, Directory.current.path, targetFile, route, device, Directory.current.path, targetFile, route,
getBuildMode(), argResults['start-paused'], hotMode); getBuildMode(), argResults['start-paused'], hotMode);
int result = await app.runner.waitForAppToFinish(); int result = await app.runner.waitForAppToFinish();
if (result != 0) if (result != 0)
throwToolExit(null, exitCode: result); throwToolExit(null, exitCode: result);
return null;
} }
int debugPort; int debugPort;
......
...@@ -85,6 +85,30 @@ void main() { ...@@ -85,6 +85,30 @@ void main() {
}); });
}); });
_testUsingContext('daemon.logMessage logToStdout', () async {
StringBuffer buffer = new StringBuffer();
await runZoned(() async {
return appContext.runInZone(() async {
StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
daemon = new Daemon(
commands.stream,
(Map<String, dynamic> result) => responses.add(result),
notifyingLogger: notifyingLogger,
logToStdout: true
);
printStatus('daemon.logMessage test');
// Service the event loop.
await new Future<Null>.value();
});
}, zoneSpecification: new ZoneSpecification(print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
buffer.writeln(line);
}));
expect(buffer.toString().trim(), 'daemon.logMessage test');
});
_testUsingContext('daemon.shutdown', () async { _testUsingContext('daemon.shutdown', () async {
StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>(); StreamController<Map<String, dynamic>> commands = new StreamController<Map<String, dynamic>>();
StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>(); StreamController<Map<String, dynamic>> responses = new StreamController<Map<String, dynamic>>();
......
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