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