Unverified Commit aebf5484 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] skip web renderer defines unless web target is picked (#75160)

parent b54bdeb9
...@@ -198,7 +198,7 @@ class DriveCommand extends RunCommandBase { ...@@ -198,7 +198,7 @@ class DriveCommand extends RunCommandBase {
) ?? PackageConfig.empty; ) ?? PackageConfig.empty;
final DriverService driverService = _flutterDriverFactory.createDriverService(web); final DriverService driverService = _flutterDriverFactory.createDriverService(web);
final BuildInfo buildInfo = await getBuildInfo(); final BuildInfo buildInfo = await getBuildInfo();
final DebuggingOptions debuggingOptions = await createDebuggingOptions(); final DebuggingOptions debuggingOptions = await createDebuggingOptions(web);
final File applicationBinary = stringArg('use-application-binary') == null final File applicationBinary = stringArg('use-application-binary') == null
? null ? null
: _fileSystem.file(stringArg('use-application-binary')); : _fileSystem.file(stringArg('use-application-binary'));
......
...@@ -159,8 +159,8 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -159,8 +159,8 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
String get traceAllowlist => stringArg('trace-allowlist'); String get traceAllowlist => stringArg('trace-allowlist');
/// Create a debugging options instance for the current `run` or `drive` invocation. /// Create a debugging options instance for the current `run` or `drive` invocation.
Future<DebuggingOptions> createDebuggingOptions() async { Future<DebuggingOptions> createDebuggingOptions(bool webMode) async {
final BuildInfo buildInfo = await getBuildInfo(); final BuildInfo buildInfo = await getBuildInfo(updateWebDefines: webMode);
final int browserDebugPort = featureFlags.isWebEnabled && argResults.wasParsed('web-browser-debug-port') final int browserDebugPort = featureFlags.isWebEnabled && argResults.wasParsed('web-browser-debug-port')
? int.parse(stringArg('web-browser-debug-port')) ? int.parse(stringArg('web-browser-debug-port'))
: null; : null;
...@@ -322,6 +322,7 @@ class RunCommand extends RunCommandBase { ...@@ -322,6 +322,7 @@ class RunCommand extends RunCommandBase {
final String description = 'Run your Flutter app on an attached device.'; final String description = 'Run your Flutter app on an attached device.';
List<Device> devices; List<Device> devices;
bool webMode = false;
String get userIdentifier => stringArg(FlutterOptions.kDeviceUser); String get userIdentifier => stringArg(FlutterOptions.kDeviceUser);
...@@ -393,7 +394,7 @@ class RunCommand extends RunCommandBase { ...@@ -393,7 +394,7 @@ class RunCommand extends RunCommandBase {
} }
} }
final BuildInfo buildInfo = await getBuildInfo(); final BuildInfo buildInfo = await getBuildInfo(updateWebDefines: webMode);
final String modeName = buildInfo.modeName; final String modeName = buildInfo.modeName;
return <CustomDimensions, String>{ return <CustomDimensions, String>{
CustomDimensions.commandRunIsEmulator: '$isEmulator', CustomDimensions.commandRunIsEmulator: '$isEmulator',
...@@ -448,13 +449,18 @@ class RunCommand extends RunCommandBase { ...@@ -448,13 +449,18 @@ class RunCommand extends RunCommandBase {
'--${FlutterOptions.kDeviceUser} is only supported for Android. At least one Android device is required.' '--${FlutterOptions.kDeviceUser} is only supported for Android. At least one Android device is required.'
); );
} }
// Only support "web mode" with a single web device due to resident runner
// refactoring required otherwise.
webMode = featureFlags.isWebEnabled &&
devices.length == 1 &&
await devices.single.targetPlatform == TargetPlatform.web_javascript;
} }
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
// Enable hot mode by default if `--no-hot` was not passed and we are in // Enable hot mode by default if `--no-hot` was not passed and we are in
// debug mode. // debug mode.
final BuildInfo buildInfo = await getBuildInfo(); final BuildInfo buildInfo = await getBuildInfo(updateWebDefines: webMode);
final bool hotMode = shouldUseHotMode(buildInfo); final bool hotMode = shouldUseHotMode(buildInfo);
final String applicationBinaryPath = stringArg('use-application-binary'); final String applicationBinaryPath = stringArg('use-application-binary');
...@@ -476,7 +482,7 @@ class RunCommand extends RunCommandBase { ...@@ -476,7 +482,7 @@ class RunCommand extends RunCommandBase {
try { try {
app = await daemon.appDomain.startApp( app = await daemon.appDomain.startApp(
devices.first, globals.fs.currentDirectory.path, targetFile, route, devices.first, globals.fs.currentDirectory.path, targetFile, route,
await createDebuggingOptions(), hotMode, await createDebuggingOptions(webMode), hotMode,
applicationBinary: applicationBinaryPath == null applicationBinary: applicationBinaryPath == null
? null ? null
: globals.fs.file(applicationBinaryPath), : globals.fs.file(applicationBinaryPath),
...@@ -550,18 +556,13 @@ class RunCommand extends RunCommandBase { ...@@ -550,18 +556,13 @@ class RunCommand extends RunCommandBase {
platform: globals.platform, platform: globals.platform,
), ),
]; ];
// Only support "web mode" with a single web device due to resident runner
// refactoring required otherwise.
final bool webMode = featureFlags.isWebEnabled &&
devices.length == 1 &&
await devices.single.targetPlatform == TargetPlatform.web_javascript;
ResidentRunner runner; ResidentRunner runner;
if (hotMode && !webMode) { if (hotMode && !webMode) {
runner = HotRunner( runner = HotRunner(
flutterDevices, flutterDevices,
target: targetFile, target: targetFile,
debuggingOptions: await createDebuggingOptions(), debuggingOptions: await createDebuggingOptions(webMode),
benchmarkMode: boolArg('benchmark'), benchmarkMode: boolArg('benchmark'),
applicationBinary: applicationBinaryPath == null applicationBinary: applicationBinaryPath == null
? null ? null
...@@ -577,7 +578,7 @@ class RunCommand extends RunCommandBase { ...@@ -577,7 +578,7 @@ class RunCommand extends RunCommandBase {
target: targetFile, target: targetFile,
flutterProject: flutterProject, flutterProject: flutterProject,
ipv6: ipv6, ipv6: ipv6,
debuggingOptions: await createDebuggingOptions(), debuggingOptions: await createDebuggingOptions(webMode),
stayResident: stayResident, stayResident: stayResident,
urlTunneller: null, urlTunneller: null,
); );
...@@ -585,7 +586,7 @@ class RunCommand extends RunCommandBase { ...@@ -585,7 +586,7 @@ class RunCommand extends RunCommandBase {
runner = ColdRunner( runner = ColdRunner(
flutterDevices, flutterDevices,
target: targetFile, target: targetFile,
debuggingOptions: await createDebuggingOptions(), debuggingOptions: await createDebuggingOptions(webMode),
traceStartup: traceStartup, traceStartup: traceStartup,
awaitFirstFrameWhenTracing: awaitFirstFrameWhenTracing, awaitFirstFrameWhenTracing: awaitFirstFrameWhenTracing,
applicationBinary: applicationBinaryPath == null applicationBinary: applicationBinaryPath == null
......
...@@ -820,7 +820,7 @@ abstract class FlutterCommand extends Command<void> { ...@@ -820,7 +820,7 @@ abstract class FlutterCommand extends Command<void> {
/// ///
/// Throws a [ToolExit] if the current set of options is not compatible with /// Throws a [ToolExit] if the current set of options is not compatible with
/// each other. /// each other.
Future<BuildInfo> getBuildInfo({ BuildMode forcedBuildMode }) async { Future<BuildInfo> getBuildInfo({ BuildMode forcedBuildMode, bool updateWebDefines = true }) async {
final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation') && final bool trackWidgetCreation = argParser.options.containsKey('track-widget-creation') &&
boolArg('track-widget-creation'); boolArg('track-widget-creation');
...@@ -940,7 +940,7 @@ abstract class FlutterCommand extends Command<void> { ...@@ -940,7 +940,7 @@ abstract class FlutterCommand extends Command<void> {
? stringsArg(FlutterOptions.kDartDefinesOption) ? stringsArg(FlutterOptions.kDartDefinesOption)
: <String>[]; : <String>[];
if (argParser.options.containsKey('web-renderer')) { if (argParser.options.containsKey('web-renderer') && updateWebDefines) {
dartDefines = updateDartDefines(dartDefines, stringArg('web-renderer')); dartDefines = updateDartDefines(dartDefines, stringArg('web-renderer'));
} }
......
...@@ -19,6 +19,7 @@ import 'package:flutter_tools/src/base/user_messages.dart'; ...@@ -19,6 +19,7 @@ import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/run.dart'; import 'package:flutter_tools/src/commands/run.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
...@@ -388,6 +389,66 @@ void main() { ...@@ -388,6 +389,66 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
Usage: () => usage, Usage: () => usage,
}); });
testUsingContext('No web renderer options are added to non web device', () async {
final FakeApplicationPackageFactory applicationPackageFactory = ApplicationPackageFactory.instance as FakeApplicationPackageFactory;
final RunCommand command = RunCommand();
final MockDevice mockDevice = MockDevice(TargetPlatform.ios);
when(mockDevice.supportsRuntimeMode(any)).thenAnswer((Invocation invocation) => true);
when(mockDevice.isLocalEmulator).thenAnswer((Invocation invocation) => Future<bool>.value(false));
when(mockDevice.getLogReader(app: anyNamed('app'))).thenReturn(FakeDeviceLogReader());
when(mockDevice.supportsFastStart).thenReturn(true);
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) => Future<String>.value('iOS 13'));
applicationPackageFactory.package = PrebuiltIOSApp(projectBundleId: 'test');
DebuggingOptions debuggingOptions;
when(mockDevice.startApp(
any,
mainPath: anyNamed('mainPath'),
debuggingOptions: anyNamed('debuggingOptions'),
platformArgs: anyNamed('platformArgs'),
route: anyNamed('route'),
prebuiltApplication: anyNamed('prebuiltApplication'),
ipv6: anyNamed('ipv6'),
userIdentifier: anyNamed('userIdentifier'),
)).thenAnswer((Invocation invocation) {
debuggingOptions = invocation.namedArguments[#debuggingOptions] as DebuggingOptions;
return Future<LaunchResult>.value(LaunchResult.failed());
});
when(mockDeviceManager.getDevices()).thenAnswer(
(Invocation invocation) => Future<List<Device>>.value(<Device>[mockDevice])
);
when(mockDeviceManager.findTargetDevices(any, timeout: anyNamed('timeout'))).thenAnswer(
(Invocation invocation) => Future<List<Device>>.value(<Device>[mockDevice])
);
final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_run_test.');
tempDir.childDirectory('ios').childFile('AppDelegate.swift').createSync(recursive: true);
tempDir.childFile('.dart_tool/package_config')
..createSync(recursive: true)
..writeAsStringSync(json.encode(<String, Object>{'configVersion': 2, 'packages': <Object>[]}));
tempDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true);
tempDir.childFile('pubspec.yaml').writeAsStringSync('name: test');
globals.fs.currentDirectory = tempDir;
await expectToolExitLater(createTestCommandRunner(command).run(<String>[
'run',
'--no-pub',
'--no-hot',
]), isNull);
// No web renderer options are added.
expect(debuggingOptions.buildInfo.dartDefines, isEmpty);
}, overrides: <Type, Generator>{
Artifacts: () => artifacts,
Cache: () => mockCache,
DeviceManager: () => mockDeviceManager,
FileSystem: () => fs,
ProcessManager: () => mockProcessManager,
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
});
}); });
testUsingContext('should only request artifacts corresponding to connected devices', () async { testUsingContext('should only request artifacts corresponding to connected devices', () async {
...@@ -579,3 +640,16 @@ class FakeDevice extends Fake implements Device { ...@@ -579,3 +640,16 @@ class FakeDevice extends Fake implements Device {
return null; return null;
} }
} }
class FakeApplicationPackageFactory extends Fake implements ApplicationPackageFactory {
ApplicationPackage package;
@override
Future<ApplicationPackage> getPackageForPlatform(
TargetPlatform platform, {
BuildInfo buildInfo,
File applicationBinary,
}) async {
return package;
}
}
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