Commit a33b70ed authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Clean up 'flutter run' output. (#6610)

Fixes #4166.
Fixes #5120.
Fixes #5399.
Fixes #6507.
parent c8878785
......@@ -269,14 +269,16 @@ class AndroidDevice extends Device {
return true;
}
Future<Null> _forwardPort(String service, int devicePort, int port) async {
Future<int> _forwardPort(String service, int devicePort, int port) async {
try {
// Set up port forwarding for observatory.
port = await portForwarder.forward(devicePort, hostPort: port);
printStatus('$service listening on http://127.0.0.1:$port');
printTrace('$service listening on http://127.0.0.1:$port');
return port;
} catch (e) {
printError('Unable to forward port $port: $e');
}
return null;
}
Future<LaunchResult> startBundle(AndroidApk apk, String bundlePath, {
......@@ -363,17 +365,17 @@ class AndroidDevice extends Device {
observatoryDevicePort = await observatoryDiscovery.nextPort().timeout(new Duration(seconds: 20));
}
printTrace('observatory port = $observatoryDevicePort');
printTrace('observatory port on device: $observatoryDevicePort');
int observatoryLocalPort = await options.findBestObservatoryPort();
// TODO(devoncarew): Remember the forwarding information (so we can later remove the
// port forwarding).
await _forwardPort(ProtocolDiscovery.kObservatoryService, observatoryDevicePort, observatoryLocalPort);
observatoryLocalPort = await _forwardPort(ProtocolDiscovery.kObservatoryService, observatoryDevicePort, observatoryLocalPort);
int diagnosticLocalPort;
if (diagnosticDevicePort != null) {
printTrace('diagnostic port = $diagnosticDevicePort');
printTrace('diagnostic port on device: $diagnosticDevicePort');
diagnosticLocalPort = await options.findBestDiagnosticPort();
await _forwardPort(ProtocolDiscovery.kDiagnosticService, diagnosticDevicePort, diagnosticLocalPort);
diagnosticLocalPort = await _forwardPort(ProtocolDiscovery.kDiagnosticService, diagnosticDevicePort, diagnosticLocalPort);
}
return new LaunchResult.succeeded(
......@@ -715,8 +717,6 @@ class _AdbLogReader extends DeviceLogReader {
final AndroidDevice device;
bool _lastWasFiltered = false;
StreamController<String> _linesController;
Process _process;
......@@ -757,38 +757,44 @@ class _AdbLogReader extends DeviceLogReader {
}
// 'W/ActivityManager: '
static final RegExp _logFormat = new RegExp(r'^[VDIWEF]\/[^:]+:\s+');
static final RegExp _logFormat = new RegExp(r'^[VDIWEF]\/.{8,}:\s');
static final List<RegExp> _whitelistedTags = <RegExp>[
new RegExp(r'^[VDIWEF]\/flutter[^:]*:\s+', caseSensitive: false),
new RegExp(r'^[IE]\/DartVM[^:]*:\s+'),
new RegExp(r'^[WEF]\/AndroidRuntime:\s+'),
new RegExp(r'^[WEF]\/ActivityManager:\s+'),
new RegExp(r'^[WEF]\/ActivityManager:\s+.*(\bflutter\b|\bdomokit\b|\bsky\b)'),
new RegExp(r'^[WEF]\/System\.err:\s+'),
new RegExp(r'^[F]\/[\S^:]+:\s+')
];
// we default to true in case none of the log lines match
bool _acceptedLastLine = true;
void _onLine(String line) {
if (_logFormat.hasMatch(line)) {
// Filter out some noisy ActivityManager notifications.
if (line.startsWith('W/ActivityManager: getRunningAppProcesses'))
return;
// Filter on approved names and levels.
for (RegExp regex in _whitelistedTags) {
if (regex.hasMatch(line)) {
_lastWasFiltered = false;
_acceptedLastLine = true;
_linesController.add(line);
return;
}
}
_lastWasFiltered = true;
_acceptedLastLine = false;
} else if (line == '--------- beginning of system' ||
line == '--------- beginning of main' ) {
// hide the ugly adb logcat log boundaries at the start
_acceptedLastLine = false;
} else {
// If it doesn't match the log pattern at all, pass it through.
if (!_lastWasFiltered)
// If it doesn't match the log pattern at all, then pass it through if we
// passed the last matching line through. It might be a multiline message.
if (_acceptedLastLine) {
_linesController.add(line);
return;
}
}
printTrace('skipped log line: $line');
}
void _stop() {
......
......@@ -378,7 +378,7 @@ int _buildApk(
artifactBuilder.directory, components.resources, buildMode
);
int signResult = _signApk(builder, components, unalignedApk, keystore);
int signResult = _signApk(builder, components, unalignedApk, keystore, buildMode);
if (signResult != 0)
return signResult;
......@@ -397,7 +397,11 @@ int _buildApk(
}
int _signApk(
_ApkBuilder builder, _ApkComponents components, File apk, ApkKeystoreInfo keystoreInfo
_ApkBuilder builder,
_ApkComponents components,
File apk,
ApkKeystoreInfo keystoreInfo,
BuildMode buildMode,
) {
File keystore;
String keystorePassword;
......@@ -405,7 +409,12 @@ int _signApk(
String keyPassword;
if (keystoreInfo == null) {
printStatus('Warning: signing the APK using the debug keystore.');
if (buildMode == BuildMode.release) {
printStatus('Warning! Signing the APK using the debug keystore.');
printStatus('You will need a real keystore to distribute your application.');
} else {
printTrace('Signing the APK using the debug keystore.');
}
keystore = components.debugKeystore;
keystorePassword = _kDebugKeystorePassword;
keyAlias = _kDebugKeystoreKeyAlias;
......@@ -415,7 +424,7 @@ int _signApk(
keystorePassword = keystoreInfo.password ?? '';
keyAlias = keystoreInfo.keyAlias ?? '';
if (keystorePassword.isEmpty || keyAlias.isEmpty) {
printError('Must provide a keystore password and a key alias.');
printError('You must provide a keystore password and a key alias.');
return 1;
}
keyPassword = keystoreInfo.keyPassword ?? '';
......@@ -586,7 +595,7 @@ Future<int> buildAndroid(
if (result == 0) {
File apkFile = new File(outputFile);
printStatus('Built $outputFile (${getSizeAsMB(apkFile.lengthSync())}).');
printTrace('Built $outputFile (${getSizeAsMB(apkFile.lengthSync())}).');
_writeBuildMetaEntry(
path.dirname(outputFile),
......
......@@ -6,6 +6,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:stack_trace/stack_trace.dart';
......@@ -135,6 +136,7 @@ class HotRunner extends ResidentRunner {
String _mainPath;
String _projectRootPath;
Set<String> _startupDependencies;
int _observatoryPort;
final AssetBundle bundle = new AssetBundle();
final bool benchmarkMode;
final Map<String, int> benchmarkData = new Map<String, int>();
......@@ -217,7 +219,7 @@ class HotRunner extends ResidentRunner {
await startEchoingDeviceLog();
printStatus('Launching loader on ${device.name}...');
printTrace('Launching loader on ${device.name}...');
// Start the loader.
Future<LaunchResult> futureResult = device.startApp(
......@@ -246,13 +248,14 @@ class HotRunner extends ResidentRunner {
return 2;
}
await connectToServiceProtocol(result.observatoryPort);
_observatoryPort = result.observatoryPort;
await connectToServiceProtocol(_observatoryPort);
try {
Uri baseUri = await _initDevFS();
if (connectionInfoCompleter != null) {
connectionInfoCompleter.complete(
new DebugConnectionInfo(result.observatoryPort, baseUri: baseUri.toString())
new DebugConnectionInfo(_observatoryPort, baseUri: baseUri.toString())
);
}
} catch (error) {
......@@ -273,13 +276,13 @@ class HotRunner extends ResidentRunner {
}
await vmService.vm.refreshViews();
printStatus('Connected to ${vmService.vm.mainView}.');
printTrace('Connected to ${vmService.vm.mainView}.');
printStatus('Running ${getDisplayPath(_mainPath)} on ${device.name}...');
_loaderShowMessage('Launching...');
await _launchFromDevFS(_package, _mainPath);
printStatus('Application running.');
printTrace('Application running.');
setupTerminal();
......@@ -361,10 +364,7 @@ class HotRunner extends ResidentRunner {
devFSStatus.stop(showElapsedTime: true);
// Clear the minimal set after the first sync.
_startupDependencies = null;
if (progressReporter != null)
printStatus('Synced ${getSizeAsMB(_devFS.bytes)}.');
else
printTrace('Synced ${getSizeAsMB(_devFS.bytes)}.');
printTrace('Synced ${getSizeAsMB(_devFS.bytes)}.');
return true;
}
......@@ -537,10 +537,16 @@ class HotRunner extends ResidentRunner {
}
@override
void printHelp() {
printStatus('Type "h" or F1 for this help message; type "q", F10, or ctrl-c to quit.', emphasis: true);
printStatus('Type "r" or F5 to perform a hot reload of the app, and "R" to restart the app.', emphasis: true);
printStatus('Type "w" to print the widget hierarchy of the app, and "t" for the render tree.', emphasis: true);
void printHelp({ @required bool details }) {
printStatus('To hot reload your app on the fly, press "r" or F5. To restart the app entirely, press "R".', emphasis: true);
printStatus('The Observatory debugger and profiler is available at: http://127.0.0.1:$_observatoryPort/');
if (details) {
printStatus('To dump the widget hierarchy of the app (debugDumpApp), press "w".');
printStatus('To dump the rendering tree of the app (debugDumpRenderTree), press "r".');
printStatus('To repeat this help message, press "h" or F1. To quit, press "q", F10, or Ctrl-C.');
} else {
printStatus('For a more detailed help message, press "h" or F1. To quit, press "q", F10, or Ctrl-C.');
}
}
@override
......
......@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'base/logger.dart';
......@@ -126,7 +127,7 @@ abstract class ResidentRunner {
if (lower == 'h' || lower == '?' || character == AnsiTerminal.KEY_F1) {
// F1, help
printHelp();
printHelp(details: true);
return true;
} else if (lower == 'w') {
await _debugDumpApp();
......@@ -165,7 +166,7 @@ abstract class ResidentRunner {
void setupTerminal() {
if (usesTerminalUI) {
if (!logger.quiet)
printHelp();
printHelp(details: false);
terminal.singleCharMode = true;
terminal.onCharInput.listen((String code) {
......@@ -198,7 +199,7 @@ abstract class ResidentRunner {
/// Called right before we exit.
Future<Null> cleanupAtFinish();
/// Called to print help to the terminal.
void printHelp();
void printHelp({ @required bool details });
/// Called when the runner should handle a terminal command.
Future<Null> handleTerminalCommand(String code);
}
......
......@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:stack_trace/stack_trace.dart';
import 'application_package.dart';
......@@ -197,13 +198,13 @@ class RunAndStayResident extends ResidentRunner {
}
}
printStatus('Application running.');
printTrace('Application running.');
if (debuggingOptions.buildMode == BuildMode.release)
return 0;
if (vmService != null) {
await vmService.vm.refreshViews();
printStatus('Connected to ${vmService.vm.mainView}\.');
printTrace('Connected to ${vmService.vm.mainView}\.');
}
if (vmService != null && traceStartup) {
......@@ -261,11 +262,18 @@ class RunAndStayResident extends ResidentRunner {
}
@override
void printHelp() {
final bool showRestartText = !prebuiltMode && device.supportsRestart;
String restartText = showRestartText ? ', "r" or F5 to restart the app,' : '';
printStatus('Type "h" or F1 for help$restartText and "q", F10, or ctrl-c to quit.');
printStatus('Type "w" to print the widget hierarchy of the app, and "t" for the render tree.');
void printHelp({ @required bool details }) {
if (!prebuiltMode && device.supportsRestart)
printStatus('To restart the app, press "r" or F5.');
if (_result.hasObservatory)
printStatus('The Observatory debugger and profiler is available at: http://127.0.0.1:${_result.observatoryPort}/');
if (details) {
printStatus('To dump the widget hierarchy of the app (debugDumpApp), press "w".');
printStatus('To dump the rendering tree of the app (debugDumpRenderTree), press "r".');
printStatus('To repeat this help message, press "h" or F1. To quit, press "q", F10, or Ctrl-C.');
} else {
printStatus('For a more detailed help message, press "h" or F1. To quit, press "q", F10, or Ctrl-C.');
}
}
}
......
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