Commit 615410d2 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Inject iOS, Android workflows via context (#10750)

Eliminates the need for the device/daemon code to get at the iOS/Android
tooling indirectly via Doctor. In tests, we now inject the workflow
objects (or mocks) directly.
parent d1feb1ad
...@@ -6,6 +6,7 @@ import 'dart:async'; ...@@ -6,6 +6,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import '../android/android_sdk.dart'; import '../android/android_sdk.dart';
import '../android/android_workflow.dart';
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart' show throwToolExit; import '../base/common.dart' show throwToolExit;
import '../base/file_system.dart'; import '../base/file_system.dart';
...@@ -17,7 +18,6 @@ import '../base/process_manager.dart'; ...@@ -17,7 +18,6 @@ import '../base/process_manager.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../commands/build_apk.dart'; import '../commands/build_apk.dart';
import '../device.dart'; import '../device.dart';
import '../doctor.dart';
import '../globals.dart'; import '../globals.dart';
import '../protocol_discovery.dart'; import '../protocol_discovery.dart';
...@@ -45,7 +45,7 @@ class AndroidDevices extends PollingDeviceDiscovery { ...@@ -45,7 +45,7 @@ class AndroidDevices extends PollingDeviceDiscovery {
bool get supportsPlatform => true; bool get supportsPlatform => true;
@override @override
bool get canListAnything => doctor.androidWorkflow.canListDevices; bool get canListAnything => androidWorkflow.canListDevices;
@override @override
List<Device> pollingGetDevices() => getAdbDevices(); List<Device> pollingGetDevices() => getAdbDevices();
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/os.dart'; import '../base/os.dart';
...@@ -15,6 +16,8 @@ import '../globals.dart'; ...@@ -15,6 +16,8 @@ import '../globals.dart';
import 'android_sdk.dart'; import 'android_sdk.dart';
import 'android_studio.dart' as android_studio; import 'android_studio.dart' as android_studio;
AndroidWorkflow get androidWorkflow => context.putIfAbsent(AndroidWorkflow, () => new AndroidWorkflow());
class AndroidWorkflow extends DoctorValidator implements Workflow { class AndroidWorkflow extends DoctorValidator implements Workflow {
AndroidWorkflow() : super('Android toolchain - develop for Android devices'); AndroidWorkflow() : super('Android toolchain - develop for Android devices');
......
...@@ -27,18 +27,6 @@ import 'version.dart'; ...@@ -27,18 +27,6 @@ import 'version.dart';
Doctor get doctor => context[Doctor]; Doctor get doctor => context[Doctor];
class Doctor { class Doctor {
Doctor() {
_androidWorkflow = new AndroidWorkflow();
_iosWorkflow = new IOSWorkflow();
}
IOSWorkflow _iosWorkflow;
AndroidWorkflow _androidWorkflow;
IOSWorkflow get iosWorkflow => _iosWorkflow;
AndroidWorkflow get androidWorkflow => _androidWorkflow;
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -46,11 +34,11 @@ class Doctor { ...@@ -46,11 +34,11 @@ class Doctor {
_validators = <DoctorValidator>[]; _validators = <DoctorValidator>[];
_validators.add(new _FlutterValidator()); _validators.add(new _FlutterValidator());
if (_androidWorkflow.appliesToHostPlatform) if (androidWorkflow.appliesToHostPlatform)
_validators.add(_androidWorkflow); _validators.add(androidWorkflow);
if (_iosWorkflow.appliesToHostPlatform) if (iosWorkflow.appliesToHostPlatform)
_validators.add(_iosWorkflow); _validators.add(iosWorkflow);
final List<DoctorValidator> ideValidators = <DoctorValidator>[]; final List<DoctorValidator> ideValidators = <DoctorValidator>[];
ideValidators.addAll(AndroidStudioValidator.allValidators); ideValidators.addAll(AndroidStudioValidator.allValidators);
......
...@@ -14,9 +14,9 @@ import '../base/process.dart'; ...@@ -14,9 +14,9 @@ import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../device.dart'; import '../device.dart';
import '../doctor.dart';
import '../globals.dart'; import '../globals.dart';
import '../protocol_discovery.dart'; import '../protocol_discovery.dart';
import 'ios_workflow.dart';
import 'mac.dart'; import 'mac.dart';
const String _kIdeviceinstallerInstructions = const String _kIdeviceinstallerInstructions =
...@@ -33,7 +33,7 @@ class IOSDevices extends PollingDeviceDiscovery { ...@@ -33,7 +33,7 @@ class IOSDevices extends PollingDeviceDiscovery {
bool get supportsPlatform => platform.isMacOS; bool get supportsPlatform => platform.isMacOS;
@override @override
bool get canListAnything => doctor.iosWorkflow.canListDevices; bool get canListAnything => iosWorkflow.canListDevices;
@override @override
List<Device> pollingGetDevices() => IOSDevice.getAttachedDevices(); List<Device> pollingGetDevices() => IOSDevice.getAttachedDevices();
...@@ -97,7 +97,7 @@ class IOSDevice extends Device { ...@@ -97,7 +97,7 @@ class IOSDevice extends Device {
bool get supportsStartPaused => false; bool get supportsStartPaused => false;
static List<IOSDevice> getAttachedDevices() { static List<IOSDevice> getAttachedDevices() {
if (!doctor.iosWorkflow.hasIDeviceId) if (!iosWorkflow.hasIDeviceId)
return <IOSDevice>[]; return <IOSDevice>[];
final List<IOSDevice> devices = <IOSDevice>[]; final List<IOSDevice> devices = <IOSDevice>[];
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'dart:async'; import 'dart:async';
import '../base/common.dart'; import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/os.dart'; import '../base/os.dart';
...@@ -14,6 +15,8 @@ import '../base/version.dart'; ...@@ -14,6 +15,8 @@ import '../base/version.dart';
import '../doctor.dart'; import '../doctor.dart';
import 'mac.dart'; import 'mac.dart';
IOSWorkflow get iosWorkflow => context.putIfAbsent(IOSWorkflow, () => new IOSWorkflow());
Xcode get xcode => Xcode.instance; Xcode get xcode => Xcode.instance;
class IOSWorkflow extends DoctorValidator implements Workflow { class IOSWorkflow extends DoctorValidator implements Workflow {
......
...@@ -17,12 +17,12 @@ import '../base/platform.dart'; ...@@ -17,12 +17,12 @@ import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../doctor.dart';
import '../flx.dart' as flx; import '../flx.dart' as flx;
import '../globals.dart'; import '../globals.dart';
import '../plugins.dart'; import '../plugins.dart';
import '../services.dart'; import '../services.dart';
import 'code_signing.dart'; import 'code_signing.dart';
import 'ios_workflow.dart';
import 'xcodeproj.dart'; import 'xcodeproj.dart';
const int kXcodeRequiredVersionMajor = 7; const int kXcodeRequiredVersionMajor = 7;
...@@ -354,8 +354,8 @@ final String cocoaPodsUpgradeInstructions = ''' ...@@ -354,8 +354,8 @@ final String cocoaPodsUpgradeInstructions = '''
Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async { Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async {
if (fs.file(fs.path.join(bundle.path, 'Podfile')).existsSync()) { if (fs.file(fs.path.join(bundle.path, 'Podfile')).existsSync()) {
if (!await doctor.iosWorkflow.isCocoaPodsInstalledAndMeetsVersionCheck) { if (!await iosWorkflow.isCocoaPodsInstalledAndMeetsVersionCheck) {
final String minimumVersion = doctor.iosWorkflow.cocoaPodsMinimumVersion; final String minimumVersion = iosWorkflow.cocoaPodsMinimumVersion;
printError( printError(
'Warning: CocoaPods version $minimumVersion or greater not installed. Skipping pod install.\n' 'Warning: CocoaPods version $minimumVersion or greater not installed. Skipping pod install.\n'
'$noCocoaPodsConsequence\n' '$noCocoaPodsConsequence\n'
...@@ -365,7 +365,7 @@ Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async { ...@@ -365,7 +365,7 @@ Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async {
); );
return; return;
} }
if (!await doctor.iosWorkflow.isCocoaPodsInitialized) { if (!await iosWorkflow.isCocoaPodsInitialized) {
printError( printError(
'Warning: CocoaPods installed but not initialized. Skipping pod install.\n' 'Warning: CocoaPods installed but not initialized. Skipping pod install.\n'
'$noCocoaPodsConsequence\n' '$noCocoaPodsConsequence\n'
......
...@@ -16,10 +16,10 @@ import '../base/process.dart'; ...@@ -16,10 +16,10 @@ import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../device.dart'; import '../device.dart';
import '../doctor.dart';
import '../flx.dart' as flx; import '../flx.dart' as flx;
import '../globals.dart'; import '../globals.dart';
import '../protocol_discovery.dart'; import '../protocol_discovery.dart';
import 'ios_workflow.dart';
import 'mac.dart'; import 'mac.dart';
const String _xcrunPath = '/usr/bin/xcrun'; const String _xcrunPath = '/usr/bin/xcrun';
...@@ -34,7 +34,7 @@ class IOSSimulators extends PollingDeviceDiscovery { ...@@ -34,7 +34,7 @@ class IOSSimulators extends PollingDeviceDiscovery {
bool get supportsPlatform => platform.isMacOS; bool get supportsPlatform => platform.isMacOS;
@override @override
bool get canListAnything => doctor.iosWorkflow.canListDevices; bool get canListAnything => iosWorkflow.canListDevices;
@override @override
List<Device> pollingGetDevices() => IOSSimulatorUtils.instance.getAttachedDevices(); List<Device> pollingGetDevices() => IOSSimulatorUtils.instance.getAttachedDevices();
......
...@@ -8,7 +8,6 @@ import 'package:flutter_tools/src/android/android_workflow.dart'; ...@@ -8,7 +8,6 @@ import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/daemon.dart'; import 'package:flutter_tools/src/commands/daemon.dart';
import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/globals.dart'; import 'package:flutter_tools/src/globals.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart'; import 'package:flutter_tools/src/ios/ios_workflow.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
...@@ -220,7 +219,8 @@ void main() { ...@@ -220,7 +219,8 @@ void main() {
expect(response['params'], containsPair('title', 'Unable to list devices')); expect(response['params'], containsPair('title', 'Unable to list devices'));
expect(response['params'], containsPair('message', contains('Unable to discover Android devices'))); expect(response['params'], containsPair('message', contains('Unable to discover Android devices')));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Doctor: () => new MockDoctor(androidCanListDevices: false), AndroidWorkflow: () => new MockAndroidWorkflow(canListDevices: false),
IOSWorkflow: () => new MockIOSWorkflow(),
}); });
testUsingContext('device.getDevices should respond with list', () async { testUsingContext('device.getDevices should respond with list', () async {
...@@ -263,36 +263,24 @@ void main() { ...@@ -263,36 +263,24 @@ void main() {
commands.close(); commands.close();
}); });
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Doctor: () => new MockDoctor(), AndroidWorkflow: () => new MockAndroidWorkflow(),
IOSWorkflow: () => new MockIOSWorkflow(),
}); });
}); });
} }
bool _notEvent(Map<String, dynamic> map) => map['event'] == null; bool _notEvent(Map<String, dynamic> map) => map['event'] == null;
class MockDoctor extends Doctor {
final bool androidCanListDevices;
final bool iosCanListDevices;
MockDoctor({this.androidCanListDevices: true, this.iosCanListDevices: true});
@override
AndroidWorkflow get androidWorkflow => new MockAndroidWorkflow(androidCanListDevices);
@override
IOSWorkflow get iosWorkflow => new MockIosWorkflow(iosCanListDevices);
}
class MockAndroidWorkflow extends AndroidWorkflow { class MockAndroidWorkflow extends AndroidWorkflow {
MockAndroidWorkflow({ this.canListDevices: true });
@override @override
final bool canListDevices; final bool canListDevices;
MockAndroidWorkflow(this.canListDevices);
} }
class MockIosWorkflow extends IOSWorkflow { class MockIOSWorkflow extends IOSWorkflow {
MockIOSWorkflow({ this.canListDevices:true });
@override @override
final bool canListDevices; final bool canListDevices;
MockIosWorkflow(this.canListDevices);
} }
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