
initialize the flutter root as early as possible. This allows all interfaces to be normally injected into commands, even if those objects might read from the flutter root.
582 lines
21 KiB
Dart
582 lines
21 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:file/file.dart';
|
|
import 'package:file/memory.dart';
|
|
import 'package:flutter_tools/src/application_package.dart';
|
|
import 'package:flutter_tools/src/artifacts.dart';
|
|
import 'package:flutter_tools/src/base/common.dart';
|
|
import 'package:flutter_tools/src/base/context.dart';
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
|
import 'package:flutter_tools/src/base/io.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/base/user_messages.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/cache.dart';
|
|
import 'package:flutter_tools/src/commands/run.dart';
|
|
import 'package:flutter_tools/src/device.dart';
|
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
|
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
|
import 'package:mockito/mockito.dart';
|
|
|
|
import '../../src/common.dart';
|
|
import '../../src/context.dart';
|
|
import '../../src/fakes.dart';
|
|
import '../../src/mocks.dart';
|
|
import '../../src/testbed.dart';
|
|
|
|
void main() {
|
|
group('run', () {
|
|
MockDeviceManager mockDeviceManager;
|
|
FileSystem fileSystem;
|
|
|
|
setUpAll(() {
|
|
Cache.disableLocking();
|
|
});
|
|
|
|
setUp(() {
|
|
mockDeviceManager = MockDeviceManager();
|
|
fileSystem = MemoryFileSystem.test();
|
|
});
|
|
|
|
testUsingContext('fails when target not found', () async {
|
|
final RunCommand command = RunCommand();
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>['run', '-t', 'abc123', '--no-pub']);
|
|
fail('Expect exception');
|
|
} on ToolExit catch (e) {
|
|
expect(e.exitCode ?? 1, 1);
|
|
}
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fileSystem,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Logger: () => BufferLogger.test(),
|
|
});
|
|
|
|
testUsingContext('does not support "--use-application-binary" and "--fast-start"', () async {
|
|
fileSystem.file('lib/main.dart').createSync(recursive: true);
|
|
fileSystem.file('pubspec.yaml').createSync();
|
|
fileSystem.file('.packages').createSync();
|
|
|
|
final RunCommand command = RunCommand();
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--use-application-binary=app/bar/faz',
|
|
'--fast-start',
|
|
'--no-pub',
|
|
'--show-test-device',
|
|
]);
|
|
fail('Expect exception');
|
|
} on Exception catch (e) {
|
|
expect(e.toString(), isNot(contains('--fast-start is not supported with --use-application-binary')));
|
|
}
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fileSystem,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Logger: () => BufferLogger.test(),
|
|
});
|
|
|
|
testUsingContext('Walks upward looking for a pubspec.yaml and succeeds if found', () async {
|
|
fileSystem.file('pubspec.yaml').createSync();
|
|
fileSystem.file('.packages')
|
|
.writeAsStringSync('\n');
|
|
fileSystem.file('lib/main.dart')
|
|
.createSync(recursive: true);
|
|
fileSystem.currentDirectory = fileSystem.directory('a/b/c')
|
|
..createSync(recursive: true);
|
|
|
|
final RunCommand command = RunCommand();
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
]);
|
|
fail('Expect exception');
|
|
} on Exception catch (e) {
|
|
expect(e, isA<ToolExit>());
|
|
}
|
|
final BufferLogger bufferLogger = globals.logger as BufferLogger;
|
|
expect(
|
|
bufferLogger.statusText,
|
|
containsIgnoringWhitespace('Changing current working directory to:'),
|
|
);
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fileSystem,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Logger: () => BufferLogger.test(),
|
|
});
|
|
|
|
testUsingContext('Walks upward looking for a pubspec.yaml and exits if missing', () async {
|
|
fileSystem.currentDirectory = fileSystem.directory('a/b/c')
|
|
..createSync(recursive: true);
|
|
fileSystem.file('lib/main.dart')
|
|
.createSync(recursive: true);
|
|
|
|
final RunCommand command = RunCommand();
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
]);
|
|
fail('Expect exception');
|
|
} on Exception catch (e) {
|
|
expect(e, isA<ToolExit>());
|
|
expect(e.toString(), contains('No pubspec.yaml file found'));
|
|
}
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fileSystem,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Logger: () => BufferLogger.test(),
|
|
});
|
|
|
|
group('run app', () {
|
|
MemoryFileSystem fs;
|
|
Artifacts artifacts;
|
|
MockCache mockCache;
|
|
MockProcessManager mockProcessManager;
|
|
Usage usage;
|
|
Directory tempDir;
|
|
|
|
setUp(() {
|
|
artifacts = Artifacts.test();
|
|
mockCache = MockCache();
|
|
usage = Usage.test();
|
|
fs = MemoryFileSystem.test();
|
|
mockProcessManager = MockProcessManager();
|
|
|
|
tempDir = fs.systemTempDirectory.createTempSync('flutter_run_test.');
|
|
fs.currentDirectory = tempDir;
|
|
|
|
tempDir.childFile('pubspec.yaml')
|
|
.writeAsStringSync('name: flutter_app');
|
|
tempDir.childFile('.packages')
|
|
.writeAsStringSync('# Generated by pub on 2019-11-25 12:38:01.801784.');
|
|
final Directory libDir = tempDir.childDirectory('lib');
|
|
libDir.createSync();
|
|
final File mainFile = libDir.childFile('main.dart');
|
|
mainFile.writeAsStringSync('void main() {}');
|
|
|
|
when(mockDeviceManager.hasSpecifiedDeviceId).thenReturn(false);
|
|
when(mockDeviceManager.hasSpecifiedAllDevices).thenReturn(false);
|
|
});
|
|
|
|
testUsingContext('exits with a user message when no supported devices attached', () async {
|
|
final RunCommand command = RunCommand();
|
|
|
|
const List<Device> noDevices = <Device>[];
|
|
when(mockDeviceManager.getDevices()).thenAnswer(
|
|
(Invocation invocation) => Future<List<Device>>.value(noDevices)
|
|
);
|
|
when(mockDeviceManager.findTargetDevices(any, timeout: anyNamed('timeout'))).thenAnswer(
|
|
(Invocation invocation) => Future<List<Device>>.value(noDevices)
|
|
);
|
|
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
'--no-hot',
|
|
]);
|
|
fail('Expect exception');
|
|
} on ToolExit catch (e) {
|
|
expect(e.message, null);
|
|
}
|
|
|
|
expect(
|
|
testLogger.statusText,
|
|
containsIgnoringWhitespace(userMessages.flutterNoSupportedDevices),
|
|
);
|
|
}, overrides: <Type, Generator>{
|
|
DeviceManager: () => mockDeviceManager,
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => mockProcessManager,
|
|
});
|
|
|
|
testUsingContext('fails when targeted device is not Android with --device-user', () async {
|
|
globals.fs.file('pubspec.yaml').createSync();
|
|
globals.fs.file('.packages').writeAsStringSync('\n');
|
|
globals.fs.file('lib/main.dart').createSync(recursive: true);
|
|
final FakeDevice device = FakeDevice(isLocalEmulator: true);
|
|
when(mockDeviceManager.getAllConnectedDevices()).thenAnswer((Invocation invocation) async {
|
|
return <Device>[device];
|
|
});
|
|
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) async {
|
|
return <Device>[device];
|
|
});
|
|
when(mockDeviceManager.findTargetDevices(any, timeout: anyNamed('timeout'))).thenAnswer((Invocation invocation) async {
|
|
return <Device>[device];
|
|
});
|
|
when(mockDeviceManager.hasSpecifiedAllDevices).thenReturn(false);
|
|
when(mockDeviceManager.deviceDiscoverers).thenReturn(<DeviceDiscovery>[]);
|
|
|
|
final RunCommand command = RunCommand();
|
|
await expectLater(createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
'--device-user',
|
|
'10',
|
|
]), throwsToolExit(message: '--device-user is only supported for Android. At least one Android device is required.'));
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => MemoryFileSystem.test(),
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
DeviceManager: () => mockDeviceManager,
|
|
Stdio: () => MockStdio(),
|
|
});
|
|
|
|
testUsingContext('shows unsupported devices when no supported devices are found', () async {
|
|
final RunCommand command = RunCommand();
|
|
|
|
final MockDevice mockDevice = MockDevice(TargetPlatform.android_arm);
|
|
when(mockDevice.isLocalEmulator).thenAnswer((Invocation invocation) => Future<bool>.value(true));
|
|
when(mockDevice.isSupported()).thenAnswer((Invocation invocation) => true);
|
|
when(mockDevice.supportsFastStart).thenReturn(true);
|
|
when(mockDevice.id).thenReturn('mock-id');
|
|
when(mockDevice.name).thenReturn('mock-name');
|
|
when(mockDevice.platformType).thenReturn(PlatformType.android);
|
|
when(mockDevice.targetPlatformDisplayName)
|
|
.thenAnswer((Invocation invocation) async => 'mock-platform');
|
|
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) => Future<String>.value('api-14'));
|
|
|
|
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
|
return Future<List<Device>>.value(<Device>[
|
|
mockDevice,
|
|
]);
|
|
});
|
|
|
|
when(mockDeviceManager.findTargetDevices(any, timeout: anyNamed('timeout'))).thenAnswer(
|
|
(Invocation invocation) => Future<List<Device>>.value(<Device>[]),
|
|
);
|
|
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
'--no-hot',
|
|
]);
|
|
fail('Expect exception');
|
|
} on ToolExit catch (e) {
|
|
expect(e.message, null);
|
|
}
|
|
|
|
expect(
|
|
testLogger.statusText,
|
|
containsIgnoringWhitespace(userMessages.flutterNoSupportedDevices),
|
|
);
|
|
expect(
|
|
testLogger.statusText,
|
|
containsIgnoringWhitespace(userMessages.flutterFoundButUnsupportedDevices),
|
|
);
|
|
expect(
|
|
testLogger.statusText,
|
|
containsIgnoringWhitespace(
|
|
userMessages.flutterMissPlatformProjects(
|
|
Device.devicesPlatformTypes(<Device>[mockDevice]),
|
|
),
|
|
),
|
|
);
|
|
}, overrides: <Type, Generator>{
|
|
DeviceManager: () => mockDeviceManager,
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => mockProcessManager,
|
|
});
|
|
|
|
testUsingContext('updates cache before checking for devices', () async {
|
|
final RunCommand command = RunCommand();
|
|
|
|
// Called as part of requiredArtifacts()
|
|
when(mockDeviceManager.getDevices()).thenAnswer(
|
|
(Invocation invocation) => Future<List<Device>>.value(<Device>[])
|
|
);
|
|
// No devices are attached, we just want to verify update the cache
|
|
// BEFORE checking for devices
|
|
const Duration timeout = Duration(seconds: 10);
|
|
when(mockDeviceManager.findTargetDevices(any, timeout: timeout)).thenAnswer(
|
|
(Invocation invocation) => Future<List<Device>>.value(<Device>[])
|
|
);
|
|
|
|
try {
|
|
await createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
'--device-timeout',
|
|
'10',
|
|
]);
|
|
fail('Exception expected');
|
|
} on ToolExit catch (e) {
|
|
// We expect a ToolExit because no devices are attached
|
|
expect(e.message, null);
|
|
} on Exception catch (e) {
|
|
fail('ToolExit expected, got $e');
|
|
}
|
|
|
|
verifyInOrder(<void>[
|
|
// cache update
|
|
mockCache.updateAll(<DevelopmentArtifact>{DevelopmentArtifact.universal}),
|
|
// as part of gathering `requiredArtifacts`
|
|
mockDeviceManager.getDevices(),
|
|
// in validateCommand()
|
|
mockDeviceManager.findTargetDevices(any, timeout: anyNamed('timeout')),
|
|
]);
|
|
}, overrides: <Type, Generator>{
|
|
Cache: () => mockCache,
|
|
DeviceManager: () => mockDeviceManager,
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => mockProcessManager,
|
|
});
|
|
|
|
testUsingContext('passes device target platform to usage', () async {
|
|
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'));
|
|
// App fails to start because we're only interested in usage
|
|
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) => 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('.packages').createSync();
|
|
tempDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true);
|
|
tempDir.childFile('pubspec.yaml')
|
|
..createSync()
|
|
..writeAsStringSync('# Hello, World');
|
|
globals.fs.currentDirectory = tempDir;
|
|
|
|
// Capture Usage.test() events.
|
|
final StringBuffer buffer = await capturedConsolePrint(() =>
|
|
expectToolExitLater(createTestCommandRunner(command).run(<String>[
|
|
'run',
|
|
'--no-pub',
|
|
'--no-hot',
|
|
]), isNull)
|
|
);
|
|
// Allow any CustomDimensions.localTime (cd33) timestamp.
|
|
final RegExp usageRegexp = RegExp(
|
|
'screenView {cd3: false, cd4: ios, cd22: iOS 13, cd23: debug, cd18: false, cd15: swift, cd31: false, cd47: false, cd33: .*, viewName: run'
|
|
);
|
|
expect(buffer.toString(), matches(usageRegexp));
|
|
}, overrides: <Type, Generator>{
|
|
Artifacts: () => artifacts,
|
|
Cache: () => mockCache,
|
|
DeviceManager: () => mockDeviceManager,
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => mockProcessManager,
|
|
Usage: () => usage,
|
|
});
|
|
});
|
|
|
|
testUsingContext('should only request artifacts corresponding to connected devices', () async {
|
|
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
|
return Future<List<Device>>.value(<Device>[
|
|
MockDevice(TargetPlatform.android_arm),
|
|
]);
|
|
});
|
|
|
|
expect(await RunCommand().requiredArtifacts, unorderedEquals(<DevelopmentArtifact>{
|
|
DevelopmentArtifact.universal,
|
|
DevelopmentArtifact.androidGenSnapshot,
|
|
}));
|
|
|
|
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
|
return Future<List<Device>>.value(<Device>[
|
|
MockDevice(TargetPlatform.ios),
|
|
]);
|
|
});
|
|
|
|
expect(await RunCommand().requiredArtifacts, unorderedEquals(<DevelopmentArtifact>{
|
|
DevelopmentArtifact.universal,
|
|
DevelopmentArtifact.iOS,
|
|
}));
|
|
|
|
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
|
return Future<List<Device>>.value(<Device>[
|
|
MockDevice(TargetPlatform.ios),
|
|
MockDevice(TargetPlatform.android_arm),
|
|
]);
|
|
});
|
|
|
|
expect(await RunCommand().requiredArtifacts, unorderedEquals(<DevelopmentArtifact>{
|
|
DevelopmentArtifact.universal,
|
|
DevelopmentArtifact.iOS,
|
|
DevelopmentArtifact.androidGenSnapshot,
|
|
}));
|
|
|
|
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
|
return Future<List<Device>>.value(<Device>[
|
|
MockDevice(TargetPlatform.web_javascript),
|
|
]);
|
|
});
|
|
|
|
expect(await RunCommand().requiredArtifacts, unorderedEquals(<DevelopmentArtifact>{
|
|
DevelopmentArtifact.universal,
|
|
DevelopmentArtifact.web,
|
|
}));
|
|
}, overrides: <Type, Generator>{
|
|
DeviceManager: () => mockDeviceManager,
|
|
});
|
|
});
|
|
|
|
group('dart-defines and web-renderer options', () {
|
|
List<String> dartDefines;
|
|
|
|
setUp(() {
|
|
dartDefines = <String>[];
|
|
});
|
|
|
|
test('auto web-renderer with no dart-defines', () {
|
|
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'auto');
|
|
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=true']);
|
|
});
|
|
|
|
test('canvaskit web-renderer with no dart-defines', () {
|
|
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'canvaskit');
|
|
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=true']);
|
|
});
|
|
|
|
test('html web-renderer with no dart-defines', () {
|
|
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'html');
|
|
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=false']);
|
|
});
|
|
|
|
test('auto web-renderer with existing dart-defines', () {
|
|
dartDefines = <String>['FLUTTER_WEB_USE_SKIA=false'];
|
|
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'auto');
|
|
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=true']);
|
|
});
|
|
|
|
test('canvaskit web-renderer with no dart-defines', () {
|
|
dartDefines = <String>['FLUTTER_WEB_USE_SKIA=false'];
|
|
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'canvaskit');
|
|
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=true']);
|
|
});
|
|
|
|
test('html web-renderer with no dart-defines', () {
|
|
dartDefines = <String>['FLUTTER_WEB_USE_SKIA=true'];
|
|
dartDefines = FlutterCommand.updateDartDefines(dartDefines, 'html');
|
|
expect(dartDefines, <String>['FLUTTER_WEB_AUTO_DETECT=false','FLUTTER_WEB_USE_SKIA=false']);
|
|
});
|
|
});
|
|
}
|
|
|
|
class MockCache extends Mock implements Cache {}
|
|
class MockUsage extends Mock implements Usage {}
|
|
|
|
class MockDeviceManager extends Mock implements DeviceManager {}
|
|
class MockDevice extends Mock implements Device {
|
|
MockDevice(this._targetPlatform);
|
|
|
|
final TargetPlatform _targetPlatform;
|
|
|
|
@override
|
|
Future<TargetPlatform> get targetPlatform async => Future<TargetPlatform>.value(_targetPlatform);
|
|
}
|
|
|
|
class TestRunCommand extends RunCommand {
|
|
@override
|
|
// ignore: must_call_super
|
|
Future<void> validateCommand() async {
|
|
devices = await globals.deviceManager.getDevices();
|
|
}
|
|
}
|
|
|
|
class FakeDevice extends Fake implements Device {
|
|
FakeDevice({bool isLocalEmulator = false})
|
|
: _isLocalEmulator = isLocalEmulator;
|
|
|
|
static const int kSuccess = 1;
|
|
static const int kFailure = -1;
|
|
final TargetPlatform _targetPlatform = TargetPlatform.ios;
|
|
final bool _isLocalEmulator;
|
|
|
|
@override
|
|
String get id => 'fake_device';
|
|
|
|
void _throwToolExit(int code) => throwToolExit(null, exitCode: code);
|
|
|
|
@override
|
|
Future<bool> get isLocalEmulator => Future<bool>.value(_isLocalEmulator);
|
|
|
|
@override
|
|
bool supportsRuntimeMode(BuildMode mode) => true;
|
|
|
|
@override
|
|
bool get supportsHotReload => false;
|
|
|
|
@override
|
|
bool get supportsFastStart => false;
|
|
|
|
@override
|
|
Future<String> get sdkNameAndVersion => Future<String>.value('');
|
|
|
|
@override
|
|
DeviceLogReader getLogReader({
|
|
ApplicationPackage app,
|
|
bool includePastLogs = false,
|
|
}) {
|
|
return FakeDeviceLogReader();
|
|
}
|
|
|
|
@override
|
|
String get name => 'FakeDevice';
|
|
|
|
@override
|
|
Future<TargetPlatform> get targetPlatform async => _targetPlatform;
|
|
|
|
@override
|
|
final PlatformType platformType = PlatformType.ios;
|
|
|
|
@override
|
|
Future<LaunchResult> startApp(
|
|
ApplicationPackage package, {
|
|
String mainPath,
|
|
String route,
|
|
DebuggingOptions debuggingOptions,
|
|
Map<String, dynamic> platformArgs,
|
|
bool prebuiltApplication = false,
|
|
bool usesTerminalUi = true,
|
|
bool ipv6 = false,
|
|
String userIdentifier,
|
|
}) async {
|
|
final String dartFlags = debuggingOptions.dartFlags;
|
|
// In release mode, --dart-flags should be set to the empty string and
|
|
// provided flags should be dropped. In debug and profile modes,
|
|
// --dart-flags should not be empty.
|
|
if (debuggingOptions.buildInfo.isRelease) {
|
|
if (dartFlags.isNotEmpty) {
|
|
_throwToolExit(kFailure);
|
|
}
|
|
_throwToolExit(kSuccess);
|
|
} else {
|
|
if (dartFlags.isEmpty) {
|
|
_throwToolExit(kFailure);
|
|
}
|
|
_throwToolExit(kSuccess);
|
|
}
|
|
return null;
|
|
}
|
|
}
|