Removes check for Homebrew if all necessary packages are present. (#23844)
* Removes need for homebrew installation if all other packages are installed. Modifies test to work with this new functionality.
diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
index cfd12fb..07b30ad 100644
--- a/packages/flutter_tools/lib/src/ios/ios_workflow.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart
@@ -68,11 +68,14 @@
}
}
+ // Change this value if the number of checks for packages needed for installation changes
+ static const int totalChecks = 4;
+
@override
Future<ValidationResult> validate() async {
final List<ValidationMessage> messages = <ValidationMessage>[];
ValidationType xcodeStatus = ValidationType.missing;
- ValidationType brewStatus = ValidationType.missing;
+ ValidationType packageManagerStatus = ValidationType.installed;
String xcodeVersionInfo;
if (xcode.isInstalled) {
@@ -125,76 +128,84 @@
}
}
- // brew installed
- if (hasHomebrew) {
- brewStatus = ValidationType.installed;
+ int checksFailed = 0;
- if (!iMobileDevice.isInstalled) {
- brewStatus = ValidationType.partial;
- messages.add(ValidationMessage.error(
- 'libimobiledevice and ideviceinstaller are not installed. To install, run:\n'
- ' brew update\n'
- ' brew install --HEAD usbmuxd\n'
- ' brew link usbmuxd\n'
- ' brew install --HEAD libimobiledevice\n'
- ' brew install ideviceinstaller'
- ));
- } else if (!await iMobileDevice.isWorking) {
- brewStatus = ValidationType.partial;
- messages.add(ValidationMessage.error(
- 'Verify that all connected devices have been paired with this computer in Xcode.\n'
- 'If all devices have been paired, libimobiledevice and ideviceinstaller may require updating.\n'
- 'To update, run:\n'
- ' brew update\n'
- ' brew uninstall --ignore-dependencies libimobiledevice\n'
- ' brew uninstall --ignore-dependencies usbmuxd\n'
- ' brew install --HEAD usbmuxd\n'
- ' brew unlink usbmuxd\n'
- ' brew link usbmuxd\n'
- ' brew install --HEAD libimobiledevice\n'
- ' brew install ideviceinstaller'
- ));
- } else if (!await hasIDeviceInstaller) {
- brewStatus = ValidationType.partial;
- messages.add(ValidationMessage.error(
- 'ideviceinstaller is not installed; this is used to discover connected iOS devices.\n'
- 'To install, run:\n'
- ' brew install --HEAD usbmuxd\n'
- ' brew link usbmuxd\n'
- ' brew install --HEAD libimobiledevice\n'
- ' brew install ideviceinstaller'
- ));
- }
-
- // Check ios-deploy is installed at meets version requirements.
- if (await hasIosDeploy) {
- messages.add(ValidationMessage('ios-deploy ${await iosDeployVersionText}'));
- }
- if (!await _iosDeployIsInstalledAndMeetsVersionCheck) {
- brewStatus = ValidationType.partial;
- if (await hasIosDeploy) {
- messages.add(ValidationMessage.error(
- 'ios-deploy out of date ($iosDeployMinimumVersion is required). To upgrade:\n'
- ' brew upgrade ios-deploy'
- ));
- } else {
- messages.add(ValidationMessage.error(
- 'ios-deploy not installed. To install:\n'
- ' brew install ios-deploy'
- ));
- }
- }
-
- } else {
- brewStatus = ValidationType.missing;
+ if (!iMobileDevice.isInstalled) {
+ checksFailed += 3;
+ packageManagerStatus = ValidationType.partial;
messages.add(ValidationMessage.error(
- 'Brew not installed; use this to install tools for iOS device development.\n'
- 'Download brew at https://brew.sh/.'
+ 'libimobiledevice and ideviceinstaller are not installed. To install with Brew, run:\n'
+ ' brew update\n'
+ ' brew install --HEAD usbmuxd\n'
+ ' brew link usbmuxd\n'
+ ' brew install --HEAD libimobiledevice\n'
+ ' brew install ideviceinstaller'
+ ));
+ } else if (!await iMobileDevice.isWorking) {
+ checksFailed += 2;
+ packageManagerStatus = ValidationType.partial;
+ messages.add(ValidationMessage.error(
+ 'Verify that all connected devices have been paired with this computer in Xcode.\n'
+ 'If all devices have been paired, libimobiledevice and ideviceinstaller may require updating.\n'
+ 'To update with Brew, run:\n'
+ ' brew update\n'
+ ' brew uninstall --ignore-dependencies libimobiledevice\n'
+ ' brew uninstall --ignore-dependencies usbmuxd\n'
+ ' brew install --HEAD usbmuxd\n'
+ ' brew unlink usbmuxd\n'
+ ' brew link usbmuxd\n'
+ ' brew install --HEAD libimobiledevice\n'
+ ' brew install ideviceinstaller'
+ ));
+ } else if (!await hasIDeviceInstaller) {
+ checksFailed += 1;
+ packageManagerStatus = ValidationType.partial;
+ messages.add(ValidationMessage.error(
+ 'ideviceinstaller is not installed; this is used to discover connected iOS devices.\n'
+ 'To install with Brew, run:\n'
+ ' brew install --HEAD usbmuxd\n'
+ ' brew link usbmuxd\n'
+ ' brew install --HEAD libimobiledevice\n'
+ ' brew install ideviceinstaller'
+ ));
+ }
+
+ final bool iHasIosDeploy = await hasIosDeploy;
+
+ // Check ios-deploy is installed at meets version requirements.
+ if (iHasIosDeploy) {
+ messages.add(
+ ValidationMessage('ios-deploy ${await iosDeployVersionText}'));
+ }
+ if (!await _iosDeployIsInstalledAndMeetsVersionCheck) {
+ packageManagerStatus = ValidationType.partial;
+ if (iHasIosDeploy) {
+ messages.add(ValidationMessage.error(
+ 'ios-deploy out of date ($iosDeployMinimumVersion is required). To upgrade with Brew:\n'
+ ' brew upgrade ios-deploy'
+ ));
+ } else {
+ checksFailed += 1;
+ messages.add(ValidationMessage.error(
+ 'ios-deploy not installed. To install with Brew:\n'
+ ' brew install ios-deploy'
+ ));
+ }
+ }
+
+ // If one of the checks for the packages failed, we may need brew so that we can install
+ // the necessary packages. If they're all there, however, we don't even need it.
+ if (checksFailed == totalChecks)
+ packageManagerStatus = ValidationType.missing;
+ if (checksFailed > 0 && !hasHomebrew) {
+ messages.add(ValidationMessage.error(
+ 'Brew can be used to install tools for iOS device development.\n'
+ 'Download brew at https://brew.sh/.'
));
}
return ValidationResult(
- <ValidationType>[xcodeStatus, brewStatus].reduce(_mergeValidationTypes),
+ <ValidationType>[xcodeStatus, packageManagerStatus].reduce(_mergeValidationTypes),
messages,
statusInfo: xcodeVersionInfo
);
diff --git a/packages/flutter_tools/test/ios/ios_workflow_test.dart b/packages/flutter_tools/test/ios/ios_workflow_test.dart
index fe3a4e9..1004131 100644
--- a/packages/flutter_tools/test/ios/ios_workflow_test.dart
+++ b/packages/flutter_tools/test/ios/ios_workflow_test.dart
@@ -21,6 +21,7 @@
void main() {
group('iOS Workflow validation', () {
MockIMobileDevice iMobileDevice;
+ MockIMobileDevice iMobileDeviceUninstalled;
MockXcode xcode;
MockProcessManager processManager;
MockCocoaPods cocoaPods;
@@ -28,6 +29,7 @@
setUp(() {
iMobileDevice = MockIMobileDevice();
+ iMobileDeviceUninstalled = MockIMobileDevice(isInstalled: false);
xcode = MockXcode();
processManager = MockProcessManager();
cocoaPods = MockCocoaPods();
@@ -45,11 +47,13 @@
final IOSWorkflowTestTarget workflow = IOSWorkflowTestTarget(
hasHomebrew: false,
hasIosDeploy: false,
+ hasIDeviceInstaller: false,
+ iosDeployVersionText: '0.0.0',
);
final ValidationResult result = await workflow.validate();
expect(result.type, ValidationType.missing);
}, overrides: <Type, Generator>{
- IMobileDevice: () => iMobileDevice,
+ IMobileDevice: () => iMobileDeviceUninstalled,
Xcode: () => xcode,
CocoaPods: () => cocoaPods,
});
@@ -110,7 +114,7 @@
CocoaPods: () => cocoaPods,
});
- testUsingContext('Emits partial status when homebrew not installed', () async {
+ testUsingContext('Emits installed status when homebrew not installed, but not needed', () async {
when(xcode.isInstalled).thenReturn(true);
when(xcode.versionText)
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
@@ -119,7 +123,7 @@
when(xcode.isSimctlInstalled).thenReturn(true);
final IOSWorkflowTestTarget workflow = IOSWorkflowTestTarget(hasHomebrew: false);
final ValidationResult result = await workflow.validate();
- expect(result.type, ValidationType.partial);
+ expect(result.type, ValidationType.installed);
}, overrides: <Type, Generator>{
IMobileDevice: () => iMobileDevice,
Xcode: () => xcode,