Fix dartDefines in daemon mode (#45317)
* de-null dartDefines in daemon mode
* remove daemonCommand; pipe through dartDefines into Daemon
* pass dartDefiles in attach; add test for --machine mode
diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart
index 88b5677..04e86d8 100644
--- a/packages/flutter_tools/lib/src/commands/attach.dart
+++ b/packages/flutter_tools/lib/src/commands/attach.dart
@@ -198,8 +198,13 @@
final int devicePort = await getDevicePort();
final Daemon daemon = boolArg('machine')
- ? Daemon(stdinCommandStream, stdoutCommandResponse,
- notifyingLogger: NotifyingLogger(), logToStdout: true)
+ ? Daemon(
+ stdinCommandStream,
+ stdoutCommandResponse,
+ notifyingLogger: NotifyingLogger(),
+ logToStdout: true,
+ dartDefines: dartDefines,
+ )
: null;
Stream<Uri> observatoryUri;
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart
index 8c5d6e4..42c413d 100644
--- a/packages/flutter_tools/lib/src/commands/daemon.dart
+++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -35,7 +35,9 @@
/// It can be shutdown with a `daemon.shutdown` command (or by killing the
/// process).
class DaemonCommand extends FlutterCommand {
- DaemonCommand({ this.hidden = false });
+ DaemonCommand({ this.hidden = false }) {
+ usesDartDefines();
+ }
@override
final String name = 'daemon';
@@ -58,8 +60,10 @@
await context.run<void>(
body: () async {
final Daemon daemon = Daemon(
- stdinCommandStream, stdoutCommandResponse,
- daemonCommand: this, notifyingLogger: notifyingLogger);
+ stdinCommandStream, stdoutCommandResponse,
+ notifyingLogger: notifyingLogger,
+ dartDefines: dartDefines,
+ );
final int code = await daemon.onExit;
if (code != 0) {
@@ -82,10 +86,17 @@
Daemon(
Stream<Map<String, dynamic>> commandStream,
this.sendCommand, {
- this.daemonCommand,
this.notifyingLogger,
this.logToStdout = false,
+ @required this.dartDefines,
}) {
+ if (dartDefines == null) {
+ throw Exception(
+ 'dartDefines must not be null. This is a bug in Flutter.\n'
+ 'Please file an issue at https://github.com/flutter/flutter/issues/new/choose',
+ );
+ }
+
// Set up domains.
_registerDomain(daemonDomain = DaemonDomain(this));
_registerDomain(appDomain = AppDomain(this));
@@ -110,9 +121,9 @@
StreamSubscription<Map<String, dynamic>> _commandSubscription;
final DispatchCommand sendCommand;
- final DaemonCommand daemonCommand;
final NotifyingLogger notifyingLogger;
final bool logToStdout;
+ final List<String> dartDefines;
final Completer<int> _onExitCompleter = Completer<int>();
final Map<String, Domain> _domainMap = <String, Domain>{};
@@ -184,8 +195,6 @@
_handlers[name] = handler;
}
- FlutterCommand get command => daemon.daemonCommand;
-
@override
String toString() => name;
@@ -424,7 +433,7 @@
viewFilter: isolateFilter,
target: target,
buildMode: options.buildInfo.mode,
- dartDefines: command?.dartDefines,
+ dartDefines: daemon.dartDefines,
);
ResidentRunner runner;
@@ -437,7 +446,7 @@
debuggingOptions: options,
ipv6: ipv6,
stayResident: true,
- dartDefines: command?.dartDefines,
+ dartDefines: daemon.dartDefines,
);
} else if (enableHotReload) {
runner = HotRunner(
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index c41709a..60e1eac 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -340,8 +340,13 @@
if (devices.length > 1) {
throwToolExit('--machine does not support -d all.');
}
- final Daemon daemon = Daemon(stdinCommandStream, stdoutCommandResponse,
- notifyingLogger: NotifyingLogger(), logToStdout: true);
+ final Daemon daemon = Daemon(
+ stdinCommandStream,
+ stdoutCommandResponse,
+ notifyingLogger: NotifyingLogger(),
+ logToStdout: true,
+ dartDefines: dartDefines,
+ );
AppInstance app;
try {
final String applicationBinaryPath = stringArg('use-application-binary');
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart
index c9eadf1..8d59836 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart
@@ -39,6 +39,7 @@
commands.stream,
responses.add,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'daemon.version'});
final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
@@ -56,6 +57,7 @@
commands.stream,
responses.add,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
printError('daemon.logMessage test');
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> map) {
@@ -83,6 +85,7 @@
responses.add,
notifyingLogger: notifyingLogger,
logToStdout: true,
+ dartDefines: const <String>[],
);
printStatus('daemon.logMessage test');
// Service the event loop.
@@ -103,6 +106,7 @@
commands.stream,
responses.add,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'daemon.shutdown'});
return daemon.onExit.then<void>((int code) async {
@@ -112,16 +116,13 @@
});
testUsingContext('app.restart without an appId should report an error', () async {
- final DaemonCommand command = DaemonCommand();
- applyMocksToCommand(command);
-
final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>();
final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>();
daemon = Daemon(
commands.stream,
responses.add,
- daemonCommand: command,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'app.restart'});
@@ -133,16 +134,13 @@
});
testUsingContext('ext.flutter.debugPaint via service extension without an appId should report an error', () async {
- final DaemonCommand command = DaemonCommand();
- applyMocksToCommand(command);
-
final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>();
final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>();
daemon = Daemon(
commands.stream,
responses.add,
- daemonCommand: command,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{
@@ -160,16 +158,13 @@
});
testUsingContext('app.stop without appId should report an error', () async {
- final DaemonCommand command = DaemonCommand();
- applyMocksToCommand(command);
-
final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>();
final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>();
daemon = Daemon(
commands.stream,
responses.add,
- daemonCommand: command,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'app.stop'});
@@ -187,6 +182,7 @@
commands.stream,
responses.add,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'device.getDevices'});
final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
@@ -203,6 +199,7 @@
commands.stream,
responses.add,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
final MockPollingDeviceDiscovery discoverer = MockPollingDeviceDiscovery();
daemon.deviceDomain.addDeviceDiscoverer(discoverer);
@@ -221,9 +218,10 @@
final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>();
final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>();
daemon = Daemon(
- commands.stream,
- responses.add,
- notifyingLogger: notifyingLogger,
+ commands.stream,
+ responses.add,
+ notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
final MockPollingDeviceDiscovery discoverer = MockPollingDeviceDiscovery();
@@ -247,16 +245,13 @@
});
testUsingContext('emulator.launch without an emulatorId should report an error', () async {
- final DaemonCommand command = DaemonCommand();
- applyMocksToCommand(command);
-
final StreamController<Map<String, dynamic>> commands = StreamController<Map<String, dynamic>>();
final StreamController<Map<String, dynamic>> responses = StreamController<Map<String, dynamic>>();
daemon = Daemon(
commands.stream,
responses.add,
- daemonCommand: command,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'emulator.launch'});
@@ -274,6 +269,7 @@
commands.stream,
responses.add,
notifyingLogger: notifyingLogger,
+ dartDefines: const <String>[],
);
commands.add(<String, dynamic>{'id': 0, 'method': 'emulator.getEmulators'});
final Map<String, dynamic> response = await responses.stream.firstWhere(_notEvent);
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
index cb4f01e..fb92f5c 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
@@ -244,6 +244,37 @@
FlutterVersion: () => mockStableFlutterVersion,
WebRunnerFactory: () => mockWebRunnerFactory,
});
+
+ testUsingContext('populates dartDefines in --machine mode', () async {
+ final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_run_test.');
+ fs.currentDirectory = tempDir;
+
+ final Directory libDir = tempDir.childDirectory('lib');
+ libDir.createSync();
+ final File mainFile = libDir.childFile('main.dart');
+ mainFile.writeAsStringSync('void main() {}');
+
+ final Directory webDir = tempDir.childDirectory('web');
+ webDir.createSync();
+ final File indexFile = libDir.childFile('index.html');
+ indexFile.writeAsStringSync('<h1>Hello</h1>');
+
+ when(mockDeviceManager.deviceDiscoverers).thenReturn(<DeviceDiscovery>[]);
+
+ args.add('--machine');
+ await createTestCommandRunner(command).run(args);
+ expect(mockWebRunnerFactory._dartDefines, <String>['FOO=bar']);
+ }, overrides: <Type, Generator>{
+ DeviceManager: () => mockDeviceManager,
+ FeatureFlags: () => TestFeatureFlags(
+ isWebEnabled: true,
+ ),
+ FileSystem: () => fs,
+ ProcessManager: () => mockProcessManager,
+ DeviceManager: () => mockDeviceManager,
+ FlutterVersion: () => mockStableFlutterVersion,
+ WebRunnerFactory: () => mockWebRunnerFactory,
+ });
});
});
}
@@ -276,6 +307,9 @@
static const int kFailure = -1;
TargetPlatform _targetPlatform = TargetPlatform.ios;
+ @override
+ String get id => 'fake_device';
+
void _throwToolExit(int code) => throwToolExit(null, exitCode: code);
@override
@@ -351,6 +385,9 @@
class MockWebRunner extends Mock implements ResidentRunner {
@override
+ bool get debuggingEnabled => false;
+
+ @override
Future<int> run({
Completer<DebugConnectionInfo> connectionInfoCompleter,
Completer<void> appStartedCompleter,
@@ -358,4 +395,7 @@
}) async {
return 0;
}
+
+ @override
+ Future<int> waitForAppToFinish() async => 0;
}