mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
Make most ios_workflow host tool calls async (#10260)
Does not yet migrate hasIdeviceId since that results in a cascade of breaking interface changes that's significant enough for a separate patch.
This commit is contained in:
parent
9a908f7558
commit
dd1456ffbc
|
@ -6,6 +6,7 @@ import 'dart:async';
|
|||
|
||||
import '../base/common.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/io.dart';
|
||||
import '../base/os.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/process.dart';
|
||||
|
@ -32,53 +33,55 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
|
||||
bool get hasIDeviceId => exitsHappy(<String>['idevice_id', '-h']);
|
||||
|
||||
bool get hasWorkingLibimobiledevice {
|
||||
Future<bool> get hasWorkingLibimobiledevice async {
|
||||
// Verify that libimobiledevice tools are installed.
|
||||
if (!hasIDeviceId)
|
||||
return false;
|
||||
|
||||
// If a device is attached, verify that we can get its name.
|
||||
final String result = runSync(<String>['idevice_id', '-l']);
|
||||
if (result.isNotEmpty && !exitsHappy(<String>['idevicename']))
|
||||
final ProcessResult result = (await runAsync(<String>['idevice_id', '-l'])).processResult;
|
||||
if (result.exitCode == 0 && result.stdout.isNotEmpty && !await exitsHappyAsync(<String>['idevicename']))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get hasIDeviceInstaller => exitsHappy(<String>['ideviceinstaller', '-h']);
|
||||
Future<bool> get hasIDeviceInstaller => exitsHappyAsync(<String>['ideviceinstaller', '-h']);
|
||||
|
||||
bool get hasIosDeploy => exitsHappy(<String>['ios-deploy', '--version']);
|
||||
Future<bool> get hasIosDeploy => exitsHappyAsync(<String>['ios-deploy', '--version']);
|
||||
|
||||
String get iosDeployMinimumVersion => '1.9.0';
|
||||
|
||||
String get iosDeployVersionText => runSync(<String>['ios-deploy', '--version']).replaceAll('\n', '');
|
||||
Future<String> get iosDeployVersionText async =>
|
||||
(await runAsync(<String>['ios-deploy', '--version'])).processResult.stdout.replaceAll('\n', '');
|
||||
|
||||
bool get hasHomebrew => os.which('brew') != null;
|
||||
|
||||
bool get hasPythonSixModule => kPythonSix.isInstalled;
|
||||
|
||||
bool get hasCocoaPods => exitsHappy(<String>['pod', '--version']);
|
||||
Future<bool> get hasCocoaPods => exitsHappyAsync(<String>['pod', '--version']);
|
||||
|
||||
String get cocoaPodsMinimumVersion => '1.0.0';
|
||||
|
||||
String get cocoaPodsVersionText => runSync(<String>['pod', '--version']).trim();
|
||||
Future<String> get cocoaPodsVersionText async =>
|
||||
(await runAsync(<String>['pod', '--version'])).processResult.stdout.trim();
|
||||
|
||||
bool get _iosDeployIsInstalledAndMeetsVersionCheck {
|
||||
if (!hasIosDeploy)
|
||||
Future<bool> get _iosDeployIsInstalledAndMeetsVersionCheck async {
|
||||
if (!await hasIosDeploy)
|
||||
return false;
|
||||
try {
|
||||
final Version version = new Version.parse(iosDeployVersionText);
|
||||
final Version version = new Version.parse(await iosDeployVersionText);
|
||||
return version >= new Version.parse(iosDeployMinimumVersion);
|
||||
} on FormatException catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool get isCocoaPodsInstalledAndMeetsVersionCheck {
|
||||
if (!hasCocoaPods)
|
||||
Future<bool> get isCocoaPodsInstalledAndMeetsVersionCheck async {
|
||||
if (!await hasCocoaPods)
|
||||
return false;
|
||||
try {
|
||||
final Version installedVersion = new Version.parse(cocoaPodsVersionText);
|
||||
final Version installedVersion = new Version.parse(await cocoaPodsVersionText);
|
||||
return installedVersion >= new Version.parse(cocoaPodsMinimumVersion);
|
||||
} on FormatException {
|
||||
return false;
|
||||
|
@ -86,11 +89,8 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
}
|
||||
|
||||
/// Whether CocoaPods ran 'pod setup' once where the costly pods' specs are cloned.
|
||||
bool get isCocoaPodsInitialized {
|
||||
return fs.isDirectorySync(
|
||||
fs.path.join(homeDirPath, '.cocoapods', 'repos', 'master')
|
||||
);
|
||||
}
|
||||
Future<bool> get isCocoaPodsInitialized =>
|
||||
fs.isDirectory(fs.path.join(homeDirPath, '.cocoapods', 'repos', 'master'));
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
|
@ -152,7 +152,7 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
if (hasHomebrew) {
|
||||
brewStatus = ValidationType.installed;
|
||||
|
||||
if (!hasWorkingLibimobiledevice) {
|
||||
if (!await hasWorkingLibimobiledevice) {
|
||||
brewStatus = ValidationType.partial;
|
||||
messages.add(new ValidationMessage.error(
|
||||
'libimobiledevice is incompatible with the installed Xcode version. To update, run:\n'
|
||||
|
@ -162,7 +162,7 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
));
|
||||
}
|
||||
|
||||
if (!hasIDeviceInstaller) {
|
||||
if (!await hasIDeviceInstaller) {
|
||||
brewStatus = ValidationType.partial;
|
||||
messages.add(new ValidationMessage.error(
|
||||
'ideviceinstaller not available; this is used to discover connected iOS devices.\n'
|
||||
|
@ -174,12 +174,12 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
}
|
||||
|
||||
// Check ios-deploy is installed at meets version requirements.
|
||||
if (hasIosDeploy) {
|
||||
messages.add(new ValidationMessage('ios-deploy $iosDeployVersionText'));
|
||||
if (await hasIosDeploy) {
|
||||
messages.add(new ValidationMessage('ios-deploy ${await iosDeployVersionText}'));
|
||||
}
|
||||
if (!_iosDeployIsInstalledAndMeetsVersionCheck) {
|
||||
if (!await _iosDeployIsInstalledAndMeetsVersionCheck) {
|
||||
brewStatus = ValidationType.partial;
|
||||
if (hasIosDeploy) {
|
||||
if (await hasIosDeploy) {
|
||||
messages.add(new ValidationMessage.error(
|
||||
'ios-deploy out of date ($iosDeployMinimumVersion is required). To upgrade:\n'
|
||||
' brew update\n'
|
||||
|
@ -194,9 +194,9 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
}
|
||||
}
|
||||
|
||||
if (isCocoaPodsInstalledAndMeetsVersionCheck) {
|
||||
if (isCocoaPodsInitialized) {
|
||||
messages.add(new ValidationMessage('CocoaPods version $cocoaPodsVersionText'));
|
||||
if (await isCocoaPodsInstalledAndMeetsVersionCheck) {
|
||||
if (await isCocoaPodsInitialized) {
|
||||
messages.add(new ValidationMessage('CocoaPods version ${await cocoaPodsVersionText}'));
|
||||
} else {
|
||||
brewStatus = ValidationType.partial;
|
||||
messages.add(new ValidationMessage.error(
|
||||
|
@ -209,7 +209,7 @@ class IOSWorkflow extends DoctorValidator implements Workflow {
|
|||
}
|
||||
} else {
|
||||
brewStatus = ValidationType.partial;
|
||||
if (!hasCocoaPods) {
|
||||
if (!await hasCocoaPods) {
|
||||
messages.add(new ValidationMessage.error(
|
||||
'CocoaPods not installed.\n'
|
||||
'$noCocoaPodsConsequence\n'
|
||||
|
|
|
@ -365,7 +365,7 @@ final String cocoaPodsUpgradeInstructions = '''
|
|||
|
||||
Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async {
|
||||
if (fs.file(fs.path.join(bundle.path, 'Podfile')).existsSync()) {
|
||||
if (!doctor.iosWorkflow.isCocoaPodsInstalledAndMeetsVersionCheck) {
|
||||
if (!await doctor.iosWorkflow.isCocoaPodsInstalledAndMeetsVersionCheck) {
|
||||
final String minimumVersion = doctor.iosWorkflow.cocoaPodsMinimumVersion;
|
||||
printError(
|
||||
'Warning: CocoaPods version $minimumVersion or greater not installed. Skipping pod install.\n'
|
||||
|
@ -376,7 +376,7 @@ Future<Null> _runPodInstall(Directory bundle, String engineDirectory) async {
|
|||
);
|
||||
return;
|
||||
}
|
||||
if (!doctor.iosWorkflow.isCocoaPodsInitialized) {
|
||||
if (!await doctor.iosWorkflow.isCocoaPodsInitialized) {
|
||||
printError(
|
||||
'Warning: CocoaPods installed but not initialized. Skipping pod install.\n'
|
||||
'$noCocoaPodsConsequence\n'
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// 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/memory.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
|
@ -30,10 +32,11 @@ void main() {
|
|||
testUsingContext('Emit missing status when nothing is installed', () async {
|
||||
when(xcode.isInstalled).thenReturn(false);
|
||||
when(xcode.xcodeSelectPath).thenReturn(null);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..hasPythonSixModule = false
|
||||
..hasHomebrew = false
|
||||
..hasIosDeploy = false;
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(
|
||||
hasPythonSixModule: false,
|
||||
hasHomebrew: false,
|
||||
hasIosDeploy: false,
|
||||
);
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.missing);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -82,8 +85,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..hasPythonSixModule = false;
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasPythonSixModule: false);
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -94,8 +96,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..hasHomebrew = false;
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasHomebrew: false);
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -106,8 +107,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..hasWorkingLibimobiledevice = false;
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasWorkingLibimobiledevice: false);
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -118,8 +118,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..hasIosDeploy = false;
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasIosDeploy: false);
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -130,8 +129,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..iosDeployVersionText = '1.8.0';
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(iosDeployVersionText: '1.8.0');
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -142,8 +140,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..hasCocoaPods = false;
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(hasCocoaPods: false);
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -154,8 +151,7 @@ void main() {
|
|||
.thenReturn('Xcode 8.2.1\nBuild version 8C1002\n');
|
||||
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
|
||||
when(xcode.eulaSigned).thenReturn(true);
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget()
|
||||
..cocoaPodsVersionText = '0.39.0';
|
||||
final IOSWorkflowTestTarget workflow = new IOSWorkflowTestTarget(cocoaPodsVersionText: '0.39.0');
|
||||
final ValidationResult result = await workflow.validate();
|
||||
expect(result.type, ValidationType.partial);
|
||||
}, overrides: <Type, Generator>{ Xcode: () => xcode });
|
||||
|
@ -215,27 +211,43 @@ class MockXcode extends Mock implements Xcode {}
|
|||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
|
||||
class IOSWorkflowTestTarget extends IOSWorkflow {
|
||||
@override
|
||||
bool hasPythonSixModule = true;
|
||||
IOSWorkflowTestTarget({
|
||||
this.hasPythonSixModule: true,
|
||||
this.hasHomebrew: true,
|
||||
bool hasWorkingLibimobiledevice: true,
|
||||
bool hasIosDeploy: true,
|
||||
String iosDeployVersionText: '1.9.0',
|
||||
bool hasIDeviceInstaller: true,
|
||||
bool hasCocoaPods: true,
|
||||
String cocoaPodsVersionText: '1.2.0',
|
||||
}) : hasWorkingLibimobiledevice = new Future<bool>.value(hasWorkingLibimobiledevice),
|
||||
hasIosDeploy = new Future<bool>.value(hasIosDeploy),
|
||||
iosDeployVersionText = new Future<String>.value(iosDeployVersionText),
|
||||
hasIDeviceInstaller = new Future<bool>.value(hasIDeviceInstaller),
|
||||
hasCocoaPods = new Future<bool>.value(hasCocoaPods),
|
||||
cocoaPodsVersionText = new Future<String>.value(cocoaPodsVersionText);
|
||||
|
||||
@override
|
||||
bool hasHomebrew = true;
|
||||
final bool hasPythonSixModule;
|
||||
|
||||
@override
|
||||
bool hasWorkingLibimobiledevice = true;
|
||||
final bool hasHomebrew;
|
||||
|
||||
@override
|
||||
bool hasIosDeploy = true;
|
||||
final Future<bool> hasWorkingLibimobiledevice;
|
||||
|
||||
@override
|
||||
String iosDeployVersionText = '1.9.0';
|
||||
final Future<bool> hasIosDeploy;
|
||||
|
||||
@override
|
||||
bool get hasIDeviceInstaller => true;
|
||||
final Future<String> iosDeployVersionText;
|
||||
|
||||
@override
|
||||
bool hasCocoaPods = true;
|
||||
final Future<bool> hasIDeviceInstaller;
|
||||
|
||||
@override
|
||||
String cocoaPodsVersionText = '1.2.0';
|
||||
final Future<bool> hasCocoaPods;
|
||||
|
||||
@override
|
||||
final Future<String> cocoaPodsVersionText;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue