Skip to content

Commit 866fa64

Browse files
zandersoesarbanis
andauthored
Esarbanis flutter run help (flutter#48314)
* Reword flutter run help screen. * As per Hixie request, added Efthymios Sarmpanis to the AUTHORS file * fix test Co-authored-by: Efthymis Sarmpanis <e.sarbanis@gmail.com>
1 parent 76b21d2 commit 866fa64

File tree

8 files changed

+336
-70
lines changed

8 files changed

+336
-70
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ Robin Jespersen <info@unitedpartners.de>
4949
Jefferson Quesado <jeff.quesado@gmail.com>
5050
Mark Diener <rpzrpzrpz@gmail.com>
5151
Alek Åström <alek.astrom@gmail.com>
52+
Efthymios Sarpmpanis <e.sarbanis@gmail.com>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:math' as math;
6+
7+
import '../globals.dart' as globals;
8+
import 'terminal.dart';
9+
10+
const String fire = '🔥';
11+
const int maxLineWidth = 84;
12+
13+
/// Encapsulates the help text construction and printing
14+
class CommandHelp {
15+
16+
const CommandHelp._(this.key, this.description, [this.inParenthesis = '']);
17+
18+
static const CommandHelp L = CommandHelp._('L', 'Dump layer tree to the console.', 'debugDumpLayerTree');
19+
static const CommandHelp P = CommandHelp._('P', 'Toggle performance overlay.', 'WidgetsApp.showPerformanceOverlay');
20+
static const CommandHelp R = CommandHelp._('R', 'Hot restart.');
21+
static const CommandHelp S = CommandHelp._('S', 'Dump accessibility tree in traversal order.', 'debugDumpSemantics');
22+
static const CommandHelp U = CommandHelp._('U', 'Dump accessibility tree in inverse hit test order.', 'debugDumpSemantics');
23+
static const CommandHelp a = CommandHelp._('a', 'Toggle timeline events for all widget build methods.', 'debugProfileWidgetBuilds');
24+
static const CommandHelp d = CommandHelp._('d', 'Detach (terminate "flutter run" but leave application running).');
25+
static const CommandHelp h = CommandHelp._('h', 'Repeat this help message.');
26+
static const CommandHelp i = CommandHelp._('i', 'Toggle widget inspector.', 'WidgetsApp.showWidgetInspectorOverride');
27+
static const CommandHelp o = CommandHelp._('o', 'Simulate different operating systems.', 'defaultTargetPlatform');
28+
static const CommandHelp p = CommandHelp._('p', 'Toggle the display of construction lines.', 'debugPaintSizeEnabled');
29+
static const CommandHelp q = CommandHelp._('q', 'Quit (terminate the application on the device).');
30+
static const CommandHelp r = CommandHelp._('r', 'Hot reload. $fire$fire$fire');
31+
static const CommandHelp s = CommandHelp._('s', 'Save a screenshot to flutter.png.');
32+
static const CommandHelp t = CommandHelp._('t', 'Dump rendering tree to the console.', 'debugDumpRenderTree');
33+
static const CommandHelp w = CommandHelp._('w', 'Dump widget hierarchy to the console.', 'debugDumpApp');
34+
static const CommandHelp z = CommandHelp._('z', 'Toggle elevation checker.');
35+
36+
/// The key associated with this command
37+
final String key;
38+
/// A description of what this command does
39+
final String description;
40+
/// Text shown in parenthesis to give the context
41+
final String inParenthesis;
42+
43+
bool get _hasTextInParenthesis => inParenthesis != null && inParenthesis.isNotEmpty;
44+
45+
int get _rawMessageLength => key.length + description.length;
46+
47+
@override
48+
String toString() {
49+
final StringBuffer message = StringBuffer();
50+
message.writeAll(<String>[globals.terminal.bolden(key), description], ' ');
51+
52+
if (_hasTextInParenthesis) {
53+
bool wrap = false;
54+
final int maxWidth = math.max(outputPreferences.wrapColumn ?? 0, maxLineWidth);
55+
int width = maxWidth - (globals.platform.stdoutSupportsAnsi ? _rawMessageLength + 1 : message.length);
56+
final String parentheticalText = '($inParenthesis)';
57+
if (width < parentheticalText.length) {
58+
width = maxWidth;
59+
wrap = true;
60+
}
61+
62+
if (wrap) {
63+
message.write('\n');
64+
}
65+
// pad according to the raw text
66+
message.write(''.padLeft(width - parentheticalText.length));
67+
68+
message.write(globals.terminal.color(parentheticalText, TerminalColor.grey));
69+
}
70+
return message.toString();
71+
}
72+
73+
void print() {
74+
globals.printStatus(toString());
75+
}
76+
}

packages/flutter_tools/lib/src/resident_runner.dart

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:meta/meta.dart';
99
import 'application_package.dart';
1010
import 'artifacts.dart';
1111
import 'asset.dart';
12+
import 'base/command_help.dart';
1213
import 'base/common.dart';
1314
import 'base/file_system.dart';
1415
import 'base/io.dart' as io;
@@ -1003,23 +1004,30 @@ abstract class ResidentRunner {
10031004
void printHelp({ @required bool details });
10041005

10051006
void printHelpDetails() {
1007+
if (flutterDevices.any((FlutterDevice d) => d.device.supportsScreenshot)) {
1008+
CommandHelp.s.print();
1009+
}
10061010
if (supportsServiceProtocol) {
1007-
globals.printStatus('You can dump the widget hierarchy of the app (debugDumpApp) by pressing "w".');
1008-
globals.printStatus('To dump the rendering tree of the app (debugDumpRenderTree), press "t".');
1011+
CommandHelp.w.print();
1012+
CommandHelp.t.print();
10091013
if (isRunningDebug) {
1010-
globals.printStatus('For layers (debugDumpLayerTree), use "L"; for accessibility (debugDumpSemantics), use "S" (for traversal order) or "U" (for inverse hit test order).');
1011-
globals.printStatus('To toggle the widget inspector (WidgetsApp.showWidgetInspectorOverride), press "i".');
1012-
globals.printStatus('To toggle the display of construction lines (debugPaintSizeEnabled), press "p".');
1013-
globals.printStatus('To simulate different operating systems, (defaultTargetPlatform), press "o".');
1014-
globals.printStatus('To toggle the elevation checker, press "z".');
1014+
CommandHelp.L.print();
1015+
CommandHelp.S.print();
1016+
CommandHelp.U.print();
1017+
CommandHelp.i.print();
1018+
CommandHelp.p.print();
1019+
CommandHelp.o.print();
1020+
CommandHelp.z.print();
10151021
} else {
1016-
globals.printStatus('To dump the accessibility tree (debugDumpSemantics), press "S" (for traversal order) or "U" (for inverse hit test order).');
1022+
CommandHelp.S.print();
1023+
CommandHelp.U.print();
10171024
}
1018-
globals.printStatus('To display the performance overlay (WidgetsApp.showPerformanceOverlay), press "P".');
1019-
globals.printStatus('To enable timeline events for all widget build methods, (debugProfileWidgetBuilds), press "a"');
1025+
// `P` should precede `a`
1026+
CommandHelp.P.print();
1027+
CommandHelp.a.print();
10201028
}
10211029
if (flutterDevices.any((FlutterDevice d) => d.device.supportsScreenshot)) {
1022-
globals.printStatus('To save a screenshot to flutter.png, press "s".');
1030+
CommandHelp.s.print();
10231031
}
10241032
}
10251033

packages/flutter_tools/lib/src/run_cold.dart

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66

77
import 'package:meta/meta.dart';
88

9+
import 'base/command_help.dart';
910
import 'base/file_system.dart';
1011
import 'device.dart';
1112
import 'globals.dart' as globals;
@@ -179,31 +180,23 @@ class ColdRunner extends ResidentRunner {
179180

180181
@override
181182
void printHelp({ @required bool details }) {
182-
bool haveDetails = false;
183-
bool haveAnything = false;
184-
for (final FlutterDevice device in flutterDevices) {
185-
final String dname = device.device.name;
186-
if (device.vmService != null) {
187-
globals.printStatus('An Observatory debugger and profiler on $dname is '
188-
'available at: ${device.vmService .httpAddress}');
189-
}
190-
}
183+
globals.printStatus('Flutter run key commands.');
191184
if (supportsServiceProtocol) {
192-
haveDetails = true;
193185
if (details) {
194186
printHelpDetails();
195-
haveAnything = true;
196187
}
197188
}
198-
final String quitMessage = _didAttach
199-
? 'To detach, press "d"; to quit, press "q".'
200-
: 'To quit, press "q".';
201-
if (haveDetails && !details) {
202-
globals.printStatus('For a more detailed help message, press "h". $quitMessage');
203-
} else if (haveAnything) {
204-
globals.printStatus('To repeat this help message, press "h". $quitMessage');
205-
} else {
206-
globals.printStatus(quitMessage);
189+
CommandHelp.h.print();
190+
if (_didAttach) {
191+
CommandHelp.d.print();
192+
}
193+
CommandHelp.q.print();
194+
for (final FlutterDevice device in flutterDevices) {
195+
final String dname = device.device.name;
196+
if (device.vmService != null) {
197+
globals.printStatus('An Observatory debugger and profiler on $dname is '
198+
'available at: ${device.vmService.httpAddress}');
199+
}
207200
}
208201
}
209202

packages/flutter_tools/lib/src/run_hot.dart

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import 'package:json_rpc_2/error_code.dart' as rpc_error_code;
99
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
1010
import 'package:meta/meta.dart';
1111
import 'package:pool/pool.dart';
12-
1312
import 'base/async_guard.dart';
13+
14+
import 'base/command_help.dart';
1415
import 'base/context.dart';
1516
import 'base/file_system.dart';
1617
import 'base/logger.dart';
17-
import 'base/terminal.dart';
1818
import 'base/utils.dart';
1919
import 'build_info.dart';
2020
import 'compile.dart';
@@ -1045,29 +1045,23 @@ class HotRunner extends ResidentRunner {
10451045

10461046
@override
10471047
void printHelp({ @required bool details }) {
1048-
const String fire = '🔥';
1049-
String rawMessage = ' To hot reload changes while running, press "r". ';
1048+
globals.printStatus('Flutter run key commands.');
1049+
CommandHelp.r.print();
10501050
if (canHotRestart) {
1051-
rawMessage += 'To hot restart (and rebuild state), press "R".';
1051+
CommandHelp.R.print();
10521052
}
1053-
final String message = globals.terminal.color(
1054-
fire + globals.terminal.bolden(rawMessage),
1055-
TerminalColor.red,
1056-
);
1057-
globals.printStatus(message);
1058-
for (final FlutterDevice device in flutterDevices) {
1059-
final String dname = device.device.name;
1060-
globals.printStatus('An Observatory debugger and profiler on $dname is '
1061-
'available at: ${device.vmService.httpAddress}');
1053+
CommandHelp.h.print();
1054+
if (_didAttach) {
1055+
CommandHelp.d.print();
10621056
}
1063-
final String quitMessage = _didAttach
1064-
? 'To detach, press "d"; to quit, press "q".'
1065-
: 'To quit, press "q".';
1057+
CommandHelp.q.print();
10661058
if (details) {
10671059
printHelpDetails();
1068-
globals.printStatus('To repeat this help message, press "h". $quitMessage');
1069-
} else {
1070-
globals.printStatus('For a more detailed help message, press "h". $quitMessage');
1060+
}
1061+
for (final FlutterDevice device in flutterDevices) {
1062+
final String dname = device.device.name;
1063+
globals.printStatus('An Observatory debugger and profiler on $dname is '
1064+
'available at:\n${device.vmService.httpAddress}');
10711065
}
10721066
}
10731067

packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ void main() {
165165
if (message == '[stdout] Lost connection to device.') {
166166
observatoryLogs.add(message);
167167
}
168-
if (message.contains('To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".')) {
168+
if (message.contains('Hot reload.')) {
169+
observatoryLogs.add(message);
170+
}
171+
if (message.contains('Hot restart.')) {
169172
observatoryLogs.add(message);
170173
}
171174
});
@@ -203,14 +206,16 @@ void main() {
203206
}));
204207
});
205208

206-
expect(observatoryLogs.length, 7);
209+
expect(observatoryLogs.length, 9);
207210
expect(observatoryLogs[0], '[stdout] Waiting for a connection from Flutter on MockAndroidDevice...');
208211
expect(observatoryLogs[1], '[verbose] Observatory URL on device: http://127.0.0.1:1234');
209212
expect(observatoryLogs[2], '[stdout] Lost connection to device.');
210-
expect(observatoryLogs[3].contains('To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R"'), isTrue);
211-
expect(observatoryLogs[4], '[verbose] Observatory URL on device: http://127.0.0.1:1235');
212-
expect(observatoryLogs[5], '[stdout] Lost connection to device.');
213-
expect(observatoryLogs[6].contains('To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R"'), isTrue);
213+
expect(observatoryLogs[3].contains('Hot reload.'), isTrue);
214+
expect(observatoryLogs[4].contains('Hot restart.'), isTrue);
215+
expect(observatoryLogs[5], '[verbose] Observatory URL on device: http://127.0.0.1:1235');
216+
expect(observatoryLogs[6], '[stdout] Lost connection to device.');
217+
expect(observatoryLogs[7].contains('Hot reload.'), isTrue);
218+
expect(observatoryLogs[8].contains('Hot restart.'), isTrue);
214219

215220
verify(portForwarder.forward(1234, hostPort: anyNamed('hostPort'))).called(1);
216221
verify(portForwarder.forward(1235, hostPort: anyNamed('hostPort'))).called(1);

0 commit comments

Comments
 (0)