Skip to content

Commit 9393aae

Browse files
authored
Align web terminal messages with the VM (#163268)
- Adds better instructions for hot reload (if using the right flags), hot restart, quitting, clearing, and more. These were already being printed when using the VM, so this aligns with that. - Adds an extra parameter for `CommandHelp` to `ResidentRunner` so `ResidentWebRunner` can pass a version of it that uses its separate logger and not `globals`. In order to support this, classes up the stack also provide a `Terminal`, `Platform`, and `OutputPreferences`. - Fixes up use of `globals` from an earlier change to implement hot reload to use the logger instead. Same with `globals.platform`. - Adds tests to check that only hot restart is printed when not using the extra front-end flags, and both hot restart and hot reload is printed when you are. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
1 parent 6a912ee commit 9393aae

20 files changed

Lines changed: 276 additions & 81 deletions

packages/flutter_tools/lib/executable.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ List<FlutterCommand> generateCommands({required bool verboseHelp, required bool
218218
fileSystem: globals.fs,
219219
logger: globals.logger,
220220
platform: globals.platform,
221+
terminal: globals.terminal,
222+
outputPreferences: globals.outputPreferences,
221223
signals: globals.signals,
222224
),
223225
EmulatorsCommand(),

packages/flutter_tools/lib/src/base/command_help.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const int maxLineWidth = 84;
1515
class CommandHelp {
1616
CommandHelp({
1717
required Logger logger,
18-
required AnsiTerminal terminal,
18+
required Terminal terminal,
1919
required Platform platform,
2020
required OutputPreferences outputPreferences,
2121
}) : _logger = logger,
@@ -25,7 +25,7 @@ class CommandHelp {
2525

2626
final Logger _logger;
2727

28-
final AnsiTerminal _terminal;
28+
final Terminal _terminal;
2929

3030
final Platform _platform;
3131

packages/flutter_tools/lib/src/commands/daemon.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,9 @@ class AppDomain extends Domain {
710710
analytics: globals.analytics,
711711
systemClock: globals.systemClock,
712712
logger: globals.logger,
713+
terminal: globals.terminal,
714+
platform: globals.platform,
715+
outputPreferences: globals.outputPreferences,
713716
fileSystem: globals.fs,
714717
);
715718
} else if (enableHotReload) {

packages/flutter_tools/lib/src/commands/drive.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import '../base/io.dart';
1717
import '../base/logger.dart';
1818
import '../base/platform.dart';
1919
import '../base/signals.dart';
20+
import '../base/terminal.dart';
2021
import '../base/utils.dart';
2122
import '../build_info.dart';
2223
import '../dart/package_map.dart';
@@ -60,11 +61,15 @@ class DriveCommand extends RunCommandBase {
6061
required FileSystem fileSystem,
6162
required Logger logger,
6263
required Platform platform,
64+
required Terminal terminal,
65+
required OutputPreferences outputPreferences,
6366
required this.signals,
6467
}) : _flutterDriverFactory = flutterDriverFactory,
6568
_fileSystem = fileSystem,
6669
_logger = logger,
6770
_platform = platform,
71+
_terminal = terminal,
72+
_outputPreferences = outputPreferences,
6873
_fsUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform),
6974
super(verboseHelp: verboseHelp) {
7075
requiresPubspecYaml();
@@ -200,6 +205,8 @@ class DriveCommand extends RunCommandBase {
200205
final FileSystem _fileSystem;
201206
final Logger _logger;
202207
final Platform _platform;
208+
final Terminal _terminal;
209+
final OutputPreferences _outputPreferences;
203210
final FileSystemUtils _fsUtils;
204211
Timer? timeoutTimer;
205212
Map<ProcessSignal, Object>? screenshotTokens;
@@ -298,6 +305,8 @@ class DriveCommand extends RunCommandBase {
298305
applicationPackageFactory: ApplicationPackageFactory.instance!,
299306
logger: _logger,
300307
platform: _platform,
308+
terminal: _terminal,
309+
outputPreferences: _outputPreferences,
301310
processUtils: globals.processUtils,
302311
dartSdkPath: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
303312
devtoolsLauncher: DevtoolsLauncher.instance!,

packages/flutter_tools/lib/src/commands/run.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,9 @@ class RunCommand extends RunCommandBase {
720720
fileSystem: globals.fs,
721721
analytics: globals.analytics,
722722
logger: globals.logger,
723+
terminal: globals.terminal,
724+
platform: globals.platform,
725+
outputPreferences: globals.outputPreferences,
723726
systemClock: globals.systemClock,
724727
);
725728
}

packages/flutter_tools/lib/src/drive/drive_service.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import '../base/dds.dart';
1515
import '../base/logger.dart';
1616
import '../base/platform.dart';
1717
import '../base/process.dart';
18+
import '../base/terminal.dart';
1819
import '../build_info.dart';
1920
import '../device.dart';
2021
import '../resident_runner.dart';
@@ -26,19 +27,25 @@ class FlutterDriverFactory {
2627
required ApplicationPackageFactory applicationPackageFactory,
2728
required Platform platform,
2829
required Logger logger,
30+
required Terminal terminal,
31+
required OutputPreferences outputPreferences,
2932
required ProcessUtils processUtils,
3033
required String dartSdkPath,
3134
required DevtoolsLauncher devtoolsLauncher,
3235
}) : _applicationPackageFactory = applicationPackageFactory,
3336
_platform = platform,
3437
_logger = logger,
38+
_terminal = terminal,
39+
_outputPreferences = outputPreferences,
3540
_processUtils = processUtils,
3641
_dartSdkPath = dartSdkPath,
3742
_devtoolsLauncher = devtoolsLauncher;
3843

3944
final ApplicationPackageFactory _applicationPackageFactory;
4045
final Platform _platform;
4146
final Logger _logger;
47+
final Terminal _terminal;
48+
final OutputPreferences _outputPreferences;
4249
final ProcessUtils _processUtils;
4350
final String _dartSdkPath;
4451
final DevtoolsLauncher _devtoolsLauncher;
@@ -48,7 +55,9 @@ class FlutterDriverFactory {
4855
if (web) {
4956
return WebDriverService(
5057
logger: _logger,
58+
terminal: _terminal,
5159
platform: _platform,
60+
outputPreferences: _outputPreferences,
5261
processUtils: _processUtils,
5362
dartSdkPath: _dartSdkPath,
5463
);

packages/flutter_tools/lib/src/drive/web_driver_service.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import '../base/io.dart';
1515
import '../base/logger.dart';
1616
import '../base/platform.dart';
1717
import '../base/process.dart';
18+
import '../base/terminal.dart';
1819
import '../base/utils.dart';
1920
import '../build_info.dart';
2021
import '../convert.dart';
@@ -32,15 +33,21 @@ class WebDriverService extends DriverService {
3233
required String dartSdkPath,
3334
required Platform platform,
3435
required Logger logger,
36+
required Terminal terminal,
37+
required OutputPreferences outputPreferences,
3538
}) : _processUtils = processUtils,
3639
_dartSdkPath = dartSdkPath,
3740
_platform = platform,
38-
_logger = logger;
41+
_logger = logger,
42+
_terminal = terminal,
43+
_outputPreferences = outputPreferences;
3944

4045
final ProcessUtils _processUtils;
4146
final String _dartSdkPath;
4247
final Platform _platform;
4348
final Logger _logger;
49+
final Terminal _terminal;
50+
final OutputPreferences _outputPreferences;
4451

4552
late ResidentRunner _residentRunner;
4653
Uri? _webUri;
@@ -99,6 +106,9 @@ class WebDriverService extends DriverService {
99106
fileSystem: globals.fs,
100107
analytics: globals.analytics,
101108
logger: _logger,
109+
terminal: _terminal,
110+
platform: _platform,
111+
outputPreferences: _outputPreferences,
102112
systemClock: globals.systemClock,
103113
);
104114
final Completer<void> appStartedCompleter = Completer<void>.sync();

packages/flutter_tools/lib/src/isolated/resident_web_runner.dart

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' hide
1212

1313
import '../application_package.dart';
1414
import '../base/async_guard.dart';
15+
import '../base/command_help.dart';
1516
import '../base/common.dart';
1617
import '../base/file_system.dart';
1718
import '../base/io.dart';
1819
import '../base/logger.dart';
1920
import '../base/net.dart';
21+
import '../base/platform.dart';
2022
import '../base/terminal.dart';
2123
import '../base/time.dart';
2224
import '../base/utils.dart';
@@ -52,6 +54,9 @@ class DwdsWebRunnerFactory extends WebRunnerFactory {
5254
required DebuggingOptions debuggingOptions,
5355
UrlTunneller? urlTunneller,
5456
required Logger logger,
57+
required Terminal terminal,
58+
required Platform platform,
59+
required OutputPreferences outputPreferences,
5560
required FileSystem fileSystem,
5661
required SystemClock systemClock,
5762
required Analytics analytics,
@@ -69,6 +74,9 @@ class DwdsWebRunnerFactory extends WebRunnerFactory {
6974
systemClock: systemClock,
7075
fileSystem: fileSystem,
7176
logger: logger,
77+
terminal: terminal,
78+
platform: platform,
79+
outputPreferences: outputPreferences,
7280
);
7381
}
7482
}
@@ -88,13 +96,17 @@ class ResidentWebRunner extends ResidentRunner {
8896
required DebuggingOptions debuggingOptions,
8997
required FileSystem fileSystem,
9098
required Logger logger,
99+
required Terminal terminal,
100+
required Platform platform,
101+
required OutputPreferences outputPreferences,
91102
required SystemClock systemClock,
92103
required Analytics analytics,
93104
UrlTunneller? urlTunneller,
94105
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
95106
ResidentDevtoolsHandlerFactory devtoolsHandler = createDefaultHandler,
96107
}) : _fileSystem = fileSystem,
97108
_logger = logger,
109+
_platform = platform,
98110
_systemClock = systemClock,
99111
_analytics = analytics,
100112
_urlTunneller = urlTunneller,
@@ -105,10 +117,17 @@ class ResidentWebRunner extends ResidentRunner {
105117
stayResident: stayResident,
106118
machine: machine,
107119
devtoolsHandler: devtoolsHandler,
120+
commandHelp: CommandHelp(
121+
logger: logger,
122+
terminal: terminal,
123+
platform: platform,
124+
outputPreferences: outputPreferences,
125+
),
108126
);
109127

110128
final FileSystem _fileSystem;
111129
final Logger _logger;
130+
final Platform _platform;
112131
final SystemClock _systemClock;
113132
final Analytics _analytics;
114133
final UrlTunneller? _urlTunneller;
@@ -146,6 +165,20 @@ class ResidentWebRunner extends ResidentRunner {
146165

147166
bool get _enableDwds => debuggingEnabled;
148167

168+
@override
169+
bool get reloadIsRestart =>
170+
// Web behavior when not using the DDC library bundle format is to restart
171+
// when a reload is issued. We can't use `canHotReload` to signal this
172+
// since we still want a reload command to succeed, but to do a hot
173+
// restart.
174+
debuggingOptions.buildInfo.ddcModuleFormat != DdcModuleFormat.ddc ||
175+
debuggingOptions.buildInfo.canaryFeatures != true;
176+
177+
// TODO(srujzs): Return true when web supports detaching.
178+
// https://github.com/flutter/flutter/issues/163329
179+
@override
180+
bool get supportsDetach => false;
181+
149182
ConnectionResult? _connectionResult;
150183
StreamSubscription<vmservice.Event>? _stdOutSub;
151184
StreamSubscription<vmservice.Event>? _stdErrSub;
@@ -205,24 +238,6 @@ class ResidentWebRunner extends ResidentRunner {
205238
appFinished();
206239
}
207240

208-
@override
209-
void printHelp({bool details = true}) {
210-
if (details) {
211-
return printHelpDetails();
212-
}
213-
const String fire = '🔥';
214-
const String rawMessage = ' To hot restart changes while running, press "r" or "R".';
215-
final String message = _logger.terminal.color(
216-
fire + _logger.terminal.bolden(rawMessage),
217-
TerminalColor.red,
218-
);
219-
_logger.printStatus(message);
220-
const String quitMessage = 'To quit, press "q".';
221-
_logger.printStatus('For a more detailed help message, press "h". $quitMessage');
222-
_logger.printStatus('');
223-
printDebuggerList();
224-
}
225-
226241
@override
227242
Future<void> stopEchoingDeviceLog() async {
228243
// Do nothing for ResidentWebRunner
@@ -310,7 +325,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
310325
isWasm: debuggingOptions.webUseWasm,
311326
useLocalCanvasKit: debuggingOptions.buildInfo.useLocalCanvasKit,
312327
rootDirectory: fileSystem.directory(projectRootPath),
313-
isWindows: globals.platform.isWindows,
328+
isWindows: _platform.isWindows,
314329
);
315330
Uri url = await device!.devFS!.create();
316331
if (debuggingOptions.tlsCertKeyPath != null && debuggingOptions.tlsCertPath != null) {
@@ -475,10 +490,10 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
475490
// has some internal error, we should still surface it to make
476491
// debugging easier.
477492
String reloadFailedMessage = 'Hot reload failed:';
478-
globals.printError(reloadFailedMessage);
493+
_logger.printError(reloadFailedMessage);
479494
for (final ReasonForCancelling reason in contents.notices) {
480495
reloadFailedMessage += reason.toString();
481-
globals.printError(reason.toString());
496+
_logger.printError(reason.toString());
482497
}
483498
return OperationResult(1, reloadFailedMessage);
484499
}

0 commit comments

Comments
 (0)